Elizon Docs
Deployment

Personal data in traces and logs

What Elizon scrubs, seals or encrypts before run data is stored, with which key, and what is not scrubbed.

Run data passes through records that people rarely review: the run trace, workflow history, telemetry and service logs. Elizon makes sure personal data and secrets in those records are scrubbed, sealed or encrypted before they are stored, whatever your policies say. Your policies decide what a run may do with the data. This page is about what is left behind once it has done it.

What replaces a value

Where a record is scrubbed, a detected value is replaced by a placeholder that names its kind:

FoundStored as
An IBAN, also when written in groups of four[IBAN]
A payment card number, also with spaces or dashes[CARD]
An EU VAT number[VAT_ID]
A Bulgarian ЕГН[EGN]
A national identity number (BG, DE, FR, ES, IT, NL, RO, PL)[NATIONAL_ID]
An email address[EMAIL]
A phone number[PHONE]
An IP address[IP]
An API key or bearer token[SECRET]
A match of one of your custom patterns (Enterprise Edition)[CUSTOM]
A person's name (Enterprise Edition)[PERSON]

A value inside a URL is found too, also when it is percent-encoded (ana%40example.com), and a value right after a line break inside logged JSON text. A placeholder cannot be turned back into the value. (Redaction, in Enterprise Edition, is different: it hands the model numbered placeholders such as [IBAN_1] and can put the real values back where a policy allows it.)

The detectors run in the AI worker only. The API gateway and the workflow worker ask it to scrub a step's data once per write, and keep content out of their own logs instead of scanning them.

What happens to each record

RecordWhat happens
The workflow run trace (each step's input, output and error message, and a run's error message)Stored scrubbed: this is what the Activity tab, the run trace, exports and the API show. When something was detected, the step's real input and output are also stored sealed (encrypted) beside it, because a later step may need them: a Send Email step whose To is {{ upstream.lookup.output.email }} still reaches the real address, and Retry from here reuses the real outputs.
Workflow history (Temporal)Encrypted whole: every payload, failure message and stack trace. Nothing is scanned. The Temporal UI and temporal workflow show display ciphertext only.
Telemetry (OpenTelemetry)Span names, attributes, events, links and status messages are scrubbed before they are exported. Telemetry is only exported when OTEL_EXPORTER_OTLP_ENDPOINT is set.
Skill tool calls recorded on an Agent's answerThe arguments and output of each call are stored scrubbed. If they cannot be scrubbed, the calls are not stored.
AI worker logsScrubbed as each line is written (message, arguments, extra fields, tracebacks), uvicorn's and Celery's included. A line that cannot be scrubbed is withheld.
API gateway and workflow worker logsCarry ids and metadata, not content. Request and response bodies, payloads, step input and output and auth headers are removed ([redacted]), request URLs are logged without their query string, and an error keeps its type and code while its message is replaced by [redacted] unless it is a known-safe message. The Temporal SDK's own worker log follows the same rule.

If the AI worker cannot be reached when a step's data is written, Elizon does not store it unscanned: the step's input and output are sealed, and the run trace shows [unavailable: not scanned] for them. The run carries on with the real values. The same happens when a step's data is larger than the scrub request limit (8,000,000 bytes) or the AI worker does not answer within 10 seconds; each such write logs a warning naming the run and the step, never the data.

Community and Enterprise Edition

Community Edition finds the values in the first table with pattern detectors (with check digits where the format has one). Enterprise Edition adds people's names with its name recognition model in the run trace, telemetry and recorded skill tool calls; AI worker logs use the patterns only, in both editions. Name recognition reads at most POLICY_NER_SCRUB_MAX_BYTES (UTF-8, 4096 by default) of each text here: a longer text is scrubbed by the patterns alone. This is not POLICY_NER_MAX_BYTES (512 by default), the cap on name recognition while a request is being answered. If the model fails, the patterns still apply. In telemetry, names are found on the export thread, never while a request is being answered.

Your custom patterns (Enterprise Edition) apply to the run trace, telemetry and recorded skill tool calls. They do not apply to service logs, and workflow history needs none: it is encrypted whole.

Per-policy exclusions (a known false positive you told a policy to ignore) are not applied to scrubbing. A value that is hidden when it did not need to be costs nothing.

What is not scrubbed

  • The chat transcript. The messages in an Agent or Team conversation (Studio chat and the API) are the user's own record and are stored as written. If a user types an IBAN, the conversation keeps it.
  • Agent memory. An Agent with memory can store a fact that holds a raw value, and use it in a later conversation.
  • Numbers stored as numbers. A value written as a JSON number (not a string) in a step's data stays as it is; a JSON number has no room for a placeholder.
  • Text an AI worker component prints with print() instead of logging it. Only log records are scrubbed.

Use data rules in a policy to stop personal data from reaching a model, a tool or an outbound workflow step in the first place.

For operators: keys

Both kinds of encryption use AES-256-GCM with a fresh IV for every value, under keys derived (HKDF-SHA-256) from the deployment's ENCRYPTION_MASTER_KEY, the same root key the Secrets vault uses:

DataKey
A step's sealed input and output (execution_nodes)One key per Organization (run-data-seal/v1)
Workflow history (Temporal)One key per installation (temporal-seal/v1)
  • The AI worker is on every run's path: the workflow worker and the API gateway call it on every step write, so the workflow worker now also needs AI_WORKER_URL and INTERNAL_SERVICE_TOKEN. It refuses to start without AI_WORKER_URL (there is no default), so a worker with the variable missing fails at start-up instead of storing every step as [unavailable: not scanned]. The URL itself is not checked at start-up: a wrong or unreachable one still gives [unavailable: not scanned].
  • The workflow worker now needs ENCRYPTION_MASTER_KEY, loaded the same way as the API gateway and the AI worker load it (from Infisical, or from the environment with INFISICAL_BYPASS=true outside production). It refuses to start without it.
  • Back the key up. Losing ENCRYPTION_MASTER_KEY makes sealed step data and workflow history unreadable, as well as your stored secrets: open runs cannot continue and Retry from here cannot reuse sealed outputs.
  • There is no key rotation yet. Every sealed value carries a version byte, so a later release can add one; a value with a version this release does not know fails the run with an error that names the version, instead of retrying for ever.
  • INTERNAL_SERVICE_TOKEN plays no part in this encryption and can be rotated on its own.
  • The Temporal UI shows ciphertext only. A codec server that lets an operator read history in the UI is a later improvement.
  • Workflow history recorded before this release is not re-encrypted; it keeps replaying and expires with the namespace's 90-day retention.
  • Temporal Schedules created before this release (recurrence, email and app triggers) keep their action arguments (the start arguments of each scheduled run) in plaintext, with no expiry; they are encrypted when the workflow is next published (publishing replaces the Schedule's action), or when it is unpublished and published again.
  • When step data is purged after the retention period, the sealed copies are purged with it, and deleting an Organization deletes them with its runs.