Policies
Guardrails decide whether content is safe. Policy decides whether a caller is allowed to make the request at all, based on identity, context, and organisational rules. On an LLM Surface, the appliance-wide (global) policies for that surface type run before the surface’s own OPA policy. Both are deny-overrides and fail-closed, so a deny from either stops the request. A global policy set to Monitor only is the exception: it records its decision without blocking. Cost and usage governance →
OPA
OPA is the embedded Rego policy engine used by Agent Stream, so policies are compiled and evaluated in-process with no sidecar or network round trip.
Gateway-Level Policy
Gateway-Level Policy is the Trust Fabric policy type, attached to the appliance’s own gateway or to a gateway connection, or enforced appliance-wide. It gates fabric traffic, the gateway-to-gateway (DIDComm) traffic between appliances, rather than LLM Surface requests.
Surface-Level Policy
Surface-Level Policy is the OPA policy attached to a Surface and evaluated after the global policies for its surface type. LLM Surface policies use the package llm.policy; IDE Surface policies use the package ide.policy.
How front-door policy tells discovery apart from dispatch
The IDE Surface’s OPA input distinguishes, in input.request.purpose, discovery (GET /v1/models, which a policy can allow unauthenticated) from dispatch (POST /v1/chat/completions, which requires the signed-in caller), so sign-in never hits a chicken-and-egg where a client cannot fetch the sign-in profile because it is not yet signed in.
How a policy reference points to a reusable definition
- Policy Reference: A pointer from a Surface or a Gateway field to a stored OPA policy definition.
- Policy Definition: Stored Rego source plus metadata that can be reused by many Surfaces or Gateways. Definitions are immutable per version and carry a content hash so audit evidence can prove the exact bytes that ran.
A surface or gateway can also enforce more than one policy at once. The combination is deny-overrides, so every referenced policy must allow a request for it to proceed. An administrator can additionally mark one or more policies as enforced globally across every surface of a type, ANDed with that surface’s own policy set, with a monitor-only rollout mode for observing the effect of a global policy before it blocks anything.

Model Allow-List
A Model Allow-List is a member-level list of models the Member is permitted to invoke. A request to a model that is not on the allow-list is rejected with 403 model_not_allowed.
What each policy type checks
You create policies of three types, each with its own Rego package. The Policies page shows them on the Trust Fabric, LLM Policies, and IDE Policies tabs:
| Policy type | Package | Applies to |
|---|---|---|
| Trust Fabric | agentstream.policy | Appliance-to-appliance (DIDComm) fabric traffic, rather than LLM Surface requests. |
| LLM Policies | llm.policy | LLM Surfaces. |
| IDE Policies | ide.policy | The IDE catalogue’s front door, then any per-member Model Policy once the front door passes. After dispatch, the member LLM Surface’s own policies, global and surface-level, still apply. |
What a policy can see
Agent Stream builds this input document automatically before every evaluation. A policy only ever reads from it and never declares or constructs input itself. Optional fields appear only when they apply to the current request. An abridged example for a chat request to an LLM Surface:
{
"schema_version": 1,
"http": { "method": "POST", "path": "/v1/chat/completions" },
"source_auth": { "method": "jwt_bearer", "subject": "user-123", "claims": { "role": "admin" } },
"resource": { "model": "gpt-5.5", "surface_type": "llm" },
"action": "dispatch",
"environment": { "now": "2026-01-01T00:00:00Z" },
"identity_binding": { "verified": true, "agent_did": "did:web:agent.example", "issuer_did": "did:web:issuer.example" }
}schema_version versions the input contract itself. source_auth.method names how the caller authenticated: jwt_bearer, api_key, or mtls. action is dispatch for a request to a model, and connect when a realtime voice session opens.
A policy reads a value with plain dot notation, such as input.source_auth.claims.role == "admin" to check a JWT claim, or input.resource.model to gate on the requested model. See Input document → for the complete field-by-field reference, including the fields not shown here.
Policies are immutable and versioned
Editing a policy never overwrites it: each save appends a new, numbered version, and prior versions are kept for as long as the policy exists. A denial recorded in a governance record names the policy, its version, and its content hash, so it can be proven against the precise policy that produced it. A policy change can also be dry-run against a sample input before it is activated, so a bad global policy doesn’t lock out every surface it applies to.

Why an embedded, in-process engine matters
Because policy evaluation runs in-process rather than as a network call to a sidecar, a policy decision adds no network latency and has no separate service to keep available.
Related
- Guardrails: Content-safety checks that run alongside policy in the request pipeline.
- Cost and attribution: The team gate that runs immediately after inbound policy.
- Security and access control: How source authentication establishes the identity a policy evaluates.
- Trust Fabric integration: The appliance-to-appliance DIDComm traffic the Trust Fabric policy type evaluates.
- Pipeline and stages: Where global and surface-level policy run in the inbound stage order.
Glad to hear it! Please tell us how we can improve more.
Sorry to hear that. Please tell us how we can improve.
Thank you for sharing your feedback so we can improve your experience.