Concept

The authorization model

Applies to: All SDKs Last updated: 2026-06-11

Every message that arrives at your agent is checked against a set of policy rules before being delivered to your code. The rules are persisted in an encrypted store the agent reads and writes via its own HexaEight key โ€” never as plain text on disk โ€” and are organised into four levels that cover increasingly specific cases. Rules are added and modified only through Bridge APIs; hand-editing the on-disk store is not supported. This page describes the model. The How-to section contains the practical steps for each rule type.

What gets checked, when

Authorisation runs at two moments:

  1. Before encryption, when your code asks the SDK to send a message. If a rule denies the outbound message, the SDK throws an exception and the message is never produced.
  2. After decryption, when a message arrives and the SDK has cryptographically verified the sender. If a rule denies the inbound message, the SDK returns the message with its body replaced by a fixed redaction marker, so your code sees that a message arrived but never sees the original content.

Both checks are automatic. They can be turned off globally with a single method call if your application uses an external authorisation system instead.

The bootstrap state

When the SDK starts up and finds no policy file (or an empty one), it enters a friendly state called bootstrap mode. In this state, every message is allowed. This is so a new application can start working immediately without forcing the developer to write a rule first.

As soon as you add your first rule, bootstrap mode turns off and the SDK starts enforcing.

How rules are stored

Policy rules are always persisted in an encrypted store โ€” plain-text on-disk storage is not supported. Two storage modes are available; pick the one that matches your deployment topology:

ModeWhen to useWhat's encrypted
Single-agent local-encrypted
EnableLocalEncryption
A single agent (or independent deployments of the same agent identity that don't share storage) The policy file on local disk, encrypted under the agent's own SKey-derived ASK. Only this agent identity can decrypt.
Swarm-shared encrypted
EnableSwarmMode
Multiple agents that need to share the same policy file (S3 / Azure Blob / shared filesystem) The policy file in shared storage, encrypted under a swarm-shared ASK. Any agent that holds the swarm key can read / write.

Rules are added or modified only through Bridge APIs โ€” AddPolicyRuleAsync, RemovePolicyRuleAsync, and ImportEncryptedPolicyAsync. Hand-editing the on-disk file is not supported; Bridge will refuse to load a file that wasn't produced by one of its own encrypt funcs.

Moving policy between deployments of the same identity

If you run the same agent identity in more than one location (typical for HA / DR / region replication where the deployments cannot share storage), use ExportEncryptedPolicyAsync on the source and ImportEncryptedPolicyAsync on the target. The destination deployment derives the source SKey on the fly (it shares the agent identity, so the SKey ASK is reproducible), decrypts the imported blob once, then re-encrypts it under its own SKey for ongoing local persistence.

The four levels of rules

Every rule has a realm column that determines what level of rule it is. There are four possible realm values:

RealmWhat it representsTypical use
default Always evaluated, for every message Your agent's baseline rules โ€” "anyone from acme.com is allowed", "anyone from evil.com is denied"
app:<hash-or-name> Evaluated when the sending application matches the named one "Only the billing portal application can write invoices"
session:<agent-name> Evaluated when the message belongs to session-mediated traffic at this agent (caller passes the agent's own name as sessionId to AuthorizeAsync) "On this agent's session-mediated traffic, [email protected] is allowed to relay to claude01.mycompany.com"
user:<sha512> Evaluated when a specific user is involved as sender, recipient, or original sender in a relay "Anyone acting on alice's behalf can't reach payment-gateway"

For most agents, the default realm is sufficient. The other three are there for finer-grained control when you need it.

Evaluation order: deny-overrides

When multiple rules match a single message, the SDK uses deny-overrides: any rule with effect deny causes the request to be denied, regardless of what other rules say. If no deny rule matches and at least one allow rule matches, the request is permitted. If nothing matches, the request is denied (default-deny).

This means you can build a baseline of allow rules and then add specific deny rules to block exceptions, without worrying about rule ordering.

Direction matters

Each rule applies to one direction:

A rule that allows inbound messages from a sender does not automatically allow outbound messages to them. This separation is intentional: there are legitimate cases where you want to receive from a party but not send to them, or vice versa.

What identity gets checked

The sender identity used for rule matching is the cryptographically verified sender, taken from inside the decrypted message โ€” not the opaque identifier in the wire header. This is important because the wire-level identifier is just a routing hint; only the inside-the-payload sender name is unforgeable.

External authorisation systems

The built-in engine described above is the default. If you have an existing authorisation system โ€” LDAP, OAuth, Open Policy Agent, AWS IAM, Azure RBAC โ€” you can replace the built-in engine with your own implementation. The rest of the SDK does not change; the encryption, decryption, and message handling all work the same way. Only the policy evaluation step is swapped out.

What the SDK does NOT check

The authorisation layer checks who sent a message and whether they are permitted to do so. It does not understand the content of the message. Rules like "if the message asks to delete files, only allow administrators" require a second authorisation layer that interprets natural language. That capability is on the roadmap as a separate layer; the current SDK does not provide it.

See also