Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions examples/policy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ These templates provide baseline policy packs by risk tier:
- `base_high_risk.yaml`
- `baseline-highrisk.yaml` (hyphenated alias)
- `knowledge_worker_safe.yaml` (reversible-first profile)
- `ci_cd_pipeline.yaml` (CI/CD agent guardrails)

Scaffold a baseline file directly from the CLI:

Expand Down Expand Up @@ -39,6 +40,12 @@ gait policy test examples/policy/base_high_risk.yaml examples/policy/intents/int
gait policy test examples/policy/base_high_risk.yaml examples/policy/intents/intent_tainted_egress.json --json
gait policy test examples/policy/base_high_risk.yaml examples/policy/intents/intent_delegated_egress_valid.json --json
gait policy test examples/policy/base_high_risk.yaml examples/policy/intents/intent_delegated_egress_invalid.json --json

gait policy test examples/policy/ci_cd_pipeline.yaml examples/policy/intents/intent_ci_read_artifact.json --json
gait policy test examples/policy/ci_cd_pipeline.yaml examples/policy/intents/intent_ci_deploy_staging.json --json
gait policy test examples/policy/ci_cd_pipeline.yaml examples/policy/intents/intent_ci_deploy_production.json --json
gait policy test examples/policy/ci_cd_pipeline.yaml examples/policy/intents/intent_ci_secret_access.json --json
gait policy test examples/policy/ci_cd_pipeline.yaml examples/policy/intents/intent_ci_infra_destroy.json --json
```

Expected verdict matrix:
Expand All @@ -49,13 +56,19 @@ Expected verdict matrix:
- `intent_tainted_egress.json` => `block` (exit `3`)
- `intent_delegated_egress_valid.json` => `allow` (exit `0`)
- `intent_delegated_egress_invalid.json` => `block` (exit `3`)
- `intent_ci_read_artifact.json` => `allow` (exit `0`)
- `intent_ci_deploy_staging.json` => `allow` (exit `0`)
- `intent_ci_deploy_production.json` => `block` (exit `3`)
- `intent_ci_secret_access.json` => `require_approval` (exit `4`)
- `intent_ci_infra_destroy.json` => `block` (exit `3`)

High-risk note:

- `base_high_risk.yaml` marks write actions with `require_broker_credential: true` for least-privilege brokering.
- `base_high_risk.yaml` requires explicit delegation metadata for high-risk egress writes and blocks tainted external payload flow to network destinations.
- `base_high_risk.yaml` and `baseline-highrisk.yaml` include `destructive_budget` defaults to fail-closed once destructive threshold windows are exceeded.
- `knowledge_worker_safe.yaml` defaults unknown tools to block, prefers archive/trash actions, and requires explicit break-glass approval for permanent delete paths.
- `ci_cd_pipeline.yaml` governs AI agents operating inside CI/CD pipelines: allows artifact reads and staging deploys, blocks production deploys and infrastructure destruction, requires approval for secret access and infrastructure provisioning.
- For runtime checks in hardened mode, evaluate with `--profile oss-prod` and an explicit broker, for example:

```bash
Expand Down
63 changes: 63 additions & 0 deletions examples/policy/ci_cd_pipeline.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
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]
rules:
- name: allow-read-build-artifacts
priority: 10
effect: allow
match:
tool_names: [artifact.read, artifact.download, artifact.list, tool.read]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Narrow read allowlist to artifact-specific tools

Including tool.read in the artifact-read rule allows any generic read call at low/medium risk, not just artifact access. In adapters that surface secret or vault retrieval as tool.read, those requests bypass the require-approval-secret-access rule and are approved as allow, which weakens the template’s stated secret-access guardrail. Restrict this rule to artifact-specific tool names (or add strict target/path constraints) so non-artifact reads do not auto-pass.

Useful? React with 👍 / 👎.

risk_classes: [low, medium]
reason_codes: [safe_artifact_read]

