# How to Ship EU AI Act Compliance for AI Agents (Minimal Pack)

> A shippable, vendor-neutral evidence pack for AI agents: run logs, tool approvals, guardrail configs, retention/redaction, and an audit export you can produce in days.

- Canonical: https://www.kunalganglani.com/blog/eu-ai-act-compliance-ai-agents
- Author: Kunal Ganglani
- Published: 2026-10-01 · Updated: 2026-10-01
- Category: Cybersecurity · Tags: ai-governance, compliance, audit-logging, ai-agents, ai-security

## TL;DR

Shipping AI agents is easy. Getting them past security and legal is not. EU AI Act compliance comes down to being able to prove what happened in an agent run: who started it, what tools it called, what safeguards were active, and who approved risky actions. The fastest approach is a minimal “evidence pack” you can generate automatically: a run trace log, a tool-approval record, a control register that maps risks to guardrails, and an audit export packet. Build it once, and every agent workflow gets easier to ship and defend in an audit.

If you want **EU AI Act compliance for AI agents**, the fastest path is not a 60-page policy doc. It’s an evidence pack your runtime can spit out for every single agent run.

The prerequisite that keeps tripping teams up is identity. If you can’t answer “**which human (or service) initiated this run**?” and “**who approved each high‑impact tool call**?”, then the rest of your logs are basically trivia.

This post is my vendor-neutral, minimum-viable evidence pack. It’s for teams shipping agentic workflows across mixed stacks (OpenAI/Anthropic/Bedrock, SaaS tools, internal APIs) who keep getting blocked by security and legal for the same reason. You can’t prove what happened.

I learned this the hard way running this blog’s multi-agent publishing pipeline. After an incident where **rewriting slugs burned 907K impressions of link equity**, I stopped trusting “we’ll remember what happened” stories. Deterministic evidence or it didn’t happen.

## What is EU AI Act compliance for AI agents?

**EU AI Act compliance for AI agents is the practice of designing, operating, and documenting agentic AI systems so you can demonstrate the EU Artificial Intelligence Act’s required controls (risk management, logging, oversight, security, transparency) with auditable evidence.** In practice, that means your agent runtime produces traceable logs, approval records, and control configurations that match your system’s risk tier.

