Policy Authoring
Policy Authoring Workflow
Use this workflow to reduce policy rollout mistakes before runtime enforcement.
Objective
Make policy changes deterministic, reviewable, and low-friction for developers:
- scaffold from a baseline template
- validate syntax and semantics early
- normalize formatting deterministically
- test verdict behavior against intent fixtures
Recommended Authoring Loop
gait init --template baseline-mediumrisk --json
gait check --json
gait policy validate .gait.yaml --json
gait policy fmt .gait.yaml --write --json
gait doctor --json
# Optional richer fixture loop from a repo checkout:
gait policy test .gait.yaml examples/policy/intents/intent_write.json --json
gait policy simulate --baseline examples/policy/base_medium_risk.yaml --policy .gait.yaml --fixtures examples/policy/intents --jsonInterpretation:
policy validatechecks strict YAML parsing + policy semantics only.policy fmtrewrites normalized YAML deterministically.doctorconfirms the install-safe onboarding lane before you depend on richer repo fixtures.policy testevaluates one intent fixture and returns verdict, reason codes, andmatched_rule.policy simulatecompares baseline vs candidate verdicts over fixture corpora and recommends rollout stage (observe,require_approval,enforce).
Equal-Priority Contract
When multiple rules at the same priority match one intent, Gait evaluates the entire matching priority tier and applies the most restrictive verdict from that tier.
- verdict precedence is
allow < dry_run < require_approval < block - renaming same-priority rules must not change the verdict
matched_ruleremains deterministic and may include a comma-separated set of same-priority matches when more than one rule is visible
If you need one rule to win unconditionally, give it a strictly lower numeric priority instead of relying on rule names.
Migration Notes
- For context-required policies, runtime enforcement now requires a verified
--context-envelopeongait gate eval; raw intent context claims are not enough to satisfyrequire_context_evidence,required_context_evidence_mode, ormax_context_age_seconds. - If a policy review depends on a same-priority rule "winning" by name, change the numeric
priorityinstead. Equal-priority names are no longer part of the verdict contract.
Draft Proposal Migration
If an older draft or pasted spec still uses the proposal keys below, keep the repo-root .gait.yaml contract and migrate to the shipped fields instead:
version->schema_idplusschema_versionname-> remove the top-level field; userules[].nameonly where rule naming mattersboundaries->rulesand optionalmcp_trustdefaults->default_verdictand optionalfail_closedtrust_sources->mcp_trust.snapshotafter rendering a local trust snapshot fileunknown_server->mcp_trust.actionwith local snapshot coverage and fail-closed policy
gait policy validate .gait.yaml --json now returns deterministic migration guidance when those draft proposal fields are present, rather than silently accepting a second policy DSL.
Repo-Root Policy Contract
The default onboarding contract is the repo-root file .gait.yaml.
gait init --json writes that file and returns:
policy_pathtemplatedetected_signalsgenerated_rulesunknown_signalsnext_commands
gait check --json reads .gait.yaml and reports the live contract, including:
default_verdictrule_countfindingsgap_warningsnext_commands
Use gait policy init --out gait.policy.yaml --json only when you intentionally want a non-default path.
next_commands from gait init --json and gait check --json stay install-safe: they only point at commands and files available after the CLI created .gait.yaml. Repo fixture paths under examples/policy/intents/ remain a repo-checkout authoring lane.
Common Top-Level Fields
The schema for .gait.yaml is schemas/v1/gate/policy.schema.json.
Most policies start with these fields:
schema_id: must begait.gate.policyschema_version: currently1.0.0default_verdict: one ofallow,block,dry_run,require_approvalfail_closed: optional high-risk missing-data rulesmcp_trust: optional local trust-snapshot contract for MCP server admissionrules: ordered rule list
Example:
schema_id: gait.gate.policy
schema_version: 1.0.0
default_verdict: block
fail_closed:
enabled: true
risk_classes: [critical]
required_fields: [targets, arg_provenance]
mcp_trust:
enabled: true
snapshot: ./examples/integrations/mcp_trust/trust_snapshot.json
action: block
required_risk_classes: [high, critical]
min_score: 0.8
rules:
- name: require-approval-tool-write
priority: 20
effect: require_approval
min_approvals: 2
match:
tool_names: [tool.write]
reason_codes: [approval_required_for_write]Common Rule Fields
Rules usually combine:
name,priority, andeffectmatch.tool_nameormatch.tool_namesmatch.risk_classes,match.target_kinds,match.identities, or other structured selectorsreason_codesand optionalviolations
Additional rule features are available when needed:
endpointfor path/domain and destructive endpoint controlsdestructive_budgetandrate_limitfor bounded executionrequire_context_evidencefor context-proof gatingrequire_broker_credentialfor broker-backed approval flows- script-specific controls via
approved-script-registryongait gate eval
Failure Semantics
- exit
0: valid / allow path - exit
3: policy test verdictblock - exit
4: policy test verdictrequire_approval - exit
6: invalid input, parse error, unknown field, or invalid schema/value
Treat exit 6 as fail-closed in CI and production rollout lanes.
IDE Schema Wiring (YAML Language Server)
For editors that support YAML schema mapping, point policy files at:
schemas/v1/gate/policy.schema.json
Example VS Code workspace settings:
{
"yaml.schemas": {
"./schemas/v1/gate/policy.schema.json": [
".gait.yaml",
"gait.policy.yaml",
"examples/policy/**/*.yaml"
]
}
}This gives fast feedback for enum values and unknown keys before runtime.
Team Workflow Recommendation
- Require
policy validate+ fixturepolicy testin pre-merge CI. - Run
policy simulateagainst representative fixture sets before changing rollout stage. - Keep policy files formatted by
policy fmt --writebefore review. - Review policy changes with fixture deltas and matched-rule evidence, not raw YAML diff alone.
- Include equal-priority overlap fixtures in CI when multiple rules intentionally target the same tool surface.
- For context-required fixtures, include a
gait gate eval --context-envelope ... --jsonlane so CI exercises the same boundary contract as production. - Keep the repo-default contract truthful: if docs say
.gait.yaml, examples should use.gait.yamlunless a custom path is the point of the example.
Signing Key Lifecycle (Local)
For production verification profiles and trace signing workflows, manage keys with CLI primitives:
gait keys init --out-dir ./gait-out/keys --prefix prod --json
gait keys rotate --out-dir ./gait-out/keys --prefix prod --json
gait keys verify --private-key ./gait-out/keys/prod_private.key --public-key ./gait-out/keys/prod_public.key --jsonExample Policy Packs
- baseline templates:
examples/policy/base_low_risk.yaml,examples/policy/base_medium_risk.yaml,examples/policy/base_high_risk.yaml - endpoint controls:
examples/policy/endpoint/* - skill trust controls:
examples/policy/skills/* - simple guard fixtures:
examples/policy-test/*
Frequently Asked Questions
What happens if no rule matches a tool call?
The default action applies. In fail-closed mode (oss-prod profile), the default is block. In standard mode, the default is configurable per policy.
Can I test a policy without affecting production?
Yes. Use gait policy test against fixture intents, or gait policy simulate to compare candidate vs baseline policy across fixtures before deploying.
What policy formats are supported?
Gait uses YAML policy files with structured rules. Use gait init for the additive repo-root onboarding path (.gait.yaml), or gait policy init --out ... when you want an explicit custom scaffold path such as gait.policy.yaml.
Can I set different rules per tool class?
Yes. Rules can match on tool name, tool class (read, write, delete, admin), endpoint patterns, risk class, and actor identity.
How do I roll out a policy change safely?
Start with observe mode (dry_run), then require_approval for high-risk actions, then enforce. Use gait policy simulate to see verdict deltas before each step.