Where policies live
Policies are configured in the EgisAI dashboard. The dashboard is the source of truth; the SDK consumes the published configuration. You do not embed policy documents in your repository. The SDK works without any extra files.Categories of rules
Exact rule shape and ordering are managed in the product. The SDK consumes the
published configuration and applies rules in a fixed order designed to keep
sensitive content local-first (see How it works).
PII rules can carry patterns you define
The built-in PII types cover shapes that are the same at every company — an IBAN is an IBAN whether you are a bank or a bakery. The shapes that actually leak often aren’t:EMP-004182, an
internal case reference, a customer number that means nothing
outside your systems but is exactly what an auditor asks about.
A pii_scan rule accepts your own patterns alongside the checkbox
grid, under Your own patterns on the policy form:
EMP-004182 becomes ###-######), they appear
in the audit record with a count and mask shape and never the value,
and they run everywhere the built-in types run — SDK, gateway, and
egress node.
What they are not is a detector with a false-positive rate. The
built-in types are backed by checksums (Luhn, mod-97, Verhoeff) or a
named-entity model. A pattern is backed by whatever you wrote, which
is the right trade for EMP-\d{6} and the wrong one for “names of
our customers” — that is what the person_name type and intent
rules are for.
Patterns are checked when you save. One that could backtrack
catastrophically is refused with an explanation rather than accepted
and left to slow every agent in the org hours later.
Intent rules can target tool calls
semantic_guard rules accept a targets list in the dashboard. The
default is ["text"], which means the rule reviews the prompt or
response text only. Including "tool_calls" extends the rule to ask the
intent judge whether each individual tool dispatch matches the operator’s
described intent — useful when an agent decides to call a destructive
tool you didn’t enumerate by name (deny_tool_call is pattern-based and
needs an exact name).
Privacy contract: tool arguments are PII-label-redacted before they
reach the judge, so categories like SSN or email are replaced with
<SSN> / <EMAIL> placeholders before any external network egress.
Intent classification still works because the judge cares about the
verb / noun shape, not the exact identifier value.
Prompt-injection rules watch what your agent reads
injection_scan exists for one problem: your agent reads text nobody
on your team wrote — a fetched web page, a support ticket, a PDF, a
tool result — and that text contains instructions addressed to the
model. The model can’t tell the difference, so the instruction runs
with your agent’s credentials.
Six shapes are scored:
Detection is deterministic — compiled patterns and two character-class
counts, no model call and no network — so it runs in phase 1 on every
call with the rest of the local checks.
Two settings matter:
actionisflagby default. The finding lands on the audit row and the call proceeds. Start here: nobody can predict what their own tool results look like, and a rule that starts by refusing traffic gets switched off before it teaches anyone anything. Switch toblockonce you’ve watched a week of real traffic.phaseshould bebothorresponse. The request side catches a user typing an override; the response side catches the document that types it for them, which is the attack this is named for.
semantic_guard
sits behind it for the cases only a language model can judge.
Directory rules run on the server, not in your process
The Directory category (identity_guard) is the one exception to
“the SDK enforces everything”. It answers a question about live state —
does this person still work here? — and the answer changes while your
process is running. A cached copy would enforce Friday’s directory on
Monday and still report a green check, which is worse for an audit than
plainly not covering that path.
So these rules are enforced where Egis holds a live database connection:
- The gateway (
/v1/chat/completions) — model calls. - The MCP proxy (
/v1/mcp/{server}) — tool calls.
X-Egis-End-User header, which the SDK
already sends when you call set_context(end_user_id=...). If your app
passes an email address it is matched against the directory directly;
an opaque id is matched through the identity sync’s own bridge.
Agents that call providers directly through the in-process SDK are
not covered by a directory rule, and GET /v1/sdk/policies withholds
it rather than shipping a rule that would silently do nothing. Route
those agents through the gateway if you need this control on them.
Policy targeting
Operators can scope a policy to:- All agents in the org — applies everywhere.
- Specific agents — applies only to the listed agents.
- Agent groups — applies to a named set of agents managed in the dashboard.
Policy phases
Each policy also carries a phase that selects which side of a call it fires on:
Phase is chosen in the dashboard when an operator creates or edits a rule,
and the dashboard restricts the available phases to the combinations the
rule type actually supports. The legacy spellings
pre_model /
post_model are still accepted on every write path and normalize to
request / response. See
Two-phase governance for the full matrix
and how to choose the right phase for a rule.
Surface scoping
Orthogonal to phase, a policy can carry anapplies_to list that
scopes it to specific call surfaces: model, tool, and/or mcp.
Empty or omitted means “all surfaces” — the behavior every policy had
before surface scoping existed. Requires SDK ≥ 0.32.0; older SDKs
ignore the field and apply the rule everywhere (the safe direction).
Policy refresh
Once active, the SDK keeps your local cache fresh in two ways:- Live updates — when the live update channel is reachable, policy changes propagate to your process within seconds.
- Polling — at the interval set by
refresh_interval_seconds(default10), the SDK polls for updated configuration. This is the fallback for environments that block long-lived connections.
enable_sse=False; the SDK then relies on
polling alone.
Inspecting policies from your code
The SDK exposes its public types so you can integrate policy decisions outside the patched call paths if you need to. The most useful primitives are:
See the API reference for each type’s fields.
These primitives are deliberately pure-Python. They evaluate locally and do
no I/O, so you can use them inside your own code paths to apply consistent
policy semantics to text outside the patched provider SDKs.
Empty policy sets
If your organization has no enabled policies, every call passes through. The startup banner makes this visible:What’s next
Verdicts
The three outcomes a policy can produce.
API reference
Detailed reference for
PolicyRule, PolicyContext, and PolicyDecision.