9 minute read

Generative AI changed the interface to software.

For decades, we wrote deterministic programs that called APIs. Today, we increasingly delegate intent to models that decide which tools to call, in what order, with what parameters, based on natural language and evolving context.

That shift is subtle but profound: the “program” isn’t just your code anymore. It’s your prompt, your tool wiring, your memory, your retrieval layer, your agent runtime, and the model’s outputs—often across multiple steps.

This is why policy as code matters.

Not as a buzzword. As the pragmatic answer to a question every enterprise (and honestly, every serious builder) eventually hits:

“How do we give an agent real capabilities without turning the system into a liability?”

This post is a builder’s view of policy as code—why it’s becoming necessary, what it should control, and how audits + observability stop being optional once agents act in the real world. I’ll use examples from things I’ve been building and thinking about lately—Attach.dev (a gateway/runtime), OpenBotAuth (cryptographic agent identity), and OpenClaw (agent tooling + orchestration).


What “policy as code” actually means

Policy as code is the practice of expressing rules—permissions, constraints, approvals, safety boundaries, and compliance requirements—in a machine-executable form that is:

  • Versioned (like software)
  • Reviewable (PRs, approvals)
  • Testable (unit tests + simulation)
  • Deployable (enforced at runtime)
  • Observable (you can prove what happened)

In the classic enterprise world, we already have “policies,” but they’re scattered:

  • IAM rules
  • network firewalls
  • DLP systems
  • compliance checklists
  • SOC2 controls
  • manual approvals in ticketing systems

Agent systems make this fragmentation painful, because an agent can traverse layers in one “thought-to-action” hop. The policy can’t be tribal knowledge or a PDF. It has to be enforced where actions occur.


Why the web (and enterprises) need guardrails for GenAI

1) Agents are “non-deterministic integrations”

When you integrate Stripe or Slack, you know the exact calls you make. With agents, you’re integrating a planner that can generate new sequences of calls at runtime.

That’s not inherently bad—it’s why agents are powerful—but it means your security posture can’t rely on “we didn’t code it that way.”

2) Natural language is an attack surface

Prompt injection, malicious tool outputs, poisoned retrieval results, “helpful” but wrong conclusions, accidental data leakage—these are all variations of the same theme:

The model will try to comply with the most recent, most salient instruction unless constrained.

3) Enterprises don’t fear AI text; they fear AI actions

Summarizing an email is low risk.

Sending money, modifying production config, emailing external parties, exporting data, or signing requests—those are governance problems.

The moment agents can do, not just say, policy becomes core infrastructure.


The three pillars: Identity, Authorization, Accountability

If you remember only one framework, make it this:

A) Identity — “Who is acting?”

Humans have SSO and device posture. Agents need something comparable.

This is where cryptographic identity becomes useful: the agent signs its actions. You can verify which agent did the thing, independent of which platform it ran on.

This is the role OpenBotAuth plays in my stack: a portable identity for agents (keys the agent controls), so a request or action can be verified as coming from a specific agent identity, not just “some API key in a container.” For more on this, see Portable Identity for Agents.

B) Authorization — “What is allowed, under what conditions?”

Authorization for agents must be more specific than “can access Gmail.”

It should include constraints like:

  • allowed recipients/domains
  • data classification rules (PII, secrets)
  • time windows
  • rate limits and budgets
  • required approvals for high-risk actions
  • environment restrictions (prod vs staging)
  • “break-glass” rules for emergencies

C) Accountability — “Can we prove what happened?”

If an agent takes real actions, you need:

  • audit trails (immutable enough to trust)
  • structured logs for tool calls
  • traces across multi-step runs
  • policy evaluation logs (“why was this allowed/denied?”)
  • metrics to detect drift, abuse, and cost blowups

This is where observability stops being a DevOps luxury and becomes a governance requirement.


Where policies should live: the “agent gateway” pattern

A common mistake is trying to enforce policy only in prompts:

“Don’t do X. Always do Y. Never email outsiders.”

That’s wishful thinking. Prompts are guidance; policy must be enforcement.

The clean pattern is to place a policy enforcement point between the agent and the tools it can call.

This is how I think about Attach.dev conceptually: a gateway/runtime where tools are registered, calls are mediated, policies are evaluated, and logs are captured. The agent doesn’t “have Gmail.” It has a mediated capability to request “send email” and the gateway decides if it’s allowed.

Similarly, OpenClaw (as an orchestration client in my environment) becomes a natural place to enforce policy because it’s already sitting at the junction of:

  • user intent (Discord / CLI)
  • agent planning
  • tool execution (browser, code, APIs)
  • workflows (branch creation, PRs, etc.)

If you control the junction, you control the blast radius.


Example #1: “Send receipts to the accountant every month”

I’ve been thinking about making a workflow where receipts get posted (or pasted) and an agent emails them to an accountant on the 1st of every month—because humans procrastinate and automation wins.

That sounds harmless until you enumerate what could go wrong:

  • The agent emails the wrong person (typo, injection, ambiguous contact)
  • The agent includes unrelated sensitive docs from context
  • The agent forwards internal emails “for completeness”
  • Someone in the chat tricks the agent into sending other files
  • The agent starts “helpfully” summarizing sensitive financial info in the body

A policy-as-code approach turns this into a constrained capability:

Policy intent:

  • Only allow sending to a fixed allowlist (accountant@..., maybe one backup).
  • Only allow attachments that were explicitly provided in the last N minutes.
  • Disallow reading inbox contents unless explicitly approved.
  • Require a human “approve” click if amount > X or if recipients differ.
  • Always log: sender agent identity, recipients, attachment hashes, and a trace ID.

