Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

The policy engine

A ScaiLog policy is declarative YAML that decides, for every PI-marked field, exactly one of four things to do with it: encrypt, redact, drop, or keep. This page explains how a policy is written, how the engine resolves which rule wins, and how policies are versioned so old entries stay explainable forever.

What a policy decides#

Each PI field carries a pi_type from the taxonomy. When an entry is processed, the engine resolves an action for every PI field from the tuple (service, environment, pi_type), yielding exactly one of:

Action Effect on the field
encrypt Encrypt the value under the subject's DEK; store as ciphertext in pi_fields.
redact Replace the value with [REDACTED:<pi_type>]; store no PI.
drop Discard the value entirely; record only that a field of this type was dropped.
keep Store the value in plaintext (only appropriate for pseudonymous or DPO-cleared types).

The action is recorded per field in the entry's pi_meta, so you can always explain why a given value was encrypted, redacted, dropped, or kept.

A policy is YAML#

A policy is a named, versioned document with a list of rules. Each rule matches some subset of (service, environment, pi_type) and names an action; a rule can also set retention_days. The built-in default policy simply falls every type through to its taxonomy default:

yaml
1
2
3
4
5
6
7
policy: default
version: 1
rules:
  - pi_type: "*"
    action: default
entry_retention_days: 365
pi_entry_retention_days: 90

action: default means "use the taxonomy default for this pi_type" — so with the policy above, direct_identifier encrypts, credentials drops, pseudonymous keeps, and so on, exactly as the taxonomy prescribes. A more specific policy narrows behaviour, for example:

yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
policy: default
version: 2
rules:
  - pi_type: "*"
    action: default
  - pi_type: online_identifier
    service: checkout
    environment: prod
    action: encrypt
    retention_days: 30
  - pi_type: freeform_user_content
    environment: dev
    action: redact

Most-specific rule wins#

Resolution is deterministic. The engine collects every rule that matches the field's (service, environment, pi_type), then picks the most specific one. Specificity is scored by which dimensions a rule pins down:

  • matching an exact pi_type (not *) is worth the most,
  • then a specific service,
  • then a specific environment.

If two rules tie on specificity, the later rule (higher index) wins. If the chosen rule says action: default, or if no rule matches at all, the engine falls through to the taxonomy default for that pi_type. A field with a custom pi_type that has neither a matching rule nor a taxonomy default is dropped — the safe default is never to store an unrecognized PI value.

Versioning and validation#

Policies are never edited in place. Storing a new policy creates a new version (the next version number, or a higher one the document names explicitly), and old versions are kept forever. The resolved policy_version is frozen into every entry, so you can always reconstruct exactly which policy governed a historical entry and why each field was handled as it was.

Before a policy is accepted it is validated. Hard errors — such as an unknown action — raise immediately. Softer issues produce warnings: notably, a keep action on a PI type other than pseudonymous warns that it stores plaintext PI and is only lawful for pseudonymous or DPO-cleared custom types.

The two retention fields (entry_retention_days and pi_entry_retention_days) let PI-bearing entries expire sooner than ordinary entries.

Updated 2026-07-13 09:41:42 View source (.md) rev 2