Sealing and split visibility¶
Edition: Community and Enterprise
A production fix usually names real customers: a national ID, a card number, an account. In the usual process that value travels in a ticket, an email, a chat and the script itself, and everyone who handles the change sees it. sealfix keeps the value away from everyone who does not need it, and shows each person exactly what their decision needs.
What sealing does¶
flowchart TB
V["Values typed<br/>by the requester"] --> API
subgraph API["Web application (public key only)"]
direction LR
M["Mask<br/>****4567"]
K["Fresh data key<br/>AES-256-GCM"]
W["Wrap the data key<br/>with the executor's public key"]
end
API --> S[("Store<br/>ciphertext + masked copy")]
S --> EX
subgraph EX["Executor (private key)"]
direction LR
U["Unwrap, decrypt in memory"]
B["Bind to the statements"]
end
EX --> DB[("Target database")]
classDef box fill:#E9EEF6,stroke:#23407A,color:#13202D
classDef seal fill:#F6E8EB,stroke:#7D1D2F,stroke-width:2px,color:#13202D
class M,K,W,U,B box
class S seal
- The web application receives the values once, in memory. It runs the value checks and computes the masked form.
- It encrypts them with a fresh data key per request (AES-256-GCM) and wraps that key with the executor's public key.
- It stores the ciphertext and the masked copy, and drops the plaintext.
The web application can seal, but it can never open what it sealed. Only the executor holds the private key. It opens the values in memory for the dry run and the execution, binds them to the statements and keeps no copy.
Bound, not pasted
Values reach the database only as bind variables, never as SQL text. Every approval also binds a digest of the sealed values: values swapped after approval are refused before anything is decrypted.
Who sees what¶
Each person sees what their decision needs, and nothing more.
| Template | Values | Masked values | Row counts and plans | Checks | |
|---|---|---|---|---|---|
| Requester | while typing only | ||||
| DBA reviewer | |||||
| Business approver | |||||
| Auditor | |||||
| Administrator | counts only | ||||
| Executor (service) | in memory, during a job |
Why the lines fall where they do:
- The DBA reviewer judges whether the SQL changes only the rows it should, with a plan the database can bear. That needs the SQL and its effect, not whose row it is. DBAs also have the most other ways into the data, so they get none of it.
- The business approver must recognise the case: the last digits, the amount. The masked form is enough.
- The administrator configures sealfix. That needs no content of any change, and an administrator can never approve.
A field a role may not see does not exist in that role's view at all, so neither a page nor the API can show it by mistake.
What leaves sealfix¶
None of these carries a value, masked or not:
- Notifications carry the request, the event, the state, the target and a link.
- The Git record holds templates, parameter kinds, approvals and counts.
- The SIEM export sends only the fields on each event's allowlist.
What sealing does not protect¶
Sealing keeps values away from the people and systems around a change. It cannot protect against someone who can already read the target database directly, a target that records bind values in its own logs, or root on the executor host. See What sealfix protects for what to do about each.