Skip to main content
The egisai package exposes a small, frozen set of dataclasses for callers that want to use the policy engine outside the patched provider SDKs. They are all plain Python dataclasses — no I/O, no hidden state — so they are safe to log, diff, and pickle.

PolicyRule

One active rule. The type field selects the evaluator inside the engine — common values include pii_scan, deny_regex, allow_model, max_prompt_chars, and semantic_guard. The config dict carries the type-specific options. agent_ids scopes the rule to specific agents — an empty tuple means “applies to every agent in the tenant”. phase selects which side of a call the rule fires on: The legacy wire spellings pre_model / post_model are still accepted and normalize to request / response when the rule is parsed. Every rule type accepts every phase. The engine evaluates each rule on whichever side it has meaningful signals for: text-content rules fire symmetrically on the prompt and the response; tool / shell / connector rules need response-side signals and silently no-op on request only. Older platform deployments that haven’t shipped the field yet behave as if every rule were both, preserving previous semantics. See Two-phase governance for the full phase × type matrix. applies_to scopes the rule to specific call surfaces ("model", "tool", "mcp"). An empty tuple means “all surfaces”. The evaluation functions accept a matching surfaces argument and skip rules whose scope doesn’t intersect it.

PolicyContext

Inputs for evaluating input-side policies — i.e. before the model call runs. Construct one when you want to evaluate rules against arbitrary text outside the patched call paths.

OutputPolicyContext

Inputs for evaluating output-side policies — i.e. after the model has responded. Captures the structured response so output-side rules can inspect both the assistant text and any tool / connector calls.

PolicyDecision

Outcome of evaluating a list of PolicyRule objects against one PolicyContext (input side) or OutputPolicyContext (output side).
The field was previously named sanitize_kinds. The new canonical name is sanitize_types, and sanitize_kinds is exposed as a deprecated read-only alias for one release while consumers migrate. Prefer sanitize_types in new code.
PolicyDecision exposes three convenience constructors, mostly used internally:

MatchedPolicyRecord

Each entry in PolicyDecision.matched_policies:
This makes it possible to render an audit row that lists every rule that contributed to the final outcome — even rules whose individual verdicts were overridden by a more restrictive one.

Sanitization

Returned by egisai.policy.pii.sanitize() alongside the masked text. Records the shape of what was masked (type + count + mask) but never the raw value — auditable without leaking the value it was meant to protect.

label_redact

Replace every PII match in text with a typed label (<SSN>, <EMAIL>, <CREDIT_CARD>, …) instead of the mask-character shape used by sanitize(). Useful when you want to log a redacted preview of a payload to your own observability pipeline without sending the raw bytes.
label_redact is local-only and runs the same detector pipeline as the policy engine, so the categories it knows about match what pii_scan policies enforce.

evaluate_policies

Run the supplied input-side rules against context and return the resulting PolicyDecision. No I/O — purely deterministic for the local rule kinds.

evaluate_output_policies

Run the supplied output-side rules against context and return the resulting PolicyDecision. Use this when you have a structured response (text + tool calls) that you want to evaluate before forwarding it to a downstream consumer.

Example

What’s next

Verdicts

What allow / sanitize / block mean for your call.

Policies

Categories of rules behind the verdicts.