Set Up ACP with Okta
Okta is the most common enterprise identity provider we see in ACP deployments. This guide walks you through configuring Okta’s authorization server to issue JWTs that ACP can verify and enforce.
What you need
- An Okta organization (developer or production)
- An ACP Cloud workspace (sign up)
Step 1: Create an authorization server
In the Okta Admin Console, go to Security → API → Authorization Servers.
You can use the default authorization server or create a custom one:
| Field | Value |
|---|---|
| Name | ACP Gateway |
| Audience | https://api.makeagents.run/your-slug |
| Description | Authorization server for ACP-governed tools |
The audience must match what you configure in ACP. It appears as the aud claim in every JWT.
Step 2: Add scopes
Under your authorization server, go to Scopes → Add Scope. Create scopes for each tool category:
salesforce:read
salesforce:write
github:read
github:write
slack:read
slack:write
For each scope:
- Name: The scope string (e.g.
salesforce:read) - Include in public metadata: Yes
- Default scope: No (require explicit request)
Step 3: Create access policies
Go to Access Policies → Add Policy on your authorization server. Create a policy that applies to your application, then add rules:
| Rule | Scopes | Groups |
|---|---|---|
| Sales Read | salesforce:read |
Sales Team |
| Sales Full | salesforce:read, salesforce:write |
Sales Managers |
| Dev Access | github:read, github:write, slack:read |
Engineering |
| Admin | All scopes | IT Admins |
Rules control which scopes a user can request based on their group membership.
Step 4: Set up group claims
By default, Okta doesn’t include groups in access tokens. Add a claim:
- Go to your authorization server’s Claims tab
- Click Add Claim
| Field | Value |
|---|---|
| Name | groups |
| Include in token type | Access Token |
| Value type | Groups |
| Filter | Matches regex .* (or filter to specific groups) |
| Include in | Any scope |
This adds the user’s Okta groups to their JWT, which ACP can use for role-based governance.
Step 5: Configure ACP
In your ACP dashboard, go to Settings → Identity Providers and enter:
| Field | Value |
|---|---|
| Issuer | https://your-org.okta.com/oauth2/your-auth-server-id |
| Audience | https://api.makeagents.run/your-slug |
| JWKS URI | Leave blank (auto-discovered from issuer) |
| Scope Claim | scp |
| Role Claim | groups |
| Tenant Claim | (optional — see multi-tenant section below) |
Okta claim mapping
Okta uses different claim names than Auth0. Here’s how they map to ACP:
| Okta Claim | ACP Field | Example |
|---|---|---|
sub |
identity.sub |
00u1a2b3c4d5e6f7g8 |
iss |
identity.issuer |
https://your-org.okta.com/oauth2/default |
scp |
identity.scopes |
["openid", "salesforce:read"] |
groups |
identity.roles |
["Sales Team", "Engineering"] |
email |
identity.email |
alice@acme.com |
name |
identity.name |
Alice Chen |
Note: Okta uses scp (array) for scopes, while Auth0 uses scope (space-delimited string). ACP normalizes both formats.
Step 6: Configure tool scopes
In Policies → Tool Scopes, map scopes to tools:
{
"salesforce.query": ["salesforce:read"],
"salesforce.createRecord": ["salesforce:write"],
"github.listRepos": ["github:read"],
"github.createIssue": ["github:write"]
}
When a user calls a tool, ACP checks their JWT’s scp claim against the required scopes. Missing scopes return 403 Insufficient scope.
Multi-tenant with Okta
If you manage multiple organizations, you can add a custom claim to carry the tenant context:
- Add a custom user attribute in Directory → Profile Editor (e.g.
tenant_id) - Add a claim to your authorization server that maps to this attribute
Set the Tenant Claim in ACP to match your claim name. ACP uses this for tenant isolation — users in one tenant can’t see another tenant’s data.
Troubleshooting
“Invalid token: unexpected iss claim”
Okta authorization server URLs include the server ID: https://your-org.okta.com/oauth2/aus1234567. Make sure the issuer in ACP matches exactly — including whether you’re using the default server (/oauth2/default) or a custom one.
“Insufficient scope” The user’s JWT doesn’t include the required scope. Check: (1) the scope exists on the authorization server, (2) the access policy rule grants that scope to the user’s group, (3) the client is requesting the scope during authentication.
“Groups claim missing” You need to explicitly add a groups claim to your authorization server (Step 4). Okta doesn’t include groups by default.
“Token expired” Okta’s default access token lifetime is 1 hour. You can adjust this in your access policy rules under Token Lifetime.