Overview
Log schemas modify matching Connector and Endpoint logs before Formal stores or exports them. Use schemas to remove, encrypt, truncate, or sanitize sensitive fields with field-level precision. Configure them with theformal_log_schema
Terraform resource. Each schema contains:
- A CEL scope that selects logs.
- One or more protobuf field paths.
- One or more actions for each path.
- An optional asymmetric encryption key.
Configure a Log Schema
This example removes SQL literals from queries for one resource:terraform apply, then query the resource through Formal.
Verify:
Open Logs and inspect the resulting request log.
The query has values_stripped: true and does not contain its original literals.
Scope Fields
Thescope_cel expression must return a boolean. It can use these fields:
The scope cannot inspect payload fields, timestamps, or the complete log. Use
paths to select payload fields after the scope matches.
Endpoint schemas use
log.source == "endpoint". Stored Endpoint logs use
source:desktop when you search them.Schema Actions
encrypt and encrypt_sql require encryption_key_id. The key must use an
asymmetric algorithm. See Encryption Keys.
You can combine compatible actions on one path. drop takes precedence over
every other action. Truncation runs before encryption. SQL stripping runs before
SQL encryption.
Encryption Examples
Each example encrypts one kind of log content. Every example needs an asymmetricencryption_key_id.
encrypt selects one string, google.protobuf.Struct, or
google.protobuf.Value field. To encrypt a whole message, such as an HTTP body,
list each sensitive field inside it.
A path can cross a repeated field, such as messages. The action then applies
to every element of that list.
You can merge these paths into one schema. Do not repeat a path across schemas.
HTTP Bodies
This schema encrypts HTTP request and response bodies from Connectors and Endpoints:received and sent hold the body before and after Formal policies run.
dry_run_policies holds the body that dry-run policies would produce.
LLM Content
LLM content appears in two places.log.llm is the top-level view of the whole
exchange. log.request.http.llm holds the LLM fields parsed from the HTTP
request. Encrypt both to cover every copy:
messages holds the prompt the client sent. response_messages holds the
model’s reply. content_parts.input holds tool inputs, encrypted as one value.
To remove prompts instead, use one drop path on log.llm.messages. Do not
combine it with child paths such as log.llm.messages.content_parts.text.
S3 Requests
This schema encrypts the bucket name and object path of S3 requests:Exec Streams
This schema encrypts the terminal data of Kubernetes exec sessions:terraform apply, then send matching traffic through Formal. Open
Logs and inspect the log. Each selected field
holds ciphertext instead of plaintext.
Supported Paths
Every path starts withlog. The following path families support schema actions:
encrypt and truncate only support singular string fields. drop can select
a supported parent field, string, list, or map.
Paths use protobuf field names, not search aliases. For example, use
log.request.http.body.received, not request_body.
Path Restrictions
A schema cannot contain both a parent path and its child. For example, you cannot combinelog.request.http.body with
log.request.http.body.received.
Do not configure overlapping paths across separate schemas.
Failure Behavior
Formal clears a selected sensitive field if its encryption action fails. It then continues applying actions to other paths. A failed SQL encryption clears the complete selected query object. A scope evaluation failure skips only that schema. Other matching schemas continue to apply.Next Steps
Configure Encryption Keys
Register an asymmetric key for encrypted fields
Policy Input Retention
Configure how long policy evaluation inputs are kept