Policies
Policies are the heart of Eda: deterministic rules, evaluated on every check, that every agent obeys. They run in the API in well under 10ms and never call a model, so they’re safe on your hottest paths.
Anatomy of a policy
| Field | Example | Notes |
|---|---|---|
| Agent glob | support-* | Matches agent. * matches everything. |
| Action glob | refund_* | Matches action. |
| Conditions | amount > 500 | Zero or more; all must hold (AND). |
| Effect | require_approval | allow · block · require_approval. |
| Priority | 100 | Higher wins when multiple match. |
| Enabled | true | Toggle without deleting. |
Effects
allow— explicitly permit. Use to carve exceptions above a broad block.block— deny outright → the decision isblocked.require_approval— pause for a human → the decision ispendinguntil someone approves (approved) or denies (denied).
Evaluation model
Highest-priority matching policy wins. If nothing matches, Eda allows. Model
“default-deny” by adding a lowest-priority catch-all block on */* and
layering allow exceptions above it.
- Collect every policy whose agent glob and action glob match the action.
- Drop those whose conditions don’t all hold against
params. - Of the survivors, the highest
prioritywins; ties break by most-recently updated. - Its effect becomes the decision. No match →
allow.
Example: layered refund policy
| Priority | Agent | Action | Condition | Effect |
|---|---|---|---|---|
| 300 | * | refund_* | amount > 5000 | block |
| 200 | * | refund_* | amount > 500 | require_approval |
| 100 | support-* | refund_* | — | allow |
A support-agent refund of $300 → matches all three by glob, but only the
priority-100 allow has satisfied conditions among the low tiers → approved. Of
$900 → priority-200 applies → pending. Of $9000 → priority-300 → blocked.
Conditions & operators
A condition is path op value, where path is a dot-path into params
(customer.tier, items.0.sku). Operators:
| Operator | Meaning | value |
|---|---|---|
== / != | equals / not equals | any |
> >= < <= | comparison | number/string |
in / not_in | membership | array |
contains | string/array contains | element |
startsWith / endsWith | string affix | string |
matches | regex test | pattern |
exists | path present | — |
These are the same operators the SDK’s local rules use, so you can prototype a rule in code and promote it to a server policy verbatim.
Managing policies
Create and edit policies in the dashboard → Policies: add condition rows, set priority, toggle enabled, and see the evaluation order (shown highest-priority first). Each save bumps a version so you have a change trail.
Policies are workspace-wide. A rule you add affects every agent and every integration (SDK, adapters, MCP) in that workspace. Scope with agent/action globs rather than assuming a policy is local to one service.
Risk-based escalation
If you enable AI risk scoring, an action that
policies would allow can still be escalated to require_approval when its risk
score crosses your workspace threshold. Deterministic policies are always
authoritative for block; risk scoring only ever makes things stricter, never
looser.