A field with a sensitivity tag
You add asensitivity value to a field declaration on the workspace schema. Everything else — redaction in logs, masking in rendered pages, allow-listing on outbound capability calls — falls out of the tag.
schema.json
name is treated as personal data; email is contact-class; ssn_last4 is restricted. notes has no tag and is treated as public-by-default — the platform does not infer sensitivity from field names because the same name means different things in different schemas.
The tag set
Five tags exist. They are ordered by handling strictness; the strictest tag a value carries is the one that wins when a value is composed from several fields. The tags are a contract, not just a hint. The runtime enforces the handling described in the right column; you cannot opt arestricted field into a log line by setting a flag elsewhere.
Where the tag is enforced
Sensitivity is checked at four boundaries. Each one inspects the tag and applies the right action without the page author or the developer having to remember.How redaction looks
The redactor preserves enough shape for an operator to recognize the field type while removing the value. Examples (forcontact):
restricted, the redaction is total — the value is replaced with <redacted:restricted> and no shape is preserved. The redactor does not produce a deterministic token; the same value redacted twice produces the same masked output only when the field type is what determines the mask, not the underlying value.
End-user sessions and tag scope
A signed-in end user can see their owncontact and financial fields. The runtime resolves the calling end-user’s identity from the session and matches it against ownership claims on the record. A row owned by user A renders A’s email; the same row read in B’s session renders the masked form.
The tag set is not affected by who is reading — restricted is restricted for everyone. What changes per session is whether the masking applies. A workspace owner reading a customer’s record sees the redacted form on a default block; the end user reading their own record sees the unmasked value because the block resolves the ownership claim.
Tag composition
When a value is composed from several fields — a Table block rendering a row, an email template interpolating columns — the strictest tag in the composition wins. A row that contains onerestricted field is treated as restricted as a whole for the purpose of decisions made about that composition. Individual fields keep their own tags for purposes of how they render and where they ship.
This rule prevents accidentally exposing a sensitive value by burying it inside an otherwise-public surface. If you want to render a row publicly, the row must not contain a sensitive field, full stop.
Declaring a block’s sensitivity policy
Blocks declare what tags they handle. The declaration is opt-in: a block that does not opt intocontact will not render any contact-tagged field. The runtime does not silently auto-render across the boundary.
The defaults are conservative: a fresh block renders only public and personal. You opt into stricter tags explicitly.
Reading sensitivity on a record from the API
When you read a record through the API, the response carries the redacted form by default. Pass?reveal=contact,financial on the query (with a token that holds the right scope) to receive the underlying values. The reveal is logged to the audit chain by field — the platform tracks not just that the row was read, but which sensitive fields were unmasked.