Financial reasoning rarely requires a person's identity
A portfolio workflow may need balances, holdings, tax lots, cash needs, risk tolerance, or a target allocation. It usually does not need an email address, phone number, Social Security number, or account number to calculate the answer. Combining those two classes of data in every prompt creates avoidable exposure without improving the analysis.
Privacy by design begins by separating them:
- Financial facts needed for the task can be preserved when they are relevant.
- Direct identifiers should be removed or replaced before model processing.
- Credentials and secrets should be removed, never used as continuity tokens.
- The relationship between an identifier and a protected reference should remain inside the narrowest application boundary that needs it.
That separation is data minimization in practice. It does not make the remaining financial facts harmless, and it does not remove the need for contracts, access controls, retention limits, or secure provider configuration. It makes one important data path smaller and safer.
Sometimes minimization means not collecting the data
Payment credentials illustrate a stronger privacy pattern. Rainlight now sends users
to Stripe's hosted billing portal to add or manage a payment method and does not render
PAN or CVC inputs. The two former Admin API POST paths for manual card entry return
410 provider_managed_payment_methods, so an older client cannot silently restore the
retired application-side collection path.
For billing displays, reads use an explicit PAN/CVC-excluding projection rather than
selecting historical card-credential columns. It can still include personal billing
data such as cardholder name, billing address, and application metadata; those fields
remain subject to authorization, minimization, and retention. Canonical database SQL
keeps the legacy card_number_enc and card_cvc_enc compatibility columns in place
temporarily but requires both to be NULL. A focused regression test checks the UI,
retired API routes, service projection, and database constraint.
This is preferable to encrypting CVC or full card numbers inside the application: data that is not collected cannot leak from that application store. It reduces Celestice's payment-data and potential PCI DSS scope, but it is not a PCI compliance claim. The hosted integration, scripts, webhooks, authorization, incident response, and applicable self-assessment responsibilities still need periodic review.
The Admin API applies the same collection discipline to its browser-facing user-
integration routes. The self-scoped and legacy per-user POST paths return
410 provider_callback_required instead of accepting OAuth access, refresh, or ID
tokens. List, disconnect, and delete operations return an explicit metadata-only field
allowlist, and canonical SQL requires the legacy bearer-token columns to stay NULL.
The combined focused regression test covers these controls as well as the payment
boundary.
This claim is deliberately scoped to Admin API user integrations. A future OAuth connection still needs a validated server-side provider callback and an appropriate secret boundary. Financial-data connector credentials require a separate storage, encryption, rotation, logging, and access review; this control is not a claim of platform-wide secret handling or a complete OAuth implementation.
Authentication data follows a related non-replication rule. Rain's canonical
auth.users schema does not represent the upstream Supabase password hash or the
top-level confirmation, recovery, email-change, and phone-change one-time-token
fields. Internal synchronization uses an explicit allowlist projection, so those
upstream credential and OTP fields are ignored rather than copied into a second
application database. Regression tests and a clean canonical database deployment
exercise that boundary.
That guarantee applies to freshly created canonical databases and to the named top-level fields. Existing development databases must be recreated through the repository's canonical workflow to remove historical columns and data. Nested metadata and identity payloads are not recursively scrubbed by this projection, so they remain subject to separate inventory and minimization work.
One boundary for the shared agent path
A privacy control that developers must call manually in each prompt will eventually be missed. Celestice therefore places the control in shared context preparation rather than relying on every specialist agent to invent its own scrubber.
On the protected shared path, the filter runs before context can be sent to:
- a model used to compact or summarize a long conversation;
- the primary specialist model producing the response;
- a model evaluating response quality; or
- a model extracting information for long-term memory.
The Proposal specialist uses this shared boundary. The Director's model-assisted routing call applies the same privacy primitives and falls back to local routing rather than sending raw text when privacy configuration is invalid. OpenViking context integration protects stored content and uses purpose-scoped pseudonyms for explicit subject and agent identifiers.
This placement matters. Filtering only the final user prompt would leave older messages, system-added context, tool arguments, artifacts, evaluation payloads, and memory extraction as alternate routes. The Celestice filter recursively protects textual values in message content and structured model-bound fields, including tool calls and artifacts.
The same boundary also produces a non-sensitive report: policy version, operating mode, key version when relevant, and counts by transformed data class. Raw values and the internal purpose scope are excluded. That is useful evidence without turning the security log into another sensitive-data store.
The boundary is bidirectional
Screening prompts is necessary but not sufficient. A model's output is not inherently trustworthy—it can restate a value that should not have survived, echo content from an ingested document, or reproduce material from a web page that arrived through a tool call. If the privacy boundary only inspects what goes in, anything that leaks through an untrusted source or is reproduced by the model itself arrives at the user or the next pipeline step unchecked.
Celestice applies the same redaction and pseudonymization policy to model responses before they are returned to a user or passed to a downstream step. The outbound filter uses the identical classifier set and scope rules as the inbound filter. A value that would be redacted or pseudonymized on the way in receives the same treatment on the way out.
This is not redundant with inbound filtering. Consider two concrete failure modes that outbound inspection catches:
-
Restated context. A model summarizing a long conversation may reproduce an identifier from an older message that the inbound filter never saw because it arrived before the privacy boundary was introduced or through a legacy code path. Outbound inspection catches the restatement at the point of delivery.
-
Untrusted-source echo. A retrieval step ingests a document containing another person's contact details. The model quotes those details verbatim in its answer. The inbound filter applied to the retrieval payload may have pseudonymized the values for the model's context, but the model can still emit the original form if it was memorized during training or appeared in a prior turn. The outbound pass treats the response as untrusted text and applies the same transformations.
The outbound filter produces its own content-free evidence line—policy version, direction, and counts by class—so the audit record shows that both directions were inspected for every model interaction.
Redaction and pseudonymization solve different problems
Celestice supports two transformations.
Redaction replaces a recognized value with a category marker such as
[EMAIL_REDACTED]. It is the safer default when downstream reasoning does not need to
know whether two occurrences refer to the same value.
Pseudonymization replaces a recognized identifier with a stable protected reference within a deliberately narrow scope. Two appearances of the same email can receive the same pseudonym for one user, agent, and purpose, while the same email receives a different pseudonym in another scope. This preserves limited continuity without creating a platform-wide tracking key.
The shared privacy filter derives those references with a keyed cryptographic function. It includes the environment, purpose, agent, and subject in the scope, and includes a key version so rotation can be controlled. The raw identifier and internal scope are not embedded in the output. Credentials are always redacted even when identifier pseudonymization is enabled.
Some systems use vault-backed tokens when an authorized application workflow must restore an original display value. That is a different pattern: the protected token map must remain inside the application boundary, be separately access-controlled, and be limited to the workflow that needs re-linking. A model should receive the token, never the map. Celestice's shared HMAC pseudonyms are not themselves reversible; they are stable, purpose-limited references.
The privacy effect of pseudonymization
This distinction is both technical and legal. Anonymization aims to make a person no longer identifiable by reasonable means. Pseudonymization keeps additional information that can distinguish or re-link records, even if that information is held separately. Under the GDPR definition, pseudonymized data remains personal data.
Pseudonymization reduces direct exposure and cross-context linkability while preserving the limited continuity a workflow needs. Celestice combines it with data minimization, tenant authorization, provider governance, access controls, retention practices, and customer configuration so each privacy layer has a clear purpose.



