Scoped bearer keys for agentic API testing: what to grant, what to revoke, and how to prove it
Your agent works in a demo and fails in production because every key it holds can do everything. This walks through per-agent bearer keys, explicit scopes, and the test cases that catch a key with too much reach before an auditor does.
The short answer: one key per agent, scopes listed explicitly, and a test that asserts the 403
Agentic API authentication for testing requires issuing a distinct bearer token to each autonomous agent, restricting that token to the exact endpoints the agent needs, and writing tests to verify that forbidden operations return an HTTP 403 Forbidden status code. Permissions expand silently without active rejection tests. If an automated system does not actively test rejection, a single compromised or looping agent can modify resources across your entire infrastructure.
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. Shared keys destroy blast-radius boundaries. When two agents share a single token, a scheduling agent can initiate emails, a mailbox parser can overwrite calendar events, and your audit trail attributes every modification to one shared credential.
You can verify your authorization perimeter quickly. If two agent instances use the same bearer token in your test suite, revoke one immediately and generate a separate key before writing another line of orchestration code. Newly generated keys are not read-only. Because new keys default to availability:read and bookings:write, an agent configured to check calendar availability retains permission to overwrite bookings. The first integration test you write must assert that an agent intended to be read-only cannot perform a write action. Review the full endpoint mapping in the AgentDraft documentation to align your test fixtures against current scope definitions.
Why a shared key breaks before your agent does
When two agents share a bearer token, concurrent operations lose attribution. Consider a common operational incident: Agent A evaluates an inbound email request and schedules a calendar event while Agent B performs an identical task for a different customer. If both agents share the bearer token avs_live_test_123, and Agent A hits a network timeout while committing a hold, its retry logic fires a second request. If Agent B simultaneously attempts to reserve a slot within the same window, the API processes two state modifications under the same credential. When debugging the incident, your engineering team cannot identify which agent executed the retry and which executed the original request.
The failure mode is equally severe inside an agent's email layer. An AgentDraft mailbox is an addressable inbox owned by one agent; giving each agent its own mailbox isolates blast radius, so one runaway agent exhausts its own quota without exhausting the whole sending domain. If two agents share a single bearer key with the mailbox:write scope, Agent A can read inbound inquiries directed at Agent B, draft replies to external senders using Agent B's address, or purge unread messages before the intended workflow processes them.
Per-agent isolation only goes as far as the plan's mailbox count. Rate limits and sending quotas attach to the API key and its associated entity. When a looping agent rapidly consumes its allocated requests on a shared credential, it starves every other agent using that token.
When an incident occurs and an auditor asks which autonomous process initiated a state change, a shared key makes it impossible to answer. AgentDraft records state-changing agent actions in an append-only audit trail. That audit trail records the authenticated credential, not the prompt context inside an external framework. If you pass one key to five agents, your audit trail contains five times the noise and zero attribution.
Mapping scopes to endpoints before you write a test
Agentic API authentication for testing requires mapping HTTP verbs and paths to the API's granular scopes. The API rejects any request where the bearer token lacks the explicit scope tied to that endpoint, returning an HTTP 403 response with an error payload explaining the missing capability.
| Scope Name | Endpoint Surface | Operational Role |
|---|---|---|
availability:read | GET /v1/availability | Queries open 5-minute time buckets without reserving space. |
bookings:read | GET /v1/bookings/* | Inspects confirmed appointments, attendee records, and hold metadata. |
bookings:write | POST /v1/holds, POST /v1/bookings | Applies short-lived holds and commits calendar reservations. |
mailbox:read | GET /v1/mailbox/messages | Reads inbound messages, webhook payloads, and thread status. |
mailbox:write | POST /v1/mailbox/send | Dispatches booking-linked or freeform outbound email messages. |
rules:read | GET /v1/rules | Pulls schedule constraints, buffer times, and working windows. |
approvals:request | POST /v1/approvals | Suspends execution and posts an evidence payload to the human dashboard. |
The approvals:request scope is omitted from the default scope set. Creating an approval request is a state-changing operation that places an item into an operator's dashboard queue. Defaults protect human operators. If every key held this permission by default, a misconfigured agent could trigger thousands of operator alerts across a live workspace. Requiring approvals:request to be granted explicitly ensures that only designated workflow orchestrators wake human operators.
You can establish minimum viable key profiles for three primary agent architectures:
- A scheduling agent requires
availability:read,bookings:read, andbookings:write. It cannot access inbound email boxes or generate human approval requests. - A mail triage agent requires
mailbox:readandmailbox:write. It can ingest and dispatch correspondence, but cannot read or alter calendar state. - A deploy or remediation orchestrator requires only
approvals:request. It has no direct access to booking calendars or email boxes because its only role is pausing downstream operations until human sign-off occurs.
Over-granting scopes creates hidden failure modes. If a mail-parsing agent holds mailbox:write when its sole purpose is classifying incoming leads, a reasoning loop could prompt it to send unvetted replies to external customers. Because it holds write access, the API accepts the payload, bypassing human oversight entirely. To inspect the full schema for individual routes, consult the AgentDraft OpenAPI specification. If you connect your agents via framework tooling, the AgentDraft MCP server guide explains how to pass scoped credentials through the Model Context Protocol specification without exposing broad administrator credentials to your local runtime.
Agent bearer token testing: the four assertions that catch a key with too much reach
Validating an agentic architecture requires writing automated test suites focused directly on authorization boundaries. Agent bearer token testing confirms that invalid requests fail cleanly without crashing the calling process while verifying that valid calls return HTTP 200. Your test suite should implement four specific assertions.
Assertion 1: out-of-scope calls return HTTP 403 Forbidden
When an agent configured with read-only permissions attempts to write to an endpoint, the API returns a 403 Forbidden status code. It does not return 200 OK or 500 Internal Server Error. Assert exact status codes. Your test harness should pass a key lacking bookings:write to your booking client and verify the response:
// Example test asserting scope enforcement
const response = await fetch("https://api.agentdraft.io/v1/bookings", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SCHEDULER_READ_ONLY_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
slot: "2026-11-01T10:00:00Z",
duration_minutes: 30
})
});
assert.strictEqual(response.status, 403);
const body = await response.json();
assert.strictEqual(body.error, "insufficient_scope");
assert.strictEqual(body.required_scope, "bookings:write");
Running this assertion continuously in CI ensures that dashboard edits do not introduce scope creep over time.
Assertion 2: missing approval permissions reject execution
If an agent workflow pauses for human intervention by calling POST /v1/approvals, but lacks the approvals:request scope, the API returns a 403. The test evaluates whether the unprivileged agent halts execution cleanly, logs the authorization error, and avoids entering an infinite retry loop or triggering unhandled promise rejections.
Assertion 3: revoked credentials return HTTP 401 with immediate loop termination
When an API key is revoked via the dashboard, subsequent requests fail with 401 Unauthorized. The test harness must confirm that the client handles 401 errors distinctly from 403 or 5xx errors. A 403 Forbidden response indicates an authorization misconfiguration that retrying will not resolve. A 401 Unauthorized response indicates an invalid or revoked credential that requires the client to halt execution and trigger an operational alert. The agent's HTTP client must not enter an exponential backoff loop on a 401 response.
Assertion 4: audit trails explicitly attribute modifications to the token ID
Whenever an agent modifies system state, query the audit endpoint to verify attribution. The test passes only if the audit record's actor_id matches the specific key used in the request fixture:
// Confirming audit log attribution
const auditResponse = await fetch(`https://api.agentdraft.io/v1/audit?event_id=${eventId}`, {
headers: { "Authorization": `Bearer ${process.env.ADMIN_AUDIT_KEY}` }
});
const auditData = await auditResponse.json();
assert.strictEqual(auditData.record.key_prefix, "avs_live_sched_");
assert.strictEqual(auditData.record.action, "booking.created");
Your testing environment must also account for inbound communication. 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.
In accordance with time-window validation standards like RFC 6238, write integration tests that supply synthetic webhook events carrying timestamps 301 seconds in the past. Ensure your webhook handler rejects these payloads with an HTTP 400 or 401, confirming replay protection works as intended. For full implementation details, review the AgentDraft webhook verification documentation.
API key scope management for agents: rotation, storage, and the dashboard habits that keep it honest
Implementing reliable API key scope management for agents requires strict operational hygiene across key generation, vault storage, and credential cycling. A structured lifecycle ensures credentials rotate cleanly before security reviews or production deployments occur.
Storage and cryptographic boundaries
AgentDraft hashes API keys using argon2id before writing them to the database. Plaintext keys do not persist in storage. In alignment with the OWASP Password Storage Cheat Sheet, this memory-hard hashing algorithm ensures that a database compromise does not reveal plaintext bearer tokens. Because keys are never stored in reversible formats, they cannot be retrieved after generation. Lost credentials require rotation. Store production keys in a dedicated secrets manager. Do not store credentials in local .env files, following standard practices outlined in the OWASP Secrets Management Cheat Sheet.
Four-step zero-downtime rotation
Deploy replacement credentials before deleting an active agent token. Follow four exact steps:
- Create a new bearer key in the dashboard with the required scope set.
- Update your agent runtime environment configuration with the new key.
- Run your automated authorization test suite against the live agent instance to confirm the new key satisfies all endpoint assertions.
- Revoke the old bearer token in the dashboard, verifying that subsequent requests using the old key receive HTTP 401.
Explicit credential naming
Name every key after its consuming agent process and environment. Avoid generic credential labels. Use explicit descriptors such as triage-agent-staging, booking-agent-prod, or billing-gate-ci. When an engineer reviews audit logs during an outage, self-describing key names clarify which agent executed a conflicting request.
Environment isolation
Staging keys must omit production scopes. A staging key with access to an active production mailbox can dispatch unreviewed messages to live recipients during automated testing. Maintain entirely separate workspaces or credential tiers for staging environments to prevent unintended external actions.
Human versus machine authentication boundaries
Agent credentials and human operator credentials must remain entirely distinct. Humans sign in to the dashboard with a passkey (WebAuthn), with a magic link as the bootstrap and recovery path. Passkeys block phishing attempts. This design follows the W3C Web Authentication specification to provide origin-bound, phishing-resistant access for administrative users. Agents use scoped avs_live_ bearer tokens. Do not inject human session cookies or WebAuthn credentials into automated agent headers.
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. Review the complete security architecture at the AgentDraft security center.
Testing the approval gate and key permissions
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.
Testing an approval gate requires validating the authentication boundaries of the gate itself. If an agent lacks the approvals:request scope, the API rejects the request at the front door with an HTTP 403, preventing orphaned approval states from entering the queue.
Your integration suite should validate four discrete approval paths:
- The agent submits an approval payload containing complete operational context (such as target user ID, destination account, and proposed changes). Verify that the API returns an HTTP 201 Created containing an approval ID and an initial status of
pending. - Simulate or execute an approval decision within the dashboard. The agent polls the endpoint or listens for the
approval.approvedwebhook, confirming that execution resumes safely. - When an operator rejects a request with an explanatory note, verify that the agent halts the blocked workflow, logs the operator note, and stops the gated action.
- Query the audit trail to confirm that the creation, decision, and operator identity are preserved in immutable audit storage.
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.
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. If you need to build robust polling and webhook retry mechanisms around these states, follow the patterns outlined in the AgentDraft human-in-the-loop implementation guide.
Where the free tier stops and what that means for your test plan
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. Signed webhook delivery is included on the Developer tier, so a free workspace is a working sandbox for testing webhook handlers.
This tier structure directly impacts how you design authorization tests. 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. Because the Developer tier provides only one mailbox per workspace, you can validate that three distinct agents enforce three distinct scope profiles, but you cannot test simultaneous inbox-to-inbox isolation between multiple running agents.
If your test suite asserts that Agent A cannot read inbound messages directed to Agent B's dedicated inbox while both run concurrently, you will hit the limits of the Developer tier. AgentDraft plans are per workspace. Developer (free): 3 agents, 1 mailbox, 50 bookings a month. Individual: 3 agents, 1 mailbox, 500 bookings a month. Team: unlimited agents, 5 mailboxes, 5 seats, 10,000 bookings a month. Scale: unlimited agents, 25 mailboxes, 25 seats, 100,000 bookings a month. Enterprise: custom, with no mailbox cap. Freeform outbound email (not tied to a booking) starts at Team.
You must also account for booking limits during automated test runs. AgentDraft coordinates holds and commits through a priority-aware conflict engine so multiple agents can act on the same calendar without double-booking. 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 call, and each write carries a ConditionExpression encoding the priority rule. This architecture relies directly on the guarantees specified in the AWS DynamoDB TransactWriteItems API reference, which caps transactions at 100 items per request.
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. 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. 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. If your automated tests generate booking payloads spanning more than 99 five-minute buckets, the engine rejects them immediately. You can review all tier ceilings on the AgentDraft pricing page.
Pitfalls that pass tests and fail audits
Passing tests in a local environment does not guarantee compliance under production auditing. Several common testing anti-patterns introduce security risks and operational failures that only surface after deployment.
Testing with root credentials
Developers often run integration suites using an administrator key holding every available scope, intending to narrow the scopes before merging. If a deployed agent depends on an ungranted scope, it passes every CI test but immediately crashes with a 403 in production. Write tests using keys configured with the exact minimal scopes designated for that agent.
Treating 403 errors as transient errors
Treating an authorization failure like a temporary network blip causes severe systemic overhead. When an agent receives a 403 Forbidden, retrying ten times generates ten consecutive failure records in your audit trail while stalling your agent's processing queue. Configure your HTTP clients to treat 403 responses as permanent configuration errors that immediately halt the calling task.
Logging key prefixes without token IDs
Relying on key prefixes for operational logging creates ambiguity. Every live token uses the same avs_live_ prefix. Logging only the prefix confirms that a key was present, but provides no insight into which agent owned the key or what permissions it held. Log the explicit agent identifier and unique key name assigned during provisioning.
Misunderstanding audit retention windows
Audit retention is per-tier and enforced on read as well as on write, so the retention claim holds even though deletion is lazy. A test that verifies audit trail generation in a free workspace will succeed initially, but any test asserting access to historical audit records older than 7 days will return empty sets. Ensure your verification harnesses respect your plan's retention ceiling.
Verifying webhook signatures without validating timestamps
A webhook verification test that checks only the HMAC signature passes even if the payload was sent hours ago. Cryptographic integrity ensures the payload was not tampered with, but only strict timestamp verification prevents replay attacks. Any receiver test must verify that payloads older than 300 seconds are rejected outright.
Bypassing dashboard approvals for test convenience
Avoid bypassing approval gates in automated test harnesses. Engineers sometimes create unauthenticated webhooks or custom bypass routes to programmatically approve actions during testing. Simulating human sign-off with arbitrary endpoints removes the security guarantees of the approval system. Keep human approvals inside the dashboard workflow so your test environments mirror actual production paths.
AgentDraft does not hold formal compliance certifications (SOC 2, HIPAA, ISO 27001, etc.). It does keep an append-only audit trail. This append-only design provides verifiable proof of agent actions, provided your keys are scoped correctly from the start.
A checklist you can run before the next deploy
Run through this pre-flight authorization checklist before pushing an agent update to staging or production environments:
- Confirm that every agent runs on its own distinct
avs_live_key so no two processes share a token. - Match each agent key scope to functional requirements, and review diffs whenever capabilities change.
- Include explicit assertions in CI verifying that calls to ungranted endpoints return HTTP 403.
- Terminate client code on 401 and 403 responses, reserving retries for 5xx server errors and network timeouts.
- Reject webhook payloads with timestamps older than 300 seconds regardless of HMAC validity.
- Verify that actions requiring sign-off dispatch an approval request, wait for a decision, and handle rejections.
- Follow a generate-deploy-test-revoke sequence during credential rotation.
The key is the first test surface
An autonomous agent's capabilities are defined entirely by its authentication boundaries. Issuing distinct bearer tokens, restricting their scopes to explicit endpoints, and asserting failure responses in your test suite isolates operational blast radius and preserves attribution across your infrastructure. When an agent experiences an edge-case failure, an append-only audit trail tied to a dedicated credential provides immediate visibility into exactly what occurred.
The public changelog is at agentdraft.io/changelog and every user-visible change lands there. Track scope additions before updating agent permissions in your CI pipeline.
To start testing scoped keys, create an account on AgentDraft. The free Developer tier needs no card and includes 1 user, 3 agents, and one mailbox per workspace.
Frequently asked questions
Which API scopes should an agent receive for basic calendar holds?
An agent reserving calendar holds requires bookings:write. If it also needs to query open slots before reserving,