Govern AI agent API access end to end: a setup guide for platform engineers
A complete platform engineer's guide to governing AI agent API access in Zerq: scoped clients, per-agent profiles, rate limits, MCP setup, and audit trail.
- ai-agents
- mcp
- access-control
- governance
- security
AI agents are calling your enterprise APIs. Not in a controlled, reviewed, purpose-built way. In many teams they are using tokens that were created for testing, shared with a CI/CD pipeline, or issued to a developer six months ago and never rotated. When something goes wrong, you cannot tell from the logs whether the request came from an agent, an app, or a person. That is the AI agent API access control problem, and it compounds every time a new agent gets wired in without a governance review.
This guide walks through setting up scoped, governed AI agent API access in Zerq from scratch. You will create a dedicated client for the agent, assign only the collections it needs, attach a rate limit policy designed for non-human traffic, configure a profile with method restrictions and IP allowlisting, initialize an MCP session to verify the scope, and confirm the access controls in the request logs before the agent goes to production.
Why ad hoc agent credentials create compliance and security gaps
Most teams connecting AI agents to enterprise APIs reach for whatever credential is available: a service account token from a CI/CD pipeline, a personal API key, or a bearer token originally issued for a different microservice. This gets the integration working quickly. It also creates several problems that accumulate silently until a compliance review or a security incident forces them into view.
The first is shared blast radius. When an AI agent uses the same credential as a billing service, a compromised or runaway agent can reach every API the billing service is authorized to call. That might be a read-only analytics endpoint, or it might be a payment initiation endpoint. Revoking the credential to contain the damage requires taking the billing service offline at the same time.
The second is audit opacity. Shared credentials make the request log a ledger of undifferentiated calls. When a compliance reviewer asks why your accounts API received 3,000 requests between 2am and 3am last Tuesday, "client ID 8f2a4c was calling it" is not a useful answer if that same client ID covers your data warehouse connector, an internal agent, and three developer test environments.
Kong, Apigee, and AWS API Gateway do not solve this natively. You can issue an API key for an agent, but there is no built-in mechanism to restrict that key to a subset of your API catalog, enforce read-only HTTP methods at the credential level, or set throughput limits tuned to the agent's expected call pattern rather than borrowed from human-traffic defaults. Every governance requirement becomes a custom plugin or an external authorization policy, neither of which appears in your existing traffic logs.
Zerq's access model (clients, profiles, collection assignments, and rate limit policies) applies to AI agents exactly as it does to any other consumer. The same enforcement, the same logs, the same security controls. No separate agent gateway, no second credential store.
Setting up AI agent access control in Zerq
The four layers you configure are: the client (who the agent is), the collection assignment (which APIs it can see), the policy (how much traffic it can send), and the profile (how it authenticates and which HTTP methods it can use). Configure them in sequence and each layer narrows the next.
Step 1: create a dedicated client for the agent
Go to Clients in the sidebar and click New Client. Fill in the form:
| Field | Value for an AI agent |
|---|---|
| Name | Identify the agent and environment: fraud-analysis-agent-prod |
| Description | Record the purpose and team contact: Read-only fraud detection agent. Owner: [email protected] |
| The team contact email, not a personal address | |
| Collections | Only the collections this agent actually needs (see step 2) |
| Policy | Leave blank for now (you will attach one in step 3) |
| Developer Portal access | Off; agents do not use the developer portal |
Click Create. Zerq generates a Client ID (UUID) and a default profile with no auth. You will configure the profile in step 4.
One agent, one client. Do not share a client between agent environments. A staging agent and a production agent should be separate clients with separate credentials. This gives you independent rotation, independent audit history, and the ability to suspend one without affecting the other. When a security event requires credential rotation for the production agent, you rotate exactly one token and nothing else changes.
Step 2: assign collections at minimum privilege
The most important decision in this entire setup is which collections the agent can reach. Zerq enforces collection assignment at the gateway: a request from this client to a collection it is not assigned returns 403, regardless of what credential it presents and regardless of whether the endpoint exists.
For a fraud analysis agent that needs transaction history and account summary data only:
- Assign:
transactions-api,accounts-readonly-api - Do not assign:
payments-api,admin-api,user-management-api
Go back to the collection selection in Edit Client, check only those two, and save. From this point, the agent cannot discover that payments-api or admin-api exist. They do not appear in MCP tool results and any direct REST call to those paths returns 403.
This collection-level boundary is the primary blast radius control. The scope of any worst-case outcome is bounded before the agent ships.
Step 3: create a rate limit policy for agent traffic
AI agents have different traffic patterns from human clients. A well-behaved agent polling for data every 30 seconds sends around 120 requests per hour in steady state. An agent caught in a feedback loop, or responding to a prompt that generates repeated API calls, can send thousands of requests in seconds. Standard human-traffic rate limits are often far too permissive for agent workloads.
Go to Policies in the sidebar, click New Policy, and configure:
name: "fraud-agent-strict"
description: "Rate limits for fraud analysis agent: tighter than human traffic"
rate_limit:
max_requests: 60 # 1 per second average, enough for periodic polling
interval: "1m" # 1-minute sliding window
quota:
max_requests: 50000 # daily ceiling; investigate if exceeded
interval: "1d" # resets at midnight UTC
The interval field for rate limits accepts 1m, 5m, or 1h. For quotas: 1d, 7d, or 30d. When the agent exceeds the rate limit, Zerq returns:
{
"error": "rate_limit_exceeded",
"message": "You have exceeded your request rate limit. Please try again later."
}
This 429 response is logged with the client ID and profile ID attached, so a spike in rate limit hits is immediately visible when you filter the request log by client.
Return to the client, click Edit, select fraud-agent-strict from the Policy dropdown, and save.
Step 4: configure a read-only profile with IP restrictions
Open the client and navigate to the Profiles tab. Click into the default profile and click Edit. Configure:
| Field | Setting |
|---|---|
| Name | production-readonly |
| Active | On |
| Auth Type | token: Zerq auto-generates a bearer token; copy it immediately after saving |
| Allowed Methods | GET only; deselect POST, PUT, DELETE, PATCH, OPTIONS, HEAD |
| IP Restrictions | The CIDR block where the agent runs: 10.0.4.0/24 |
Setting Allowed Methods to GET only enforces read-only access at the profile level, independent of what the collection allows. Even if transactions-api exposes a POST /transactions/initiate endpoint, a request from this profile using POST returns 405 Method Not Allowed. This is the method-level enforcement layer.
Setting IP Restrictions means requests from any address outside that CIDR range are rejected with 403 before the token is even validated. Add multiple CIDR ranges as separate entries if the agent runs across multiple infrastructure segments.
After saving, the profile detail page shows three values you need:
- Copy X-Client-ID: the client's UUID
- Copy X-Profile-ID: this profile's UUID
- Copy Authorization header: the full
Authorization: Bearer <token>string
Store these in a secrets manager. The raw token is only displayed once. To retrieve it later, you use Rotate credentials, which generates a new token and immediately invalidates the old one.
Step 5: initialize an MCP session and verify scope
If the agent connects via Gateway MCP, the session begins with an initialize call. Pass all three credential values as headers:
curl -X POST "https://gateway.company.com/mcp" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer zerq_tok_xxxxxx" \
-H "X-Client-ID: cl_7f3a29b1-0000-0000-0000-000000000000" \
-H "X-Profile-ID: pr_c2d4e891-0000-0000-0000-000000000000" \
-d '{
"jsonrpc": "2.0",
"method": "initialize",
"id": 1,
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "fraud-analysis-agent", "version": "1.0" }
}
}'
The response includes an Mcp-Session-Id header. Use it on all subsequent requests in the session:
curl -X POST "https://gateway.company.com/mcp" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer zerq_tok_xxxxxx" \
-H "X-Client-ID: cl_7f3a29b1-..." \
-H "X-Profile-ID: pr_c2d4e891-..." \
-H "Mcp-Session-Id: sess_a1b2c3d4..." \
-d '{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 2
}'
The tools/list response returns the four Gateway MCP tools: list_collections, list_endpoints, endpoint_details, and execute_endpoint. When the agent calls list_collections, it only sees transactions-api and accounts-readonly-api. The existence of payments-api and admin-api is not disclosed.
Step 6: run the three verification calls
Before deploying the agent, confirm all three enforcement layers are working:
# Confirm a GET request on an assigned collection succeeds
curl -i "https://gateway.company.com/transactions/v1/recent" \
-H "Authorization: Bearer zerq_tok_xxxxxx" \
-H "X-Client-ID: cl_7f3a29b1-..." \
-H "X-Profile-ID: pr_c2d4e891-..."
# Expected: 200
# Confirm a POST is blocked by the method restriction
curl -i -X POST "https://gateway.company.com/transactions/v1/initiate" \
-H "Authorization: Bearer zerq_tok_xxxxxx" \
-H "X-Client-ID: cl_7f3a29b1-..." \
-H "X-Profile-ID: pr_c2d4e891-..."
# Expected: 405 Method Not Allowed
# Confirm a collection outside scope is blocked
curl -i "https://gateway.company.com/payments/v1/accounts" \
-H "Authorization: Bearer zerq_tok_xxxxxx" \
-H "X-Client-ID: cl_7f3a29b1-..." \
-H "X-Profile-ID: pr_c2d4e891-..."
# Expected: 403 Forbidden
All three responses (200, 405, and 403) appear in the request logs with the client ID and profile ID attached. This is intentional: every denied request is logged with as much identity context as a successful one.
Step 7: read the agent's request log entries
Go to Logs in the sidebar and filter by Client ID to see all requests from this agent. Each entry contains:
| Field | What it tells you for an AI agent |
|---|---|
Request ID | Unique trace ID for incident correlation |
Client ID | Confirms which agent made the request; not shared with any other service |
Profile ID | Confirms the read-only production profile was used, not a dev profile |
Collection | Which API product was called; any unexpected collection indicates a credential mix-up |
Method | Should only be GET; any POST or DELETE indicates a profile misconfiguration |
Status code | 200 (success), 403 (scope violation), 405 (method blocked), 429 (rate limit) |
Latency | Outliers suggest upstream issues or agent feedback loops |
Client IP | Should stay within the configured CIDR range |
For a fraud agent polling every 30 seconds, you expect a steady stream of 200s on GET paths, with Client ID constant. Any 403 on a collection the agent is not supposed to reach is worth investigating immediately — it means either the agent code changed or the token ended up in a different process. A run of 429s indicates the polling interval is too short for the configured rate limit budget.
Filter, bookmark, and share these log views using the URL. The dashboard's View Logs links construct pre-filtered URLs; you can share a link to "all 4xx responses from this client in the last 7 days" directly with a security reviewer without requiring them to navigate the filter UI.
The observability layer applies to all traffic through the gateway. There is no separate logging path for MCP sessions or AI agent calls; they appear in the same request log as REST traffic, with the same fields, the same filtering, and the same retention policy.
What this looks like in practice
A mid-sized financial services team building an internal fraud scoring system wanted to connect a real-time analysis agent to their transactions API. The agent was to poll for recent transactions every 30 seconds, score them against a model, and write findings to an internal data store. The write path was entirely outside the API gateway.
Before moving to per-agent access control, the team had the agent sharing a token with their data warehouse connector. Both appeared in logs with the same client ID. When a quarterly compliance review flagged unusual off-hours API activity, neither the platform team nor the compliance team could determine quickly whether it was the warehouse connector running scheduled exports or the agent. Both had to be investigated, and the token had to be rotated for both simultaneously, which took the connector offline for roughly 20 minutes while a replacement credential was provisioned, configured, and deployed.
After setting up a dedicated client in Zerq, the migration took about 10 minutes of admin time:
- One new client:
fraud-analysis-agent-prod, assigned totransactions-apionly - Rate limit policy: 60 requests per minute, 50,000 per day
- Profile: GET only, restricted to the agent infrastructure's CIDR block
The agent now appears in logs under its own client ID. Compliance reviewers can export all requests from fraud-analysis-agent-prod for any time window in seconds, with no cross-referencing required. Token rotation (scheduled quarterly) happens independently. When the token rotates, the warehouse connector is untouched. The compliance team gets the token rotation audit event in the platform's change log, timestamped, with the actor ID of the admin who performed the rotation.
The architecture overview explains how Zerq stores both request logs and config change events in the customer's own MongoDB instance. The compliance team's quarterly export pulls from the same database that runs the gateway; there is no external system to query and no data leaves the customer's environment.
What this setup gives you that shared credentials cannot
Per-agent access control in Zerq gives you four things that ad hoc credential sharing cannot replicate:
The blast radius is defined before the agent ships. Collection assignments and method restrictions mean that even if the agent behaves unexpectedly, the maximum scope of any damage is bounded at configuration time. You do not need a separate security review every time an agent's behavior changes, because the enforcement is at the gateway rather than in the agent code.
The audit trail is unified. Every agent request appears in the same request log as every human and app request. Compliance teams can filter, export, and query across all traffic without needing to correlate from multiple systems. Denied requests are logged with the same completeness as successful ones.
Rate limits are sized for agent traffic. Borrowing a human-traffic rate limit for an agent is not a security control; it is a coincidence. Setting the limit at the policy level, independent of the agent code, means you can tune it without a deployment, and it enforces a ceiling even if the agent's logic changes.
The credential lifecycle is independent. When a security event requires rotation, you rotate one token, one profile. No shared credentials to audit, no other services to coordinate with.
Zerq is an enterprise API gateway built for regulated industries — one platform for API management, AI agent access, compliance audit, and developer portal, running entirely in your own infrastructure. See how it works or request a demo to walk through your specific requirements.