Data classification
Project Synapse checks text for sensitive values wherever it is about to leave one part of the platform for another: into a model, out to a connector, into a knowledge pack, into a log or an export. Each of those places is a boundary. At every boundary a versioned policy bundle decides what happens to what was found: allow it, replace it, hold it for review, or block it.
This guide explains what is detected, what each decision does, where the decisions are recorded, and what the platform does not do yet.
What is detected
Detection in this release is deterministic. There is no machine-learning classifier and nothing is sent to an outside classification service.
| Detected | Examples | Data class in class-v1 |
|---|---|---|
| Credentials | bearer tokens, JSON web tokens, cloud access key ids, private key blocks, platform and source-control access tokens, high-entropy values next to words such as password or api_key | Restricted |
| Personal identifiers | email addresses, phone numbers in international format | Confidential |
| Financial identifiers | IBANs and card numbers that pass their checksum | Confidential |
Health information has no detector yet. The Regulated class exists in the policy so that a future detector is blocked by default, not allowed by default.
The five data classes
class-v1 is the policy bundle every new run is pinned to. The table shows
what it does with each class.
| Class | What it covers | Model routes | Transformation | Who reviews |
|---|---|---|---|---|
| Public | Text with no finding | The mock model, or the four approved real routes on the hosted demo (Haiku 5.5 as the economy route, Sonnet 5.5 as the standard route, Opus 5.5 as the frontier route, Fable 5.1 as the apex route) for approved users | None | Nobody |
| Internal | Reserved for a future detector | Same as Public | None | Nobody |
| Confidential | Personal and financial identifiers | Same as Public; the value is sent as written | None, except at connector writes, where the value is held for review | PlatformAdmin and Auditor can read the findings evidence; run owners see counts |
| Restricted | Credentials | Never reaches a model as written: it is replaced before model input | Replaced by a vault token or a placeholder at model input, retrieval, embedding, connector writes and exports; blocked at upload; held for review in connector results; allowed and counted in model output | PlatformAdmin and Auditor can read the findings evidence; run owners see counts |
| Regulated | Nothing is detected as regulated yet | None | Blocked at every boundary | PlatformAdmin publishes the bundle that would change this |
Region. Findings and vault tokens are stored in the hosted project's database region, US East (N. Virginia). On the hosted demo the four approved real model routes are declared as global routes: the model provider chooses where a request is processed. A deployment's active route profile decides which real routes exist and what region they declare.
Routing limit. A run's routing data class is fixed to Public today. Classification findings do not yet raise it, so the model route is not chosen from what was found. What protects a restricted value is the replacement at model input, not the route.
What each decision does
- Allow. The text passes as written. If something was found, the count is recorded.
- Redact. The value is replaced before the text moves on.
- Inside a run, the replacement is a vault token (it starts with
rst_). The original value is encrypted and kept for that run only. No part of the platform turns a token back into the value in this release. - Where there is no run (a document being added to a knowledge pack, an
upload at run intake, a workflow action, an export), the replacement is a
placeholder such as
[REDACTED:credential]. A placeholder cannot be reversed. For a knowledge document, the stored file itself is the redacted text; the original is not kept.
- Inside a run, the replacement is a vault token (it starts with
- Review required. The value is withheld. There is no reviewer queue in this release and no approval is created: a tool call is denied with a visible reason, and anything else stops the run or the step.
- Block. The value is withheld and the run, step, upload or document is refused with a plain reason.
If classification itself cannot run (the policy cannot be read, a detector fails, the check runs out of time, a finding cannot be recorded), the value is withheld. The platform never falls back to allowing.
A demo note: under class-v1, a connector write that contains an email
address, a phone number, an IBAN or a card number needs a review, so the write
is denied. The lever is the policy bundle: a PlatformAdmin publishes a new one.
Lookups are different: see the connector write row below.
Where it is enforced
| Boundary | What is checked | When |
|---|---|---|
| Model input | The system prompt and every text part sent to a model, including the advisor's question and a workflow agent step's prompt | Before the model is called |
| Model output | The final answer, a workflow agent step's result, the advisor's answer | Before it is saved |
| Retrieval | Each knowledge chunk, its title and its pack slug | Before it enters the prompt and before the retrieval receipt is stored |
| Connector result | What a connector or MCP server returned | Before the model sees it |
| Connector write | The arguments of write and destructive capabilities, and the inputs of workflow actions. A read-only lookup is not checked here: looking a record up by an identifier is the normal use of a system of record, and a restricted value was already replaced by a token before the model could choose it as an argument | Before they leave for the connector |
| Upload | Evidence text, image captions, the text extracted from attached documents, and the file names of attachments and screenshots | At run intake, before the run exists |
| Embedding | A knowledge document's text, title and file name, and the retrieval query | Before anything is stored or embedded |
| Export | Audit export cells | When the file is written |
| Telemetry | Log values, trace attributes, stored run errors and error messages returned to a client | Always |
Telemetry and export use credential detection only. They are always on and do not consult the policy bundle. Email addresses and similar identifiers are left in logs and audit exports, because those detectors would also match parts of hashes, identifiers and timestamps. Property names in logged and exported values are checked the same way as the values under them.
Structured values. Tool arguments, workflow action inputs, connector results and a workflow agent step's result are checked field by field: every text value, every number and every property name, at any depth. Only a text value can be replaced in place. When the policy says to replace something found in a number or in a property name, the whole value is withheld instead. It is never passed on as written, and a number is never turned into text. Raw bytes are not text: a connector result that carries raw bytes (a file body, for example) is withheld, and a log entry records only how many bytes there were.
When the pinned bundle could withhold or change a model's answer, the answer is
held until the decision is made and nothing is streamed early. class-v1 never
withholds an answer, so answers stream as they are written.
What is recorded, and for how long
- Findings are counts: boundary, kind of value, data class, decision, detector and policy version. They never include the matched text or its position. They belong to a run and are deleted with their run.
- Vault tokens expire after 7 days. An expired token can no longer be resolved, and a bounded purge removes expired rows.
- Decisions made without a run (a knowledge document, an upload at
intake, a workflow action) exist only in the logs, as a
classification.decisionentry with the boundary, the decision, the kinds of value, the counts and the policy version. Export and telemetry redaction is always on and leaves no decision entry. - The run record shows a Classification panel: the policy version the run is pinned to and a count for each boundary and decision. It never shows a value.
Who can see what:
- Run owners see counts for their own runs.
- Auditor and PlatformAdmin can read the findings evidence for every run.
- PlatformAdmin publishes policy bundles. Publishing is audited.
Policy versions
A run is pinned to the policy version that was active when the run was created, and it keeps that version to the end, even if a new bundle is published while it runs. Publishing a bundle never changes an agent or one of its versions.
Emergency behaviour
There is no switch that turns enforcement off. If classification is unavailable, the platform fails closed: content is withheld and the run, step, upload or document is refused. The emergency lever is the same as the ordinary one: a PlatformAdmin publishes a new bundle through the audited publishing step. New runs use it at once; runs already in progress finish on the version they were pinned to. One check on a run is the exception: the retrieval query is checked before it is embedded, as a boundary without a run, so it uses the active version.
Configuration
CLASSIFICATION_TOKEN_SECRET is the key that protects vault tokens. It is
needed only when a redact decision occurs inside a run. Without it, that one
check is unavailable and the content is withheld; text with nothing to redact
is unaffected. Setting the key on the hosted demo is an operator step.
Limits in this release
- What the owner typed is stored as entered. A run's input, a refine instruction and a workflow's trigger payload are kept as their owner wrote them. Classification governs where a value flows, not what its owner stored: a refine instruction is checked at model input when the refinement runs.
- Workflow context is not enforced. Values written into a workflow's context are not wired to the policy. Every place a context value can go next is: model input at agent steps, connector writes at action steps, exports and telemetry. A restricted value can therefore remain in workflow history rows, which row-level security already restricts.
- No reviewer queue. A review decision denies the value; nobody is asked.
- No token resolution. Nothing turns a vault token back into its value.
- Images are not scanned. Only text is classified. A screenshot that shows a credential is not detected.
- Later steps of a run. Model input is checked when a run starts: the
system prompt and the messages. On later steps the model is called again
with the conversation so far. Tool results in it were checked when they
arrived, but the model's own earlier text and the tool arguments it chose
are sent back to it without a new check. They came from that same model, so
nothing new is disclosed, and
class-v1withholds nothing there. A workflow agent step and the advisor make one call each and have no such gap. - Size and time. A single check fails closed at its limits: more than 1,024 findings, a structured value with more than 10,000 fields (text values, numbers and distinct property names together) or nested deeper than 64 levels, or a check that takes longer than 5 seconds. Each is treated as unavailable and the content is withheld. A very large connector result, or a large document in a script that uses several bytes for each character, can therefore be refused.
- Action arguments are recorded first. A workflow action's arguments are stored with the action's claim before the connector write check decides. That record is workflow history, which row-level security already restricts.
- Downloading a run's output is not an export check. It returns the stored output to someone who can already read that run, and it names the file from the run's first input value.
- Authored configuration is not classified. Tool names, descriptions and schemas, and a workflow step's output schema, reach the model without a check. They are written by an authorized builder or administrator and are not supplied at run time. The descriptors of an external MCP server are supplied by the remote server, but they are frozen by a PlatformAdmin when the server's tools are admitted, and a later change is refused.
- Card numbers are recognised by their checksum alone. Any run of 13 to 19
digits that passes the card checksum is treated as a financial identifier,
as text or as a number. That is about one 13-digit number in ten, and a
millisecond timestamp is such a number. The share grows with length, to
about half of the runs of 19 digits. Under
class-v1a connector write that contains one is held for review and denied. Narrowing the detector to real card prefixes and lengths is planned as Task 4.5; until then the lever is publishing a bundle. - Encoded values are not decoded. A value written in another encoding, such as base64 or a list of byte values, is checked as the text or the numbers it is written as. The detectors do not decode it.
- A replaced pack slug changes the receipt. If a value in a pack's slug is replaced at retrieval, the receipt stores the replaced slug, not the original.
- A value split across fields is not reassembled. Each field is checked on its own, so a value divided between two fields is not found.
- Key context is the direct property name. A secret with no shape of its
own is recognised only by the name of the field that holds it, such as a
field called
password. A structure that names the field in one place and holds the value in another (a field callednameset topasswordnext to a field calledvalue) is not recognised that way. - Lookups. The arguments of a read-only connector lookup are not checked at the connector write boundary.
- Escaped private keys. A private key embedded in text where its line breaks are written as escape sequences is replaced only through its first line when that text is checked as one rendered string. Structured values are checked field by field, which avoids this.
- Other providers. Findings from a classifier other than the built-in detectors are counted in the logs, not in the findings table.
- Notifications. There is no outbound notification channel in the platform, so nothing is enforced there.
- Assistive control. Deterministic detection misses values it has no pattern for. It is a safeguard, not a compliance guarantee.