AI CodeOps

Policy rules reference

Write workspace policy rules for AI sessions: the seven actions, allow, ask and deny, resource globs, trust postures, log-only mode, and a worked example.

A workspace policy decides what AI sessions may do on their own, what needs a person's approval, and what they may never do. This page is the reference for writing rules. For how approvals work once a rule asks for one, see Approvals and policies.

Policies govern sessions only. What a person may do is set by their role.

Open the policy

Open Secure → Policies. The page shows:

  • Enforcement: Enforced or Log only.
  • Rules in effect, Trust posture and Version.
  • Rules: each rule's ID, action, resource and decision.
  • How rules apply: the actions and what each one matches.
  • Recent decisions: the latest denials, holds and log-only outcomes, with View session.

The page is shown to roles with the policy-manage permission: owners, admins and security admins by default.

Rule format

Rules are a JSON array. Each rule has these fields:

FieldRequiredWhat it is
idYes1–64 characters: letters, digits, ., _, : or -. Unique.
actionYesOne of the actions below, or * for every action.
decisionYesallow, ask (needs an approval) or deny.
resourceNoA glob matched against what the action touches. Omitted means all.
descriptionNoUp to 500 characters, shown under the rule's ID.
enabledNofalse keeps the rule but stops it applying.

A policy can hold up to 200 rules.

Actions

ActionLabelResource it matchesWhen it is checkedDecisions
workflow.dispatchStart a sessionworkflow IDWhen a session startsallow, ask, deny
agent.dispatchRun an agent stepagent ID, e.g. builderWhen a session starts, for every agent it will runallow, ask, deny
mcp.invokeCall an MCP toolserver/toolWhen a session starts, for each connected MCP toolallow, deny
shell.commandRun the test commandthe commandBefore the session runs your testsallow, deny
diff.applyChange a filefile path, e.g. infra/**When the pull request is opened, for every fileallow, ask, deny
github.pushOpen a pull requestowner/repoWhen the pull request is openedallow, ask, deny
release.deployDeploy automaticallyenvironment nameBefore an automatic deploy after a mergeallow, deny

Some actions can't wait for a person, so they can't use ask. The editor refuses an ask on them. A stored ask on one of them is enforced as deny.

What each decision does:

  • Session start (workflow.dispatch, agent.dispatch): deny refuses the session. ask holds it until someone approves it under Review & Gate → Approvals; rejecting or letting it expire cancels it.
  • MCP tools: a tool that isn't allowed is never offered to the agents.
  • Pull request (github.push, diff.apply): deny refuses the pull request. ask requires an approved review of the change. The session still runs and proposes its change; the rule decides whether it can land.
  • Automatic deploy: anything but allow stops the deploy. It is recorded as a blocked deployment so you can see it didn't go out.

How rules are evaluated

  1. Every enabled rule whose action matches (or is *) and whose resource matches is considered.
  2. The strictest decision wins: deny beats ask, and ask beats allow. Rule order doesn't matter.
  3. If no rule matches, the trust posture decides.

Resource globs

  • ** matches anything, including /.
  • * matches any run of characters. For file paths, server/tool and owner/repo, it stops at /.
  • ? matches one character.
  • No resource, * or ** matches everything.

So src/*.ts matches src/app.ts but not src/lib/app.ts; use src/** for the whole folder.

Trust posture

The posture applies when no rule matches.

PostureDefault decisions
trustedEverything is allowed.
limited (default)As trusted, but opening a pull request is ask.
nonedeny for MCP tools, the test command, file changes, pull requests and automatic deploys, unless allowed.

Every session that changes code also gets a review request under Review & Gate → Approvals. The posture adds to that; it doesn't remove it.

Example

This policy holds dependency upgrades for approval, asks for a review of any change to infrastructure files, blocks automatic deploys to production and keeps one MCP tool away from the agents:

[
  {
    "id": "approve-dependency-refresh",
    "action": "workflow.dispatch",
    "resource": "dependency-refresh",
    "decision": "ask",
    "description": "A person approves before a dependency upgrade session starts"
  },
  { "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" }
]

Edit the policy

  1. Open Secure → Policies and choose Edit rules.
  2. Pick a Trust posture.
  3. Edit the rules in the JSON box. An example is shown under it.
  4. Choose Save (version → N).

If a rule has a problem, nothing is saved and every problem is listed, for example Rule 2: decision — "mcp.invoke" cannot wait for an approval; use allow or deny. If someone else saved first, you see "Policy conflict" and the page loads their version; make your change again.

Each save creates a new version and a policy.updated entry in the audit log.

Log-only mode

Choose Switch to log only to stop enforcing without deleting rules. Every decision is still computed and recorded, shown as "logged" under Recent decisions, but nothing is blocked or held. Choose Enforce to turn it back on. Use log-only mode while you tune a new policy.

Only decisions other than a plain allow are recorded.

Next steps

Frequently asked questions

Does the order of my rules matter?

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

Do policies limit what people can do?

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

Can I test a policy without blocking anyone?

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

Was this page helpful?