- name: allow-staging-deploy
priority: 15
effect: allow
match:
tool_names: [deploy.apply, deploy.push]
risk_classes: [medium]
workspace_prefixes: [/ci/staging, /deploy/staging]
Comment on lines +21 to +23
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Constrain staging deploys by destination scope

The staging deploy allow rule only checks tool name, risk class, and workspace prefix, so a request can still target production infrastructure while presenting workspace as /ci/staging and risk_class as medium, and it will be allowed. Because this rule does not validate destination/target scope, it can authorize production deploy behavior under a staging label; add destination constraints (allowlist/denylist) to enforce true staging-only deploys.

Useful? React with 👍 / 👎.

reason_codes: [staging_deploy_allowed]

- name: block-production-deploy
priority: 20
effect: block
match:
tool_names: [deploy.apply, deploy.push]
risk_classes: [critical]
workspace_prefixes: [/ci/production, /deploy/production]
reason_codes: [production_deploy_blocked_in_ci]
violations: [unauthorized_production_deploy]

- name: require-approval-secret-access
priority: 25
effect: require_approval
min_approvals: 1
match:
tool_names: [secret.read, vault.read, secret.rotate]
risk_classes: [high, critical]
reason_codes: [approval_required_for_secret_access]
violations: [secret_access_requires_approval]

- name: block-infrastructure-mutation
priority: 30
effect: block
match:
tool_names: [infra.destroy, infra.delete, db.drop, db.truncate]
reason_codes: [infrastructure_mutation_blocked]
violations: [destructive_infrastructure_operation]

