Set Up ACP with Auth0
This guide walks you through the complete Auth0 setup — from creating the Auth0 API to seeing verified identity flow through your first tool call.
What you need
- An Auth0 account (free tier works)
- An ACP Cloud workspace (sign up)
Step 1: Create an Auth0 API
In the Auth0 Dashboard, go to Applications → APIs → Create API.
| Field | Value |
|---|---|
| Name | ACP Gateway (or anything descriptive) |
| Identifier (Audience) | https://api.agenticcontrolplane.com/your-slug |
| Signing Algorithm | RS256 (required — ACP rejects HS256) |
The identifier becomes the aud claim in JWTs. ACP verifies it on every request.
Step 2: Configure permissions
Under your API’s Permissions tab, add the scopes your tools will require:
salesforce:read
salesforce:write
github:read
github:write
slack:read
slack:write
These will appear in the permissions claim of Auth0 JWTs when you enable RBAC.
Enable RBAC
Go to your API’s Settings tab and enable:
- Enable RBAC ✓
- Add Permissions in the Access Token ✓
Now when users authenticate, their JWT includes a permissions array with the scopes you’ve assigned to their role.
Step 3: Set up roles
Go to User Management → Roles and create roles that map to your team structure:
| Role | Permissions |
|---|---|
| Sales (Read Only) | salesforce:read |
| Sales (Full Access) | salesforce:read, salesforce:write |
| Developer | github:read, github:write, slack:read |
| Admin | All permissions |
Assign users to roles. When they authenticate, their JWT carries their role’s permissions.
Step 4: Configure ACP
In your ACP dashboard, go to Settings → Identity Providers and enter:
| Field | Value |
|---|---|
| Issuer | https://your-tenant.auth0.com/ |
| Audience | https://api.agenticcontrolplane.com/your-slug |
| JWKS URI | Leave blank (auto-discovered from issuer) |
| Scope Claim | scope |
| Role Claim | permissions |
| Tenant Claim | org_id |
Auth0 claim mapping
Here’s how Auth0 JWT claims map to ACP identity fields:
| Auth0 Claim | ACP Field | Example |
|---|---|---|
sub |
identity.sub |
auth0\|8f3a2b1c9d4e5f6a |
iss |
identity.issuer |
https://your-tenant.auth0.com/ |
scope |
identity.scopes |
["openid", "profile", "email"] |
permissions |
identity.roles |
["salesforce:read", "github:write"] |
org_id |
identity.tenantId |
org_acme_corp |
email |
identity.email |
alice@acme.com |
name |
identity.name |
Alice Chen |
The permissions claim from Auth0 RBAC maps to roles in ACP. The scope claim carries OAuth scopes (if using custom grant flows). Both are checked during governance.
Step 5: Configure tool scopes
In Policies → Tool Scopes, map permissions to tools:
{
"salesforce.query": ["salesforce:read"],
"salesforce.createRecord": ["salesforce:write"],
"github.listRepos": ["github:read"],
"github.createIssue": ["github:write"]
}
When a user calls salesforce.query, ACP checks that their JWT contains salesforce:read in the permissions claim. If it doesn’t, the call is rejected with 403 Insufficient scope.
Step 6: Test the flow
Using the ACP playground
Go to Tools → Playground in the dashboard. Select a tool, enter test input, and execute. The playground uses your Firebase Auth session — you’ll see the governance decision in real-time.
Using an MCP client
Point Claude Desktop or any MCP client at https://api.agenticcontrolplane.com/your-slug. When you authenticate, Auth0 issues a JWT. ACP verifies it and grants access based on your permissions.
Verify in the audit log
Check Logs in the dashboard. You’ll see:
{
"sub": "auth0|8f3a2b1c9d4e5f6a",
"tool": "salesforce.query",
"scopes": ["salesforce:read", "salesforce:write"],
"ok": true,
"latencyMs": 142
}
The sub is the Auth0 user ID. The scopes are from the JWT. The action is fully attributed.
Auth0 Organizations (multi-tenant)
If you use Auth0 Organizations, users’ JWTs include an org_id claim. Set the Tenant Claim to org_id in ACP’s IdP config.
ACP uses this for tenant isolation — users in one organization can’t access another organization’s data, even if they authenticate with the same Auth0 tenant.
Troubleshooting
“Invalid token: unexpected iss claim”
Your issuer URL has a trailing slash mismatch. Auth0 tokens use https://your-tenant.auth0.com/ (with trailing slash). ACP normalizes this, but make sure your configured issuer matches what Auth0 puts in the token.
“Insufficient scope” The user’s JWT doesn’t include the required permission. Check: (1) RBAC is enabled on the API, (2) “Add Permissions in the Access Token” is checked, (3) the user is assigned a role with the required permission.
“Missing bearer token” The MCP client isn’t sending the Authorization header. Ensure the client is configured to use OAuth, not just connecting without auth.
Back to guides · Set up Okta → · Set up Entra ID →
Run agents? ACP lets you see, control, and price every tool call they make — allow/ask/deny policy, per-session cost, and a full audit log for Claude Code, Cursor, Codex, and OpenClaw, in one command:
curl -sf https://agenticcontrolplane.com/install.sh | bash
irm https://agenticcontrolplane.com/install.ps1 | iex
Getting started → · see your first governed call → · free up to 5 agents