This transforms “agent has email” into “agent has this specific, auditable dispatch ability.”


Example #2: “Rebalancing rules” and preventing accidental trading

Another scenario I’ve been thinking about: rules like “if NVDA exceeds 10% of portfolio, trim back to 7%” or “if a position drops 15%, flag for review.” Whether the agent executes trades or merely alerts you is a huge governance boundary.

A strong policy posture here is: default to advisory, and make execution a separate, higher-trust path.

Policy intent (advisory mode):

  • Agent can read price feeds and your rules.
  • Agent can notify you with suggested actions.
  • Agent cannot place orders.

If execution is required:

  • Cap max order size
  • Enforce cooldowns
  • Require a second factor / explicit approval
  • Maintain a full audit trail and “reason for trade” metadata
  • Log exactly which data inputs were used to decide

This is a classic case where policy prevents the system from becoming a self-inflicted incident.


Example #3: Multi-user context and the KV-cache privacy problem

A deeper issue I’ve been exploring: multi-user chat with AI, shared context, and the risk that optimizations (like shared caches) could cause accidental leakage—e.g., the agent pulling private facts from one user context into a shared room.

That’s not a prompt problem. That’s an architecture + policy problem.

You need explicit policies for:

  • context boundaries (per-user vs shared)
  • what data types are eligible to enter shared context
  • redaction rules (PII, secrets)
  • retention windows
  • “no cross-user recall” constraints in shared threads

In practice, “policy as code” here often looks like:

  • data labeling (public/internal/secret)
  • enforcement in the gateway (Attach-style mediation)
  • structured memory APIs that require a classification label
  • logs that show when data moved between scopes

This is one of the most important guardrails topics for enterprise adoption—the difference between “useful assistant” and “compliance nightmare.”


Policies aren’t only for safety—they’re for steering outcomes

There’s a quieter benefit: policies don’t just prevent bad things; they produce better outcomes.

If you want agents to be consistently useful inside enterprises, they need:

  • clear operational boundaries
  • approved data sources
  • approved actions
  • predictable escalation paths (“ask a human when unsure”)
  • consistent formatting and metadata on outputs

Without policy, you’ll get:

  • random tool usage patterns
  • inconsistent decisions run-to-run
  • untraceable failures
  • confusion about “why did it do that?”

Policy is the system’s shape. It’s how you move from “cool demo” to “reliable coworker.”


Audits and observability: what you must record

If an agent can take real actions, you eventually need answers to questions like:

  • Who did this?
  • What tool calls were made?
  • With what inputs?
  • Under which policy version?
  • Was it allowed automatically or approved by a human?
  • What data sources influenced the decision?
  • What changed since last week (why are outputs worse now)?

A practical baseline:

For every run:

  • a run ID / trace ID
  • agent identity (signed if possible)
  • policy bundle version hash
  • tool calls (name, arguments, response metadata)
  • input sources (docs, URLs, connectors) + hashes
  • outputs + redaction status (what was removed)
  • timing, cost, token usage
  • allow/deny decisions + reason codes

If you can’t answer those questions, you can’t debug, secure, or govern the system.

And in regulated environments, you also can’t pass audits.


What policy as code looks like (concretely)

You can express policy in many ways. The important thing is that it’s executable and testable.

Here’s a deliberately simple, human-readable sketch:

policies:
  - id: "email_receipts_to_accountant"
    when:
      tool: "gmail.send"
    allow_if:
      to_in_allowlist: ["[email protected]", "[email protected]"]
      attachments:
        source: "explicit_user_upload"
        max_age_minutes: 30
        max_total_mb: 20
      body:
        must_not_contain: ["api_key", "seed phrase", "private key"]
    require_approval_if:
      subject_contains: ["invoice", "tax", "salary"]
    log:
      level: "full"
      include_attachment_hashes: true

Under the hood, you might implement this in OPA/Rego, Cedar, a custom rules engine, or a typed policy DSL. The mechanism matters less than the lifecycle: reviewable, testable, enforceable.


A practical checklist

If you’re building agentic infrastructure (or integrating agents into enterprise workflows), this is a good starting order:

  1. Enumerate tools the agent can call (email, browser, DB, deploy, payments).
  2. Define actors (human users, agents, services) and give them identities.
  3. Classify data (public/internal/secret) and enforce where it can flow.
  4. Decide enforcement points (gateway/proxy is the cleanest).
  5. Write minimal policies first: allowlists, budgets, rate limits, approvals.
  6. Add observability: traces, tool-call logs, policy decision logs.
  7. Test policies with simulation (good requests, bad requests, edge cases).
  8. Version + roll out safely (canary policies, staged enforcement).
  9. Add break-glass procedures for emergencies (with heavy logging).
  10. Continuously review based on incidents, drift, and real usage.

Closing thought

Agents are the first time we’ve tried to put a probabilistic planner in the driver’s seat of production systems.

That can be transformative—if we treat governance as part of the product, not an afterthought.

In practice, “policy as code” is the layer that makes it possible to say:

  • yes, the agent can act
  • yes, it’s constrained
  • yes, it’s auditable
  • yes, we can prove what happened
  • yes, we can improve it safely over time

Attach.dev, OpenBotAuth, and OpenClaw are concrete anchors for this idea in my own work: a mediated runtime, portable identity, and a practical orchestration surface. The bigger point is broader than any one project:

If GenAI is going to operate inside real systems, the web needs executable guardrails—policies that ship like code, and systems that can be audited like infrastructure.


Find me at @hammadtariq if you’re thinking about this space.