API Resources & Scopes
API Resources represent the protected APIs in your system. Each resource defines its own set of scopes (permissions) that can be assigned to roles.
Creating an API Resource
- Open the Admin Panel at
/admin - Navigate to your realm
- Go to API Resources > Create
- Fill in the fields:
- Name -- human-readable label (e.g. "Blog API")
- Indicator -- audience URI (e.g.
https://api.example.com). This value is used as theaudclaim in JWT tokens. - Access Token TTL -- token lifetime in seconds (default: 3600)
Adding scopes
After creating a resource, add scopes to define permissions:
- Open the API Resource
- Go to the Scopes section
- Click Add Scope
- Enter a name (e.g.
read:posts) and description
Naming convention
Use the action:entity pattern for clarity:
read:posts -- read blog posts
write:posts -- create/update blog posts
delete:posts -- delete blog posts
admin:users -- manage users
Requesting resource-scoped tokens
When requesting tokens, specify the resource parameter to indicate which API the token is for:
curl -X POST https://your-domain.com/oauth2/{realmUUID}/token \
-d grant_type=client_credentials \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_SECRET \
-d scope="read:posts write:posts" \
-d resource=https://api.example.com
The resulting JWT will have:
audset to the resource indicatorscopecontaining only the granted scopes for that resource
Built-in Management API
Every realm auto-creates a Management API resource. Its indicator is:
https://your-domain.com/api/v1/{realmUUID}
This resource comes with pre-defined scopes for managing users, applications, roles, resources, providers, and settings. See RBAC for the full scope list.
Validating scopes in your API
After verifying the JWT signature and expiration, check the scope claim:
const scopes = decodedToken.scope.split(' ');
if (!scopes.includes('read:posts')) {
return res.status(403).json({ error: 'Insufficient scope' });
}
See Protect Your API for complete examples.