AI CodeOps

Policy engine

A policy engine evaluates rules against requested actions and returns allow or deny. How policy-as-code works, and how AI CodeOps uses it to govern AI sessions.

A policy engine is a component that evaluates rules against a requested action and returns a decision, such as allow or deny, separately from the application code that performs the action. The rules ("policy as code") can be changed, versioned and reviewed without changing the application.

What it is

The application asks the engine a question: "may this actor do this action on this resource?". The engine matches the request against its rules and answers. Good engines are deterministic, explain which rule decided, and have a defined default for when no rule matches. Some also support a dry-run or audit mode that records decisions without enforcing them.

Why it matters

With AI agents acting on your code, the question isn't only who may act but what the automation may do on its own. Keeping those rules in one engine means one place to read them, one place to change them, and one record of every decision. It also separates concerns: security teams own the policy, product code just asks.

In AI CodeOps

The workspace policy, under Secure → Policies, governs what AI sessions may do. Rules are a JSON array; each has an id, an action, an optional resource glob and a decision of allow, ask (needs a person's approval) or deny. There are seven actions:

workflow.dispatch   start a session           (allow, ask, deny)
agent.dispatch      run an agent step         (allow, ask, deny)
mcp.invoke          call an MCP tool          (allow, deny)
shell.command       run the test command      (allow, deny)
diff.apply          change a file             (allow, ask, deny)
github.push         open a pull request       (allow, ask, deny)
release.deploy      deploy automatically      (allow, deny)

A policy that asks before dependency upgrades, reviews infrastructure changes, blocks automatic production deploys and keeps delete tools away from agents:

[
  {
    "id": "approve-dependency-refresh",
    "action": "workflow.dispatch",
    "resource": "dependency-refresh",
    "decision": "ask"
  },
  { "id": "review-infra-changes", "action": "diff.apply", "resource": "infra/**", "decision": "ask" },
  { "id": "no-production-deploys", "action": "release.deploy", "resource": "production", "decision": "deny" },
  { "id": "no-repo-deletes", "action": "mcp.invoke", "resource": "github/delete_*", "decision": "deny" }
]

How it decides:

  • Every enabled rule whose action and resource match is considered. The strictest wins: deny beats ask, ask beats allow.
  • When no rule matches, the trust posture decides: trusted, limited (the default; opening a pull request is ask) or none (read-only unless a rule allows more).
  • Actions that can't wait for a person refuse ask in the editor; a stored ask on one is enforced as deny.
  • Log only mode evaluates and records without blocking.

Each save creates a new version and a policy.updated entry in the audit log. Denials, holds and log-only outcomes appear under Recent decisions. Editing the policy needs the policy:manage permission: owners, admins and security admins.

Frequently asked questions

Do AI CodeOps policies limit what people can do?

No. Policies govern what AI sessions may do. What a person may do is set by their role.

Does the order of rules matter?

No. Every matching rule is considered and the strictest decision wins, so adding a rule can never loosen another.

Can I test a policy without blocking anyone?

Yes. Switch to log only. Rules are still evaluated and decisions recorded, but nothing is blocked or held.