![black and gray code padlock anchored on chain-link fence selective focus photo](https://cdn.sanity.io/images/vzekdneq/production/09a54c9b20d53039be322e5722fa578fe862bc73-1200x675.webp)

## What is the EU AI Act?

The **EU Artificial Intelligence Act (Regulation (EU) 2024/1689)** is the European Union’s risk-based law governing how AI systems are built and used.

![A computer screen with the words back the web on it](https://cdn.sanity.io/images/vzekdneq/production/246303128ca639fb48d401a312b84dd9a8b67b5a-1200x675.webp)

The only framing that matters for engineers is this: the Act is not asking you to “be ethical”. It’s asking you to **operate like you’ll be audited**.

A clean primary-source entry point is the official text index at [artificialintelligenceact.eu](https://artificialintelligenceact.eu/the-act/), which links to the Official Journal / EUR-Lex versions.

The practical implication for AI agents is pretty obvious. Agents aren’t a single model call. They’re a *workflow engine* that:

- pulls data from retrieval sources
- routes across models
- calls tools with side effects
- makes policy decisions
- sometimes asks for human sign-off
That’s the exact shape of system regulators and auditors hate. Lots of moving parts. Fuzzy boundaries. Endless room for “that wasn’t us”.

## Who does the EU AI Act apply to?

The Act applies across the AI value chain. If you ship agents, assume you’re one or more of:

![An open padlock surrounded by scattered black computer keyboard keys under red and green light](https://cdn.sanity.io/images/vzekdneq/production/36a9b7592300095aa1822626d260acbf3d7bfbc7-1200x675.webp)

- **Provider**: you develop the AI system (or agent platform) and place it on the market.
- **Deployer**: you use an AI system in your org to run a business process.
- **Importer / distributor / product manufacturer**: if you bundle it into something else.
IBM’s explainer is useful because it lays out the operator types and why “we just integrated a model” is not a get-out-of-jail-free card. See [Matt Kosinski](https://www.ibm.com/topics/eu-ai-act) and coauthors.

For agents, the boundary mess gets worse once you add tools. You might be a “deployer” of an agent that calls third-party SaaS. But you’re also effectively the “provider” of a *system* that makes decisions and executes actions.

My rule is simple: if your agent can change state in a customer’s environment (send email, modify records, approve refunds, deploy code), act like you’ll be treated as an operator with real obligations.

## What requirements does the EU AI Act impose?

This depends on risk tier (more on that below), but the themes repeat:

- **Risk management**: show you identified and mitigated risks.
- **Data governance**: show you control training/eval/operational data flows.
- **Technical documentation**: show you can describe the system.
- **Record-keeping / logging**: show you can reconstruct what happened.
- **Transparency**: show users understand they’re interacting with AI where required.
- **Human oversight**: show humans can intervene meaningfully.
- **Accuracy, robustness, cybersecurity**: show you designed for failure and for attack.
If you want a sane structure to hang evidence on, I like NIST’s AI RMF because it’s boring and operational. The four functions are **Govern, Map, Measure, Manage**, and they translate cleanly into “who owns this”, “what is it”, “how did you test it”, “what controls are running”. See the official [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework).

### Prohibited AI practices

You’re not going to solve prohibited practices with logging. If your use case is prohibited, stop.

What I see more often with agent teams is accidental drift into “this feels like surveillance/manipulation” because the workflow got too powerful and nobody drew a line.

Concrete engineering takeaway: **log intent and capability**. An agent that can quietly scrape, infer, and act is a completely different risk profile than one that only drafts.

### Standards for high-risk AI

High-risk is where the “minimal evidence pack” pays for itself.

High-risk systems need stronger requirements around record-keeping, human oversight, and robustness.

Even if you’re not high-risk today, you want the same primitives. Otherwise the next PM request is “can the agent auto-approve X?” and you’ll be rebuilding your runtime while legal is breathing down your neck.

### Rules for general purpose AI (GPAI) models

GPAI obligations often land on the model providers. Fine. But deployers and system builders still own how models are used.

In an agent world, “GPAI” shows up as **model routing**. Different prompts go to different vendors, sometimes inside the same run.

So your evidence pack has to capture **model provenance per span**: provider, model name, version/snapshot, region, and configuration.

### EU AI Act fines

IBM summarizes the penalty ranges as:

- **€35 million or 7%** of worldwide annual turnover (upper tier)
- down to **€7.5 million or 1%** (lower tier)
That’s not “compliance theatre” money. That’s existential.

### When does the EU AI Act take effect?

The AI Act was published in the Official Journal on **12 July 2024** per the official text index at [artificialintelligenceact.eu](https://artificialintelligenceact.eu/the-act/).

Different obligations phase in on different timelines. The point for builders in 2026 is simpler: audits and procurement questionnaires are already here. If you sell into Europe, you’re already being asked to prove governance.

## Why agent governance is a different problem

Most compliance programs were built for deterministic software. Agents are not deterministic, and they come with a tool belt.

Three things change the game:

1. **The unit of work is a run, not a request.** One “task” can contain 20+ model/tool/retrieval spans.
1. **The most important events are decisions.** “Why did it call that tool?” matters more than “what did the model say?”.
1. **Your system boundary moves.** The agent’s “brain” might be vendor A, retrieval vendor B, tools vendor C, plus your internal APIs.
This is why I keep pushing teams to invest in [agent orchestration](/pillars/ai-agents) primitives early. If you don’t have run IDs, span IDs, and control points, you don’t have a product. You have a demo.

If you’re thinking about tool protocols, also read my take on [agent framework](/blog/mcp-vs-function-calling-agents) tradeoffs. Tooling choices decide what you can log and what you can control later.

## The evidence a regulator asks for (your minimal pack)

You don’t need a full GRC platform to answer an audit. You need **four artifacts** you can generate on demand.

### 1) Run trace (JSON)

One JSON document per run, with a stable `run_id` and a tree of spans.

Minimal fields that I’ve seen unblock security reviews:

- identifiers: `run_id`, `trace_id`, `tenant_id`, `environment`
- initiator: `actor_type` (human/service), `actor_id`, `auth_context`
- model provenance: `provider`, `model`, `version`, `region`
- prompts/outputs: **redacted or hashed** (more below)
- tool calls: name, parameters (redacted), result metadata, side-effect classification
- retrieval: source IDs/URIs, doc hashes, chunk IDs, top-k
- policy decisions: which policy evaluated, allow/deny, reason codes
- human oversight: approvals, overrides, aborts, “break-glass” usage
If you already use OpenTelemetry, this maps cleanly to the “trace + span attributes” mental model. I’ve written about building this in [execution trace trees for AI agents](/blog/execution-trace-tree-agents) and a concrete [AI agents observability logging schema](/blog/ai-agent-observability-logging-schema).

Here’s a copy-pastable minimal schema you can implement in any stack:

```json
{
  "run_id": "run_01J9...",
  "started_at": "2026-10-01T13:03:11.231Z",
  "ended_at": "2026-10-01T13:03:44.902Z",
  "environment": "prod",
  "tenant_id": "acme-co",
  "initiator": {
    "actor_type": "human",
    "actor_id": "user_18372",
    "session_id": "sess_...",
    "ip": "203.0.113.10",
    "step_up": false
  },
  "agent": {
    "name": "refund-agent",
    "version": "git:9b3b0b2",
    "policy_bundle_version": "policy:2026-09-28.1"
  },
  "model_routing": [
    {
      "span_id": "s1",
      "provider": "anthropic",
      "model": "claude-sonnet-4.6",
      "region": "eu-west-1",
      "temperature": 0.2
    }
  ],
  "spans": [
    {
      "span_id": "s1",
      "parent_span_id": null,
      "type": "llm",
      "name": "plan",
      "input": {
        "prompt_hash": "sha256:...",
        "redaction_applied": true,
        "token_count": 1840
      },
      "output": {
        "response_hash": "sha256:...",
        "token_count": 410
      },
      "policy": {
        "decision": "allow",
        "policies_evaluated": ["pii_redaction_v2", "tool_scope_v4"],
        "reason_codes": ["OK"]
      },
      "timing_ms": 612
    },
    {
      "span_id": "s2",
      "parent_span_id": "s1",
      "type": "tool_call",
      "tool": "payments.refund.create",
      "impact": "high",
      "request": {
        "params_hash": "sha256:...",
        "redaction_applied": true
      },
      "approval": {
        "required": true,
        "approval_id": "appr_01J9...",
        "status": "approved"
      },
      "result": {
        "status": "success",
        "http_status": 201
      },
      "timing_ms": 241
    }
  ],
  "links": {
    "incident_ticket": "JIRA-1234",
    "change_request": "CRQ-99213"
  }
}
```

Concrete numbers that actually matter:

- keep `timing_ms` at span level so you can answer “what was the system doing for 33,671 ms?” without hand-waving
- record token counts per call. Token spikes correlate with data leakage *and* cost incidents.
### 2) Tool approval record (JSON)

Tool approvals are the difference between “we had human oversight” and “we had a Slack message.”

Your approval record has to be standalone. An auditor should be able to read it without loading your tracing UI, your data warehouse, and your internal wiki.

```json
{
  "approval_id": "appr_01J9...",
  "run_id": "run_01J9...",
  "span_id": "s2",
  "requested_at": "2026-10-01T13:03:29.002Z",
  "requested_by": {
    "actor_type": "agent",
    "agent_name": "refund-agent",
    "agent_version": "git:9b3b0b2"
  },
  "action": {
    "tool": "payments.refund.create",
    "impact": "high",
    "amount_cents": 4999,
    "currency": "USD",
    "dry_run": false
  },
  "policy_basis": {
    "policy_id": "dual_control_refunds_v1",
    "reason": "amount_over_threshold",
    "threshold_cents": 2000
  },
  "approvals": [
    {
      "approved_by": "user_991",
      "approved_at": "2026-10-01T13:03:34.114Z",
      "auth": {
        "step_up": true,
        "method": "webauthn"
      }
    }
  ],
  "final_status": "approved"
}
```

Numbers you should make painfully explicit:

- thresholds (`threshold_cents: 2000`)
- auth method (`webauthn`) and whether step-up happened (`step_up: true`)
If you want more patterns here, I’ve collected approval flows in [tool approval patterns for AI agents](/blog/tool-approval-patterns-ai-agents) and the control-flow implications in [AI agent control flow patterns](/blog/ai-agent-control-flow-patterns).

### 3) Control register (YAML)

This is the bridge between legal language and runtime behavior.

It should map: **risk → control → where enforced → evidence produced**.

```yaml
system: refund-agent
system_version: git:9b3b0b2
last_reviewed: 2026-09-28
owner: security@acme.co
risks:
  - id: R1
    name: Prompt injection causing unauthorized tool use
    controls:
      - id: C1
        name: Tool allowlist + parameter schema validation
        enforcement: runtime
        evidence:
          - trace.span.policy.policies_evaluated
          - trace.span.tool_call.tool
      - id: C2
        name: JIT approval for high-impact tool calls
        enforcement: runtime
        evidence:
          - approval_record.final_status
          - approval_record.approvals[].auth.step_up
  - id: R2
    name: PII leakage via prompts/tool I/O
    controls:
      - id: C3
        name: Field-level redaction before logging
        enforcement: runtime
        evidence:
          - trace.spans[].input.redaction_applied
          - trace.spans[].request.redaction_applied
  - id: R3
    name: Lateral movement via over-privileged tool tokens
    controls:
      - id: C4
        name: Least privilege OAuth scopes per tool
        enforcement: IAM
        evidence:
          - iam.policy_id
          - tool_token.scope
```

This YAML becomes your audit map. It’s also how you keep the system honest when someone adds a new tool on Friday afternoon.

If you’re already doing policy-as-code, great. If you’re not, this register is still worth it because it forces precision.

### 4) Audit packet checklist (what you export)

When an auditor asks “show me one incident end-to-end”, you should be able to produce a zip.

My minimum audit packet for an agent run:

1. `run_trace.json`
1. `approval_*.json` (all approvals referenced by spans)
1. `control_register.yaml` (the version active at run time)
1. `policy_bundle/` (compiled rules that actually executed)
1. links to: incident ticket, change request, IAM policy versions
If this sounds like overkill, remember what the alternative looks like. Two weeks of scrambling every time procurement asks for “evidence of controls”.

As a concrete example of “exportable evidence”, an AWS Community Builders walkthrough shows runtime governance beats like **hard-blocking prompt injection**, **PII redaction across sub-agents**, and **stamping/exporting audit evidence** as engineered artifacts, not policy PDFs. That post is on dev.to so I’m not linking it here, but the point stands. Evidence generation is a product feature.

## Real-time enforcement vs scheduled detection

This is where teams lie to themselves.

- **Scheduled detection** is dashboards, SIEM queries, daily scans.
- **Real-time enforcement** is “the agent literally cannot do the thing”.
For EU AI Act compliance, scheduled detection helps you learn. It does not stop harm.

In agent systems, the controls that matter need to be runtime:

- tool allowlists and schemas
- scope/permission checks
- egress controls
- spend limits
- approval gates
- kill switches
Everything else can be detective.

If you want a control that ships fast, implement hard ceilings on tool execution and cost. I’ve written a full playbook on [AI agent kill switch spend limits](/blog/ai-agent-kill-switch-spend-limits) and how to keep it auditable.

A number that matters operationally: if your agent can take **10 tool actions per run**, then “scheduled detection every 24 hours” means you’re comfortable with **thousands of bad actions** before anyone notices. That’s not governance. That’s hope.

## What exactly should you log for an AI agent run (without storing sensitive data)?

Logging is where compliance and security teams fight. Security wants full forensics. Privacy wants minimization. Engineers want to ship.

My compromise is: **log metadata by default, log sensitive content only behind break-glass, and hash everything so you can correlate without hoarding.**

### The minimal logging checklist (8 items)

Use this as your copy/paste implementation checklist for **AI agent audit logging EU AI Act** readiness:

1. Stable `run_id` and `trace_id` for every run.
1. Initiator identity (`actor_id`, `session_id`) and auth context.
1. Model provenance per LLM span (provider, model, version, region).
1. Prompt/response hashes plus token counts, not raw text.
1. Tool call name, impact rating (low/medium/high), and redacted parameter hashes.
1. Retrieval sources (document IDs/URIs) plus content hashes and top-k.
1. Policy decisions (allow/deny) with reason codes.
1. Human oversight events (approval requested, approved/denied, override, abort) with approver identity.
That’s enough to answer what happened, why it happened, and who allowed it.

If you need a deeper redaction strategy, I’ve gone into it in [LLM data leakage playbook](/blog/llm-data-leakage-playbook) and [field-level redaction for RAG pipelines](/blog/field-level-redaction-rag).

## How do you design a tool-approval workflow for agents and keep an auditable trail?

Tool approvals fail when they’re bolted on.

The approval workflow has to be part of your [AI agents](/pillars/ai-agents) control flow. The agent should be able to pause, request approval, resume, or abort deterministically.

Here’s what works in practice:

- **Pre-approval** for repeatable low-risk actions (read-only tools, drafting).
- **Just-in-time approval** for high-impact actions (payments, deletes, privilege changes).
- **Step-up authentication** when approving high-impact actions (WebAuthn, re-auth within 5 minutes).
- **Dual control** above a threshold (two distinct humans).
- **Break-glass** for incident response, with automatic paging and post-incident review.
Concrete numbers I recommend starting with:

- step-up required if approval is for an action with `impact=high` or if the params include a “write” scope
- dual control required above **$20** for refunds or any “delete” tool action
- break-glass token TTL **15 minutes** and scoped to one tool
Most teams already have the pieces in IAM and ticketing. Don’t build a new UI unless you have to. You just need the record.

If you’re using MCP-style tool protocols, security gets even more interesting. See my [MCP OAuth security](/blog/mcp-oauth-security-impersonation) write-up for how tool impersonation and token replay show up in audits.

## Retention, redaction, and DSAR: how long should agent logs live?

Retention is a policy choice. But if it’s not explicit and enforced, you don’t have a policy. You have vibes.

My opinionated baseline:

- **Run metadata** (IDs, timing, tool names, policy decisions): retain **180 days**.
- **Approval records** (who approved what): retain **2 years**.
- **Raw prompt/tool I/O**: retain **0 days by default**. Store only with break-glass and a defined reason.
Redaction strategy that won’t collapse the first time there’s an incident:

- redact PII/secrets *before* writing to logs
- store a `prompt_hash` / `params_hash` so you can correlate incidents
- keep a separate encrypted “forensics vault” with strict access control for the rare cases where you must store raw content
Also design for deletion requests:

- if you log raw content, you now owe a deletion workflow
- if you only log hashes + metadata, DSAR gets dramatically simpler
I’m blunt about this because I’ve watched teams dump raw prompts into systems that were never meant to hold sensitive data. They end up with “compliance debt” that’s worse than tech debt.

## Human oversight: how to prove it’s effective

Saying “a human can override” is meaningless if nobody ever does.

To prove oversight is real, you need metrics and events:

- count of approval requests per 1,000 runs
- median approval latency (e.g., **42 seconds**)
- override rate (humans disagreeing with the agent)
- abort rate (human stops the run)
- “safe mode” activations (agent drops to read-only)
Log these as events and push them to your existing monitoring stack. This is where compliance starts paying rent.

If you want a practical test harness to validate these flows, steal from chaos engineering. I like injecting forced approval prompts and tool failures in CI. I’ve written about this in [agent tool call failure testing](/blog/agent-tool-call-failure-testing).

## Cybersecurity and robustness controls you can actually evidence

This is the part many teams miss. AI compliance isn’t separate from security. It’s security with an LLM-shaped attack surface.

ENISA has been explicit that securing ML systems involves secure design, monitoring, and threat mitigation. See the EU agency publication [ENISA](https://www.enisa.europa.eu/publications/securing-machine-learning-algorithms).

For agents, the minimum set I’d ship:

- prompt injection defenses, including indirect injection. Start with [prompt injection](/blog/prompt-injection-2026-owasp-llm-vulnerability) and build regression tests (yes, tests) via [prompt injection regression testing](/blog/prompt-injection-regression-testing-ci).
- tool sandboxing and egress control, especially for “computer use” style agents. See [secure local LLM inference](/blog/secure-local-llm-inference) for the same design patterns.
- least-privilege tokens per tool (scopes per agent role)
- allowlists for outbound domains and internal APIs
- monitoring for unusual tool-call patterns (spikes, new tools, repeated failures)
Evidence you can attach without drama:

- policy bundle version used at run time
- test results for prompt injection regression suite (date-stamped)
- IAM policy versions / scope grants
- alerts fired + incident ticket links
If you need an agent-specific threat model, I’ve covered the core attack surfaces in [agent attack surfaces security](/blog/agent-attack-surfaces-security).

## Third-party models and tools: what evidence to keep vs request

If you use third-party models/tools, don’t pretend you can log what you don’t control.

Split evidence into three buckets:

1. **You must collect** (always): your run trace, approvals, policies, IAM decisions.
1. **You should request from vendors**: model versioning, region/data residency, retention terms, security attestations.
1. **You can’t get** (and should design around): vendor-internal reasoning, raw training data lineage.
Two practical moves that ship fast:

- treat every vendor call as a span with `provider`, `model`, and `request_id`
- record vendor response headers / request IDs so you can correlate with vendor support later
Also assume multi-vendor routing. Your evidence pack should not break if an agent calls **2 providers in one run**.

If you’re cost-sensitive, you can route some workloads to a [local LLM](/pillars/llm-hardware-local-ai). Just don’t do it purely for cost. Do it when you want tighter control over data and logs.

## Honest caveats

A “minimal evidence pack” is not magic.

- If your org has no appetite for runtime enforcement, you’ll end up with beautiful logs of bad behavior instead of prevention.
- If you ship agents into a truly high-risk domain, you’ll need deeper documentation and assurance work.
- If your agent does autonomous actions without approvals, your evidence pack will show that clearly. Which is the point.
Also, don’t use compliance as an excuse to log everything. You’ll build a privacy incident factory.

## The challenge

Pick one existing agent workflow this week and force it through the audit story:

- show one run end-to-end
- show the approvals
- show which controls were active
- show how you would export it as a packet
If you can’t do that in **48 hours**, your agent isn’t production-ready. It’s just running in production.

Photo by Olena Kholina on Unsplash.
