AI Agent Identity and Access Management: Scoping Keys, Roles, and Approvals So One Agent Can't Break Production
Your agent works in the demo and breaks in production because every agent shares one credential. This walks through per-agent keys, scope boundaries, role design, and the approval gate that stops an unapproved send before it leaves.
AI agent identity and access management requires isolating bearer credentials per agent, locking scopes to specific endpoints, and placing human approval gates before irreversible operations execute. Giving every autonomous agent an identical, broad workspace API key guarantees that when an LLM hallucinates an outbound email or clobbers a shared calendar, you cannot isolate the blast radius, revoke the offending worker, or identify the actor in your audit trail.
When autonomous systems move from local evaluation harnesses into production runtimes—orchestrated via frameworks like LangChain, CrewAI, AutoGen, or the Model Context Protocol (MCP)—traditional service accounts fail. Robust agent permissions and secure agent authentication demand an architecture that treats autonomous agents as distinct non-human actors. This guide details how to scope keys, define least-privilege roles, implement signed webhooks, and place human review gates so a single misbehaving agent cannot break production.
The failure is almost never the model. It is the credential.
When an agent sends an unvetted email containing contractual promises to a customer or double-books an executive's calendar across competing clients, developers tend to debug the system prompt. They add defensive prompt engineering, write few-shot examples, or adjust temperature settings. Yet the fundamental failure mode is architectural: an autonomous entity had the network access, API authorization, and unconstrained credential required to execute an irreversible write without programmatic resistance.
In most production incidents involving autonomous tools, the post-mortem reveals a shared workspace API token. When five agents running on background workers all present the same authorization header, the destination API treats every transaction as the workspace owner. The downstream database records that the workspace initiated a booking or dispatched a message, leaving the identity of the specific autonomous agent entirely blank.
Treating non-human actors as first-class identities requires separating three distinct operational concerns:
- Authentication: Proving the distinct identity of the executing worker via distinct non-human credentials rather than a shared static secret.
- Authorization: Restricting the actions that credential can execute using strictly enforced endpoint scopes rather than role descriptions passed in system prompts.
- Auditability: Recording tamper-evident evidence showing exactly which key, scope, and request payload produced every state change.
Managing agent roles requires ditching shared tokens. In the sections below, we walk through constructing a production-grade identity architecture: provisioning per-agent bearer tokens prefixed avs_live_, enforcing endpoint-level scopes, and inserting deterministic approval gates before consequential writes touch external systems.
Give every agent its own credential, not a shared workspace key
Using a single API key across multiple agents creates an all-or-nothing security perimeter. If an agent analyzing incoming correspondence enters an execution loop and begins issuing aberrant writes, an engineer cannot revoke that single agent without taking down the scheduling, extraction, and reporting pipelines sharing the credential. Rotating a single shared token requires coordinated deployment across all services, inevitably delaying incident mitigation.
As documented in the NHIMG bearer authentication header guide, bearer tokens are transmitted directly within the Authorization request header and carry no intrinsic cryptographic proof of possession. Anyone holding the token exercises its full authority. Consequently, if an agent leaks a bearer token into application logs, third-party LLM context windows, or distributed trace spans, an adversary or misconfigured worker possesses direct access to every service authorized by that key.
AgentDraft agents authenticate with bearer API keys prefixed avs_live_, stored argon2id-hashed. Hashing stored keys with a memory-hard function ensures that a compromised database dump does not yield usable credentials. Per the IETF RFC 9106 specifications for Argon2 and the OWASP Password Storage Cheat Sheet, Argon2id provides state-of-the-art resistance against both GPU-accelerated cracking and side-channel attacks by combining data-dependent and data-independent memory access.
Practical non-human key hygiene requires adhering to three production rules:
- One key per agent, per environment: Provision separate keys for development, staging, and production. If an experimental scheduler running on a local developer machine makes an error, production systems remain isolated.
- Prompt context exclusion: As outlined in the OWASP Top 10 for LLM Applications guidance on sensitive information disclosure, injecting raw API credentials into prompt contexts, scratchpads, or memory systems exposes secrets during prompt injections or error logging. Keys belong strictly in execution-time environment variables or external secret stores accessed by the tool execution wrapper.
- Distinct human and machine identity paths: Never allow human platform operators and automated agents to authenticate through the same flow. AgentDraft uses separate auth architectures for people and autonomous agents. Humans sign in to the dashboard using a passkey (WebAuthn), with a magic link serving as the bootstrap and recovery mechanism. As explained in the NHIMG WebAuthn passkeys overview, public-key authentication via WebAuthn eliminates shared secrets and provides hardware-backed resistance against credential phishing and replay attacks.
Enterprise SSO (SAML/SCIM via WorkOS) is on the AgentDraft roadmap and not available today; agents authenticate with bearer API keys and humans with passkeys.
Scopes are the actual permission model. Roles are a naming convention on top.
In secure agent authentication, a "role" is merely a mental model for human operators. Downstream enforcement systems do not parse human-readable roles; they evaluate granular, deterministic scopes attached directly to the authenticated credential. If an agent designated as a "Customer Support Triage Agent" possesses a key authorized for destructive writes, any model deviation can result in state mutations across the underlying platform.
AgentDraft agents authenticate with bearer API keys prefixed avs_live_, stored argon2id-hashed. Each key carries explicit scopes (availability:read, bookings:read, bookings:write, mailbox:read, mailbox:write, rules:read, approvals:request); new keys default to availability:read and bookings:write, and approvals:request must be granted per key.
Scopes must be validated at the endpoint handler, not within application logic downstream from the request. When an agent attempts an unauthorized operation, the system must immediately reject the call with an HTTP 403 Forbidden response rather than attempting a partial write or fallback execution.
Consider the functional scopes required for common agent responsibilities:
- Calendar Coordinator: Requires
availability:readandbookings:writeto inspect open slots and place holds. It should lackmailbox:readandmailbox:writeentirely. - Email Parser: Requires
mailbox:readto ingest messages and summarize user inquiries. It does not requirebookings:write. - Escalation Agent: Requires
approvals:requestto surface structured payloads to human operators when confidence thresholds fail or irreversible actions are proposed.
Platform engineers face an architectural tradeoff between debugging convenience and blast radius isolation. Granting broad, wildcard scopes minimizes development friction and eliminates HTTP 403 authorization failures during rapid prototyping. However, broad scopes increase systemic vulnerability: a single runaway loop or prompt-injection attack can alter critical resources across calendars, mailboxes, and workflows. Narrow, explicit scopes introduce small operational overhead when an agent's mandate expands, requiring a key update or re-provisioning, but they guarantee deterministic execution boundaries.
To diagnose permission boundaries during failures, log the authenticated key ID and the granted scope set alongside every rejection. When an agent fails an operation, platform engineers should be able to review the audit log and immediately determine whether the failure stemmed from model execution logic or an intentional scope restriction.
Isolate blast radius with per-agent inboxes and calendars
Authentication boundaries must extend to shared resources. When multiple agents share a single email address or calendar, actions taken by one agent bleed into the operational space of every other agent. If an experimental outbound sales agent triggers spam rate limits on a shared email inbox, the transactional booking notifications and inbound support pipelines running through that same inbox stall completely.
AgentDraft gives AI agents per-agent email inboxes with inbound webhooks, replies, and audit evidence. The number of inboxes a workspace can run at once is set by plan: 1 on Developer and Individual, 5 on Team, 25 on Scale, unlimited on Enterprise. Isolating email inboxes on a per-agent basis ensures that an agent running an unconstrained loop rapidly exhausts its own isolated quota rather than degrading the domain reputation or messaging throughput of the entire engineering platform.
However, resource isolation is fundamentally constrained by workspace architecture. Mailboxes are counted per workspace, so per-agent isolation only goes as far as the plan's mailbox count. AgentDraft's free Developer tier includes one mailbox, which the workspace owner can move between its 3 agents; giving several agents their own inbox at the same time needs Team (5 mailboxes) or above.
On the calendar interface, multi-agent concurrency presents immediate operational risks. If two independent autonomous agents—such as an inbound SDR agent and an internal recruitment agent—attempt to book the same executive meeting slot simultaneously, naive scheduling layers execute a double-booking. AgentDraft coordinates holds and commits through a priority-aware conflict engine so multiple agents can act on the same calendar without double-booking. For external calendar integration, AgentDraft syncs Google Calendar today; Microsoft 365 / Outlook calendar sync is planned, not yet shipped.
As a baseline architectural rule: if two autonomous agents are capable of independently dispatching external communications, provision two isolated mailboxes before iterating on agent system prompts.
Where the human gate goes: before the irreversible action, not after
A comprehensive strategy for AI agent identity and access management acknowledges that autonomous models occasionally make mistakes. While reads, availability checks, and local data transformations can execute autonomously, irreversible operations—such as sending unvetted external emails, committing contract modifications, initiating wire transfers, or executing database migrations—require a deterministic human gate.
AgentDraft lets an agent pause any consequential action for human sign-off: it opens an approval request carrying a one-line summary and a JSON evidence payload, a person approves or denies it in the dashboard with an optional note, and the agent reads the outcome back. The gated action does not have to be one AgentDraft performs — a deploy, a migration, or a refund is gated the same way. Every transition lands in the append-only audit trail and fires an approval.* webhook.
The requesting agent decides for itself when to open an approval request. AgentDraft does not yet provide a policy engine that auto-requires approval by action class, amount threshold, or role, and there are no escalation chains or multi-approver quorums — a single workspace human resolves each request. This structural design places the decision boundary inside the agent's deterministic workflow code: the agent evaluates its own task certainty, constructs the payload, issues the call to approvals:request, and polls or listens for the resolution event before proceeding.
Approvals are decided in the AgentDraft dashboard. AgentDraft emails the workspace owner a notification linking to the queue, but the decision itself is made signed in — there are deliberately no approve-from-email links, because an unauthenticated one-click approve is an attack surface. Slack, Discord, Teams, SMS and push delivery are not available today. Requiring dashboard authentication prevents malicious actors from triggering unauthorized approvals via email interception, link-scanning security bots, or CSRF attacks.
Apply this design pattern across all agent tool configurations: gate the write, not the read. Erroneous reads generate benign log noise, but unauthorized writes permanently compromise production systems.
The audit record is the access-control artifact auditors actually ask for
Managing agent roles is meaningless without persistent, verifiable records of every transaction. When an autonomous workflow fails, platform engineers and compliance auditors do not inspect model prompts; they evaluate access control artifacts. They need to answer: which key made the request, what scope authorized it, which resource was modified, what was the exact payload, and when did the execution complete?
AgentDraft records state-changing agent actions in an append-only audit trail. Every state-changing operation emits an audit record, linking the machine identity to its exact execution footprint. The audit trail captures:
- The authenticated actor (the specific key ID, avoiding shared identity ambiguity).
- The authorization scope evaluated at the request boundary (such as
bookings:writeormailbox:write). - The target endpoint, HTTP method, and complete JSON evidence payload.
- The sub-second timestamp of request intake and final state commitment.
- The execution outcome, including upstream error codes or human approval resolutions.
Retention is per-tier and enforced on read as well as on write, so the retention claim holds even though deletion is lazy. Under this architecture, queries for events occurring outside the entitled retention window are rejected at the database access layer, preventing data leakage regardless of when background pruning jobs purge historical records. AgentDraft does not hold formal compliance certifications (SOC 2, HIPAA, ISO 27001, etc.). It does keep an append-only audit trail.
To verify your identity and audit architecture, run a manual verification drill: select a random state-changing write executed last week and reconstruct its complete provenance. If your platform logging cannot immediately surface the originating agent ID, the verified credential scope, and the corresponding human approval record, your access control boundary contains critical visibility gaps.
Webhook identity: verifying that the payload came from the system you think it did
Identity is a two-way street. While agents must authenticate outgoing requests using scoped bearer tokens, platform services receiving asynchronous event notifications must verify inbound identity. If an autonomous worker processes unverified inbound webhooks, any external entity capable of reaching the HTTP listener can inject forged instructions directly into the agent's tool execution pipeline.
AgentDraft signs every webhook delivery with an X-AgentDraft-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256> header computed over <t>. followed by the raw request body, using the workspace's signing secret. The receiver verifies it; AgentDraft recommends that receivers reject any timestamp more than 300 seconds (5 minutes) from the current time to block replays, and its documented reference verifier does so. Signed webhook delivery is available on every plan, including the free Developer tier.
Developers frequently introduce two critical implementation bugs when writing custom webhook handlers:
- Parsing the JSON body before verification: In frameworks like Express, FastAPI, or Flask, developers often access parsed JSON dictionaries directly. Re-serializing a JSON object changes whitespace, key ordering, and character escapes. As a result, computing the HMAC-SHA256 over re-serialized text alters the byte sequence and fails signature verification. The HMAC must often be calculated against the raw, unparsed request bytes received over the wire.
- Using standard string equality operators: Comparing signature hashes using built-in string equality (such as
==or===) introduces timing attacks. Standard comparisons return false at the first non-matching byte, allowing an attacker to measure latency differences to infer valid signatures. Webhook verifiers must strictly employ constant-time comparison utilities (such as Python'shmac.compare_digestor Node.js'scrypto.timingSafeEqual).
Review the reference implementation pattern below for handling and verifying incoming webhook deliveries:
import hmac
import hashlib
import time
def verify_agentdraft_webhook(raw_body: bytes, signature_header: str, secret: str) -> bool:
# 1. Parse the signature header components
header_parts = dict(item.split("=") for item in signature_header.split(","))
timestamp = header_parts.get("t")
received_signature = header_parts.get("v1")
if not timestamp or not received_signature:
return False
# 2. Reject replays older than 300 seconds (5 minutes)
current_time = int(time.time())
if abs(current_time - int(timestamp)) > 300:
return False
# 3. Compute HMAC over timestamp.raw_body
signed_payload = f"{timestamp}.".encode("utf-8") + raw_body
computed_signature = hmac.new(
secret.encode("utf-8"),
signed_payload,
hashlib.sha256
).hexdigest()
# 4. Constant-time comparison
return hmac.compare_digest(computed_signature, received_signature)
Any unverified inbound webhook listener represents an unauthenticated, arbitrary execution path directly into your agent runtime.
Race conditions are an access-control problem, not just a scheduling problem
Platform developers typically classify race conditions as scheduling or concurrency bugs. In multi-agent autonomous environments, concurrency is fundamentally an access-control failure. When two agents read the same state simultaneously, validate that an action is permissible, and execute competing writes, an uncoordinated system allows both actions to proceed. If your system permissions allow an agent to overwrite a resource based on stale local state, your authorization model suffers from a classic Time-of-Check to Time-of-Use (TOCTOU) vulnerability.
AgentDraft's conflict engine locks time in five-minute buckets: a 30-minute booking writes 6 bucket rows, and the 480-minute maximum booking spans 96. The conflict engine is race-free at the storage layer, not in application code. A booking writes one time-bucket row per 5-minute bucket (so a 30-minute booking writes 6 rows) inside a single DynamoDB TransactWriteItems, and each write carries a ConditionExpression encoding the priority rule — so two agents committing the same slot cannot both win.
Handling booking state transitions requires distinct windows for holds, commits, and priority preemptions:
- AgentDraft holds expire after 30 seconds by default.
- A committed booking can be bumped by a higher-priority agent only within a 30-second window, after which it is frozen.
- A single booking is capped at 480 minutes (8 hours), buffers included, and at 99 five-minute buckets per request; a longer request is rejected with
422 booking_too_long. The cap is service-wide; no workspace or plan setting raises it.
The 99-bucket ceiling reflects strict infrastructure constraints: as documented in the AWS DynamoDB transactional APIs documentation, DynamoDB limits transactions to 100 items per TransactWriteItems call. By dedicating 99 items to individual 5-minute time buckets and 1 item to the parent booking metadata record, the platform enforces atomic validation across the entire requested block.
If your multi-agent architecture coordinates shared resources using read-then-write checks in application code (such as querying an SQL database for open slots and following with an unconditioned INSERT), agents will inevitably double-book resources under concurrent load. Permission rules and priority preemption must be enforced at the storage engine layer.
A working checklist for AI agent identity and access management
Before deploying autonomous agents with real-world tool execution access, verify your platform architecture against this operational checklist:
- Isolated Credentials: Every agent possesses a unique bearer token prefixed
avs_live_stored using memory-hard Argon2id hashing. No shared workspace keys exist in production. - Strict Endpoint Scopes: Keys carry minimal, explicit scopes (such as
availability:readandbookings:write). In AgentDraft,approvals:requestis not enabled by default and must be explicitly provisioned per key. - Blast Radius Containment: Agents that independently send email are allocated their own dedicated mailboxes, isolating domain reputation and rate limits.
- Pre-Commit Human Review: Destructive or external state mutations require passing a structured JSON evidence payload through a human approval gate. Decisions are authenticated through the dashboard using WebAuthn passkeys.
- Cryptographic Webhook Verification: Inbound listeners verify
X-AgentDraft-Signatureusing constant-time byte comparisons and enforce a 300-second timestamp freshness window to eliminate replay attacks. - Atomic Storage-Level Concurrency: State modifications to shared schedules operate via storage-level conditional writes, eliminating application-tier race conditions and TOCTOU vulnerabilities.
- Defined Revocation Runbook: Platform engineers have an immediate, programmatic method to revoke an individual agent's key ID without modifying adjacent services or interrupting unrelated workflows.
Frequently Asked Questions
How do I give each AI agent its own identity instead of sharing one API key?
Provision distinct bearer API keys for each agent worker, each prefixed with avs_live_. Dedicated credentials isolate key usage, define distinct permission scopes per key, and allow revoking a malfunctioning worker instantly without interrupting other agents across the workspace.
What scopes should a scheduling agent have versus an agent that sends email?
A scheduling agent should only be provisioned with calendar scopes, specifically availability:read to discover open slots and bookings:write to lock holds and commits. An email agent requires mailbox:read and mailbox:write to inspect inbound messages and dispatch responses. High-risk capabilities such as approvals:request should only be granted to agents specifically configured to open human review gates.
Can an agent approve its own action in AgentDraft?
No. Approvals are decided in the AgentDraft dashboard by authenticated human operators. An agent can only open an approval request by submitting a summary and a structured JSON evidence payload. The decision to approve or deny must be submitted by a human signed in with a passkey, preventing autonomous agents from closing their own verification loops.
How long does AgentDraft keep audit records, and does retention differ by plan?
AgentDraft records state-changing agent actions in an append-only audit trail with plan-based retention windows. The Developer tier includes 7-day audit retention. Retention limits are enforced on both read and write operations: historical queries past your plan's retention threshold are programmatically rejected at the database boundary, ensuring compliance boundaries hold before background lazy deletion completes.
How do I verify that an inbound webhook actually came from AgentDraft?
Inspect the incoming X-AgentDraft-Signature header, which contains a UNIX timestamp and an HMAC-SHA256 hex digest. Compute the HMAC over the timestamp followed by a period and the raw request bytes using your workspace signing secret. Compare the digests using a constant-time comparison utility, and reject any payload where the timestamp differs from the current system time by more than 300 seconds.
To implement scoped keys, atomic calendar concurrency, and human approval gates across your agent workflows, sign up for AgentDraft at https://agentdraft.io/pricing. AgentDraft's Developer tier is free with no card required: 1 seat, 3 agents, 1 mailbox, 1 connected calendar, 50 bookings a month, and 7-day audit retention. Developer-tier outbound email must reply within a booking thread and is capped at 5 sends per agent per day. Signed webhook delivery is included on the Developer tier, so a free workspace is a working sandbox for testing webhook handlers. For details on platform updates, monitor the AgentDraft changelog or inspect the AgentDraft webhook documentation.