Day 69: Policy as Code for Shell and Apply

Day 69: Policy as Code for Shell and Apply

Prompt text saying “be careful with prod” is not a control. Put OPA/Cedar (or similar) in front of every risky tool — shell, apply, terraform, IAM — so policy is code reviewed and testable.

⚡ TL;DR: Tools call authorize(input) before side effects. Policies live in git. Unit-test allow/deny.

Gate every risky tool

# policy/gate.py
import subprocess, json

def authorize(action: str, input_doc: dict) -> bool:
    p = subprocess.run(
        ["opa", "eval", "-f", "values", "-d", "policy/", "data.agent.allow",
         "-i", "/dev/stdin"],
        input=json.dumps({"action": action, **input_doc}).encode(),
        capture_output=True,
    )
    out = json.loads(p.stdout or "[]")
    return bool(out and out[0] is True)
# policy/shell.rego
package agent

default allow = false

allow {
  input.action == "run_shell"
  input.role == "implementer"
  startswith(input.cwd, "/workspace")
  not contains(input.cmd, "curl")
}
export async function runShell(role: string, cmd: string, cwd: string) {
  if (!authorize("run_shell", { role, cmd, cwd })) throw new Error("policy_deny");
  // proceed
}

❌ Soft-prompt “don’t run curl” while still exposing unrestricted shell.

Closing checklist

  • [ ] Policy-as-code in git
  • [ ] Authorize before side effects
  • [ ] Unit tests for allow/deny tables
  • [ ] Break-glass path with audit
  • [ ] Same gate for apply/terraform/IAM tools

Series navigation

Day 68: Abuse and Cost Attacks · Day 70: Project: Secure Coding-Agent Sandbox on ECS Fargate

Last updated September 11, 2026


Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply