Policies
Policies are the rules that govern what your AI agents can and cannot do. Every action an agent takes is evaluated against your policies before it executes. If no policy matches, the action is denied. This is fail-closed by design — agents cannot act in the absence of explicit authorization.
What a Policy Is
A policy is a named rule that matches an action type and defines what happens when an agent attempts that action. At its simplest, a policy says: "When an agent tries to do X, the answer is Y."
The answer can be:
- Allow — the action executes immediately and is logged
- Deny — the action is rejected and the agent receives a structured denial
- Require approval — the action is held until a human reviewer approves or denies it, or until the approval window expires
- Conditional — the action auto-executes when conditions pass; escalates to human review when conditions fail. This is the smart middle ground for teams that want approval only when something unusual is happening.
Policies are evaluated in order of specificity. If you have a policy for db.migrate and a wildcard policy for *, an agent calling db.migrate is governed by the specific policy. An agent calling file.read — which has no specific policy — falls through to the wildcard.
Policy Fields
Every policy has the following fields:
Action Type Pattern
The action type this policy governs. Uses dot-notation to match against the action types your agents submit via the SDK.
- Exact match:
db.migratematches onlydb.migrate - Wildcard:
*matches any action type that does not have a more specific policy
Action types are free-form strings defined by your agents. Common conventions include code.commit, pr.merge, deploy.trigger, secret.read, db.migrate, and file.write, but you can use any naming scheme that fits your workspace.
Effect
What happens when an agent's action matches this policy:
| Effect | Behavior |
|---|---|
| Allow | Action executes immediately. Logged in the audit trail. |
| Deny | Action is rejected. Agent receives denial reason and failed conditions. |
| Require approval | Action enters the approval queue. Blocks until a human approves, denies, or the timeout expires. |
| Conditional | Conditions pass → auto-executes. Conditions fail → escalates to human review. Requires at least one condition rule to be configured. |
Approval Timeout
For policies that require approval: how long the action waits in the approval queue before timing out. Specified in hours. Common values:
- 2 hours for time-sensitive actions like deployments
- 4 hours for standard review actions like PR merges
- 8 hours for non-urgent actions that can wait for the next business day
When an approval times out, the action is marked as timed out, the agent is notified, and the event is recorded in the audit trail.
Conditions
Optional field-based rules that refine when this policy's effect applies. Conditions evaluate against the metadata your agents submit with each action. See the next section for details.
Version
Policies are versioned. When you update a policy, the previous version is retained. The audit trail records which version of which policy governed each action decision. This means you can always answer: "What were the rules when this action was approved?"
Active/Inactive
Policies can be toggled on and off without deletion. An inactive policy is skipped during evaluation. Use this to test new policies or temporarily relax constraints during incidents.
Attribution
Every policy records who created it. In the policy editor, you'll see the author's name and the date the policy was created. This is part of the accountability chain — when an action auto-executes under a policy, you can always trace back to the human who authorized that behavior.
Conditions
Conditions are field-based rules that add nuance to your policies. Instead of "always require approval for PR merges," conditions let you say "require approval for PR merges where the change is larger than 50 files."
Each condition has three parts:
- Field: The metadata key to evaluate (e.g.,
pr_size,sensitivity,environment) - Operator: The comparison to perform (e.g.,
ltfor less than,eqfor equals,neqfor not equals) - Expected value: The threshold or value to compare against
How Conditions Work
When an agent submits an action with metadata, conditions evaluate against that metadata. All conditions on a policy must pass for the policy's effect to apply. What happens when conditions fail depends on the policy's effect:
- Allow or Require approval — conditions fail → action is denied with a
CONDITIONS_DENIEDreason, and the agent receives an array showing exactly which conditions passed and which failed. - Conditional — conditions fail → action escalates to human review instead of being denied outright. This is the key difference: a
conditionalpolicy never denies on its own; it only decides whether to auto-execute or route to the approval queue.
For example, a policy on code.commit with the condition pr_size lt 50 and effect allow:
- Agent submits
code.commitwithmetadata: { pr_size: 30 }— condition passes, action is allowed - Agent submits
code.commitwithmetadata: { pr_size: 120 }— condition fails, action is denied withCONDITIONS_DENIED
The denied agent receives:
{
"conditions_evaluated": [
{ "field": "pr_size", "operator": "lt", "expected": 50, "result": false }
]
}
This structured feedback is what enables the self-correcting agent pattern: the agent reads which rule fired and adapts its behavior accordingly.
Supported Operators
| Operator | Meaning | Example |
|---|---|---|
eq |
Equals | environment eq "staging" |
neq |
Not equals | sensitivity neq "critical" |
lt |
Less than | pr_size lt 50 |
gt |
Greater than | change_count gt 100 |
lte |
Less than or equal | file_count lte 10 |
gte |
Greater than or equal | risk_score gte 70 |
Resource Scoping
Actions target resources: URLs your agent fetches, databases it queries, files it reads. Resource scoping lets you write policies that govern not just what an agent does, but what it does it to.
Pass the resource parameter in your gate() or execute() call:
await al.gate("web.query", { resource: "https://linkedin.com/api/search" })
await al.gate("db.query", { resource: "users_table" })
await al.gate("file.read", { resource: "/etc/passwd" })
Then write conditions that match on the resource field:
| Use case | Condition |
|---|---|
| Allow only specific domains | resource in ["https://linkedin.com", "https://x.com"] |
| Block a specific endpoint | resource neq "https://internal.corp/admin" |
| Allow a URL prefix | resource regex "^https://api\\.example\\.com/" |
How It Works
The resource string is opaque to AgentLattice. It flows through the entire pipeline:
- Your agent passes
resourcein the SDK call - The policy engine evaluates
resourceas a condition field (just likepr_sizeorenvironment) - The resource is stored in the audit trail as a top-level field
- Delegation scopes can restrict which resources a child agent can access
Resource in Delegations
When delegating to a sub-agent, you can restrict which resources it can access:
const result = await al.delegate("searcher", {
capabilities: ["web.query"],
ttl: 300,
// Coming soon: resources restriction in delegation scope
}, async (sub) => {
await sub.gate("web.query", { resource: "https://linkedin.com" }) // allowed
await sub.gate("web.query", { resource: "https://evil.com" }) // denied
})
Fail-Closed Behavior
If a policy condition references resource but the agent omits the resource parameter, the condition fails and the action is denied. This prevents agents from bypassing resource-scoped policies by simply not providing a resource.
Resource Is Optional
If you do not pass a resource parameter, everything works exactly as before. Resource scoping is opt-in. You can start with action-type-only governance and add resource scoping later as your security requirements grow.
Per-Agent Policy Scoping
By default, policies apply to every agent in your workspace. Per-agent policy scoping lets you create rules that target a specific agent, giving you fine-grained control without affecting the rest of your fleet.
How It Works
When you create a policy, you choose its scope:
- Workspace-wide — applies to all agents. This is the default and the behavior you already know.
- Agent-specific — applies only to the selected agent. Other agents fall through to workspace-wide policies for the same action type.
The Override Model
Workspace-wide policies have a lock toggle that controls whether agent-specific policies can override them:
| Workspace policy state | Agent-specific policy exists | Result |
|---|---|---|
| Locked (default) | Yes | Workspace policy wins — the agent-specific policy is ignored |
| Locked | No | Workspace policy applies |
| Overridable | Yes | Agent-specific policy wins |
| Overridable | No | Workspace policy applies |
This works like AWS Service Control Policies: a locked workspace policy is a hard floor that no agent-level customization can bypass. An overridable workspace policy is a default that individual agents can customize.
When to Use Per-Agent Policies
- Intern agent restrictions — your experimental agent gets
require_approvalforcode.deploywhile your production agent getsallow - Vendor agent sandboxing — a third-party integration agent is locked to specific action types and resources
- Graduated trust — new agents start with strict policies and earn more autonomy as they prove reliability
- Compliance segregation — certain agents that handle sensitive data have stricter conditions than general-purpose agents
Creating an Agent-Specific Policy
In the Policies page, select "Agent-specific" as the scope and choose the target agent from the dropdown. Agent-specific policies have the same fields as workspace-wide policies: action type, effect, conditions, and timeout.
Restrictions:
- Agent-specific policies cannot use the wildcard
*action type (this prevents an agent-level policy from silently overriding all workspace governance) - Only admins can create workspace-wide policies; members can create agent-specific policies for agents they own
Delegated Agents
When an agent delegates work to a sub-agent, the parent's policies apply to the delegated call. The sub-agent does not need its own policies — it inherits the parent's governance context. This means you only need to manage policies at the top-level agent, not for every ephemeral child.
Cloning Policies
When you create a new agent that should have the same policies as an existing one, use the Clone policies action to copy all agent-specific policies from the source agent. Cloned policies are independent copies — changing one does not affect the other.
The Wildcard Policy
When you sign up, AgentLattice creates a single default policy:
- Name: Allow All (Default)
- Action type:
*(matches everything) - Effect: Allow
- Approval required: No
- Conditions: None
This wildcard policy means every action your agents take is allowed and logged from day one. You get full visibility into agent activity without blocking anything.
As you add more specific policies, they take priority over the wildcard. The wildcard continues to catch any action type that does not have a dedicated policy. This gives you a safe starting point: everything works out of the box, and you layer on governance incrementally.
Important: If you delete the wildcard policy without creating specific policies for every action type your agents use, those unmatched actions will be denied. The system is fail-closed — no policy match means no access.
Common Policy Examples
Require Approval for Database Migrations
Any agent attempting a database migration must wait for human approval. The DBA or engineering lead reviews the migration metadata and decides.
- Action type:
db.migrate - Effect: Require approval
- Approval timeout: 4 hours
- Conditions: None
Every db.migrate action enters the approval queue. The agent is blocked until a reviewer acts or the timeout expires.
Auto-Approve Small Code Commits
Code commits that touch fewer than 50 files are low-risk and can be auto-approved. Anything larger requires human review.
-
Policy 1 — Small commits:
- Action type:
code.commit - Effect: Allow
- Conditions:
pr_size lt 50
- Action type:
-
Policy 2 — Large commits (fallback):
- Action type:
code.commit - Effect: Require approval
- Approval timeout: 8 hours
- Conditions: None
- Action type:
When an agent commits with pr_size: 30, the first policy matches and the action is auto-approved. When an agent commits with pr_size: 120, the condition on the first policy fails, and the action falls through to the second policy (or the wildcard, depending on your setup).
Deny Credential Access Without Explicit Grant
Agents should not be able to read secrets or credentials unless they have been explicitly granted that capability. This policy blocks all secret.read actions where the data sensitivity is critical.
- Action type:
secret.read - Effect: Deny
- Conditions:
sensitivity eq "critical"
Any agent that attempts to read critical-sensitivity credentials is immediately denied. The agent receives structured feedback showing that the sensitivity condition failed, enabling it to self-correct by requesting only non-sensitive data.
Require Approval for Production Deployments
Deployments to production require human review. Deployments to staging or development are auto-approved.
-
Policy 1 — Production deploys:
- Action type:
deploy.trigger - Effect: Require approval
- Approval timeout: 2 hours
- Conditions:
environment eq "production"
- Action type:
-
Policy 2 — Non-production deploys:
- Action type:
deploy.trigger - Effect: Allow
- Conditions:
environment neq "production"
- Action type:
An agent deploying to production waits for approval. An agent deploying to staging proceeds immediately. Both are logged in the audit trail.
Prefix Wildcards
Policies support prefix wildcards using domain.* syntax. A policy with action type web.* covers all web actions (web.query, web.browse, web.form_submit, etc.) without requiring a separate policy for each.
Specificity order (most specific wins):
- Exact match:
web.querycovers onlyweb.query - Prefix wildcard:
web.*covers anyweb.action - Global wildcard:
*covers everything
If both web.* and web.query policies exist, agents calling gate("web.query") will be evaluated against the web.query policy.
Discovered Types
When agents call gate() with granular action types (e.g., web.query), AgentLattice automatically catalogues those types in the Discovered Types section of the Policies page.
Each discovered type shows:
- Calls — total number of gate() calls for this action type
- Status — Allowed (executed at least once), Blocked (only ever denied), or Pending (awaiting approval)
- Covered By — the policy currently governing this action type
- Action — add a granular policy, or review blocked attempts
Auto-discovery is enabled by default for new workspaces. You can toggle it from either:
- Policies page — use the toggle next to the Discovered Types heading
- Workspace Settings — under the Auto-Discover Action Types section
Policy Design Principles
Start permissive, tighten over time. The wildcard policy lets everything through with logging. Use the activity feed to see what your agents actually do, then add specific policies for the actions that matter most. You do not need to define a policy for every possible action type on day one.
Use conditions to avoid over-blocking. A blanket "require approval for all code commits" will slow your agents to a crawl. Use conditions to auto-approve the low-risk majority and gate only the high-risk minority.
Leverage structured denials. When a condition fails, the agent gets back exactly which rule fired. Design your agent code to read this feedback and adapt — split large PRs, reduce scope, or escalate to a human. Governance should be a feedback loop, not a brick wall.
Version and audit your policy changes. Every policy edit is versioned and every action records which policy version governed it. This means you can trace any governance decision back to the exact rule set that was in effect at the time — a requirement for most compliance frameworks.