- name: require-approval-infra-create
priority: 35
effect: require_approval
min_approvals: 2
require_distinct_approvers: true
match:
tool_names: [infra.create, infra.update]
risk_classes: [high, critical]
reason_codes: [approval_required_for_infrastructure_change]
violations: [infrastructure_change_requires_review]
32 changes: 32 additions & 0 deletions examples/policy/intents/intent_ci_deploy_production.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"schema_id": "gait.gate.intent_request",
"schema_version": "1.0.0",
"created_at": "2026-03-23T00:00:00Z",
"producer_version": "0.0.0-example",
"tool_name": "deploy.apply",
"args": {
"environment": "production",
"image": "app:sha-abc123"
},
"targets": [
{
"kind": "host",
"value": "api.production.example",
"operation": "write",
"endpoint_class": "net.http",
"endpoint_domain": "api.production.example"
}
],
"arg_provenance": [
{
"arg_path": "$.image",
"source": "system",
"source_ref": "ci:build_output"
}
],
"context": {
"identity": "ci-agent",
"workspace": "/ci/production",
"risk_class": "critical"
}
}
32 changes: 32 additions & 0 deletions examples/policy/intents/intent_ci_deploy_staging.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"schema_id": "gait.gate.intent_request",
"schema_version": "1.0.0",
"created_at": "2026-03-23T00:00:00Z",
"producer_version": "0.0.0-example",
"tool_name": "deploy.apply",
"args": {
"environment": "staging",
"image": "app:sha-abc123"
},
"targets": [
{
"kind": "host",
"value": "staging.internal.example",
"operation": "write",
"endpoint_class": "net.http",
"endpoint_domain": "staging.internal.example"
}
],
"arg_provenance": [
{
"arg_path": "$.image",
"source": "system",
"source_ref": "ci:build_output"
}
],
"context": {
"identity": "ci-agent",
"workspace": "/ci/staging",
"risk_class": "medium"
}
}
30 changes: 30 additions & 0 deletions examples/policy/intents/intent_ci_infra_destroy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"schema_id": "gait.gate.intent_request",
"schema_version": "1.0.0",
"created_at": "2026-03-23T00:00:00Z",
"producer_version": "0.0.0-example",
"tool_name": "infra.destroy",
"args": {
"resource": "rds-cluster-prod",
"region": "us-east-1"
},
"targets": [
{
"kind": "other",
"value": "rds-cluster-prod",
"operation": "delete",
"destructive": true
}
],
"arg_provenance": [
{
"arg_path": "$.resource",
"source": "user"
}
],
"context": {
"identity": "ci-agent",
"workspace": "/ci/workspace",
"risk_class": "high"
}
}
29 changes: 29 additions & 0 deletions examples/policy/intents/intent_ci_read_artifact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"schema_id": "gait.gate.intent_request",
"schema_version": "1.0.0",
"created_at": "2026-03-23T00:00:00Z",
"producer_version": "0.0.0-example",
"tool_name": "artifact.read",
"args": {
"artifact_id": "build-output-abc123",
"path": "/ci/artifacts/build.tar.gz"
},
"targets": [
{
"kind": "path",
"value": "/ci/artifacts/build.tar.gz",
"operation": "read"
}
],
"arg_provenance": [
{
"arg_path": "$.artifact_id",
"source": "system"
}
],
"context": {
"identity": "ci-agent",
"workspace": "/ci/workspace",
"risk_class": "low"
}
}
30 changes: 30 additions & 0 deletions examples/policy/intents/intent_ci_secret_access.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"schema_id": "gait.gate.intent_request",
"schema_version": "1.0.0",
"created_at": "2026-03-23T00:00:00Z",
"producer_version": "0.0.0-example",
"tool_name": "secret.read",
"args": {
"secret_name": "DATABASE_URL",
"vault_path": "ci/production/database"
},
"targets": [
{
"kind": "other",
"value": "vault://ci/production/database",
"operation": "read"
}
],
"arg_provenance": [
{
"arg_path": "$.secret_name",
"source": "system",
"source_ref": "ci:env_config"
}
],
"context": {
"identity": "ci-agent",
"workspace": "/ci/workspace",
"risk_class": "high"
}
}
6 changes: 6 additions & 0 deletions scripts/policy_compliance_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,15 @@ run_case "template-high-delete" "examples/policy/base_high_risk.yaml" "examples/
run_case "template-high-tainted-egress" "examples/policy/base_high_risk.yaml" "examples/policy/intents/intent_tainted_egress.json" 3
run_case "template-high-delegated-egress-valid" "examples/policy/base_high_risk.yaml" "examples/policy/intents/intent_delegated_egress_valid.json" 0
run_case "template-high-delegated-egress-invalid" "examples/policy/base_high_risk.yaml" "examples/policy/intents/intent_delegated_egress_invalid.json" 3
run_case "ci-cd-read-artifact" "examples/policy/ci_cd_pipeline.yaml" "examples/policy/intents/intent_ci_read_artifact.json" 0
run_case "ci-cd-deploy-staging" "examples/policy/ci_cd_pipeline.yaml" "examples/policy/intents/intent_ci_deploy_staging.json" 0
run_case "ci-cd-deploy-production" "examples/policy/ci_cd_pipeline.yaml" "examples/policy/intents/intent_ci_deploy_production.json" 3
run_case "ci-cd-secret-access" "examples/policy/ci_cd_pipeline.yaml" "examples/policy/intents/intent_ci_secret_access.json" 4
run_case "ci-cd-infra-destroy" "examples/policy/ci_cd_pipeline.yaml" "examples/policy/intents/intent_ci_infra_destroy.json" 3
run_validate_case "validate-template-low" "examples/policy/base_low_risk.yaml" 0
run_validate_case "validate-template-medium" "examples/policy/base_medium_risk.yaml" 0
run_validate_case "validate-template-high" "examples/policy/base_high_risk.yaml" 0
run_validate_case "validate-ci-cd-pipeline" "examples/policy/ci_cd_pipeline.yaml" 0

invalid_policy_path="gait-out/policy_invalid.yaml"
cat >"$invalid_policy_path" <<'EOF'
Expand Down