Skip to content
Talk to our solutions team

Compliances

A compliance declares how a field must be handled — at rest, on read, in logs, in exports and in indexes.

fields:
- name: national_id
type: string
compliances: [pii]

That single tag is not a label. It applies a protection bundle.

Tagging a field with a classificationpii, phi, pci or gdpr — automatically applies:

DimensionDefaultWhy
At restencryptedCiphertext in the column
On readmaskOutput shows a masked representation
LogsnologThe value never enters a log line
ExportsnoexportNever appears in a schema or data export
IndexesnoindexOnly when encrypted or tokenized — a plaintext index over ciphertext would defeat the encryption

The reasoning is worth stating plainly: a schema author should not be able to leave regulated data unprotected by forgetting a directive. Classification is the thing people remember; the bundle is what they forget.

Each dimension is applied only if you have not already expressed a conflicting directive for that dimension. The dimensions are independent, so overriding one leaves the rest in place.

DimensionDirectives (mutually exclusive)
On readmask · redact · hidden
At restencrypted · tokenize · hash
compliances: [pii, redact] # redacted on read, still encrypted, nolog, noexport
compliances: [pii, tokenize] # tokenized at rest, still masked on read

nolog and noexport are additive. They never conflict with anything, so for a classified field they always apply — you cannot accidentally turn them off by adding another directive.

DirectiveEffect
maskOutput shows a masked representation
redactOutput shows a redaction marker
hiddenThe field is omitted from output entirely
DirectiveEffect
encryptedCiphertext in the column
tokenizeStored as a token; the value lives elsewhere
hashOne-way. The original is not recoverable
DirectiveEffect
nologNever enters a log line
noexportNever appears in a schema or data export
noindexNo index is emitted over the column
DirectiveMeans
piiPersonally identifiable information
phiProtected health information
pciPayment card data
gdprIn scope for GDPR
DirectiveEffect
searchableSee below
retentionMarks the field for the retention runner. Parsed here, enforced there

Encryption and querying pull in opposite directions. An encrypted email column cannot be looked up by value.

searchable is the escape hatch: it suppresses default encryption for a classified field that must remain queryable.

- name: email
type: string
compliances: [pii, searchable]

Mask, nolog and noexport still apply. The value is still masked on read, still kept out of logs and exports — only the at-rest encryption is dropped, and only because you asked.

Everything that needs a field’s posture goes through the same resolution: read masking, at-rest encryption on both write and read, the schema exporters, and the index emitter during migration.

That matters because it is the only way the policy stays coherent. If masking resolved compliances differently from export, a field could be masked in an API response and plain in a CSV — which is exactly the failure this design exists to prevent.

Default encryption is a no-op at runtime when no key provider is configured — the encrypting hook skips.

That keeps the policy from breaking a deployment that has not set up keys yet. It also means a classified field can be sitting in plaintext while the schema says encrypted, so verify key configuration before treating classification as protection.

They are easy to confuse and do different jobs.

ComplianceTransform
GovernsWho may see the valueWhat the value is
AppliedAt read, write, export and index, per policyOn write, in declared order
hashProtection policy — a bundle dimensionA function that rewrites the stored value
Reversibleencrypted and tokenize areOnly if the function is

A masked field still stores the real value. A mask_partial transform changes what is stored. Reach for the compliance when the requirement is about access, and the transform when it is about content.