Set up identity providers and resource servers
Before clients can register or obtain tokens you need to establish the trust infrastructure: identity providers (for user-facing flows) and resource servers (the APIs tokens are issued for).
1.1 Identity providers
An Identity Provider (IdP) is an external OIDC provider that the AS federates with. The AS acts as an OIDC Relying Party to the IdP during the authorization code flow.
Fields:
| Field | Description |
|---|---|
idpId | Stable admin-assigned key (e.g. corporate-idp). Used in policy as subject.idp. |
issuer | OIDC issuer URL. Must be unique per tenant. |
name | Display name |
clientId | The AS's client_id at this IdP |
clientSecret | The AS's client_secret at this IdP |
scopes | Scopes to request from this IdP (e.g. ["openid", "profile", "email"]) |
authorizationEndpoint | IdP's authorization endpoint |
tokenEndpoint | IdP's token endpoint |
userinfoEndpoint | IdP's userinfo endpoint |
jwksUri | IdP's JWKS URI (used to verify ID tokens) |
tenantId | Scope to tenant; null = platform-wide |
Register an IdP:
curl -X POST https://pbac.example.com/admin/api/identity-providers \
-H "X-Admin-API-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"idpId": "corporate-idp",
"issuer": "https://idp.example.com",
"name": "Corporate IdP",
"clientId": "pbac-relying-party",
"clientSecret": "secret",
"scopes": ["openid", "profile", "email"],
"authorizationEndpoint": "https://idp.example.com/oauth2/authorize",
"tokenEndpoint": "https://idp.example.com/oauth2/token",
"userinfoEndpoint": "https://idp.example.com/oauth2/userinfo",
"jwksUri": "https://idp.example.com/.well-known/jwks.json"
}'
List IdPs:
curl https://pbac.example.com/admin/api/identity-providers \
-H "X-Admin-API-Key: $ADMIN_KEY"
Update or delete:
# Update
curl -X PUT https://pbac.example.com/admin/api/identity-providers/corporate-idp \
-H "X-Admin-API-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{ "issuer": "https://idp.example.com", "name": "Updated Name", "enabled": true }'
# Delete
curl -X DELETE https://pbac.example.com/admin/api/identity-providers/corporate-idp \
-H "X-Admin-API-Key: $ADMIN_KEY"
1.2 IdP selection policy
The AS uses OPA policy data to route authorize requests to the right IdP. Configure in the user.idp_selection block of your policy data (see Policy Data Guide for how to update policy data):
{
"oauth": {
"user": {
"idp_selection": {
"default_idp": "corporate-idp",
"resource_to_idp": {
"https://api.example.com/fhir": "health-idp"
},
"resource_type_to_idp": {
"urn:example:SensitiveRecord": "mfa-idp"
},
"acr_to_idp": {
"urn:acr:mfa": "mfa-idp"
}
}
}
}
}
Priority: acr_to_idp > resource_to_idp > resource_type_to_idp > default_idp
1.3 Resource servers
A resource server (RS) is an API that accepts tokens issued by this AS. It is identified by a resource indicator — a URI used in RFC 8707 resource parameters.
The AS uses the resource server DB records at token time to resolve resource → resource_type (longest-prefix match). If there is no matching RS record, a token request with that resource will fail with invalid_target unless the caller supplies a resource_type hint.
Resource servers are auto-created by DCR when the OPA register policy returns is_resource_server: true with granted_resource_indicators. Use the Admin API to pre-create, inspect, or manage them independently:
curl -X POST https://pbac.example.com/admin/api/resource-servers \
-H "X-Admin-API-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"resourceIndicator": "https://api.example.com/fhir",
"name": "FHIR API",
"description": "Clinical data API",
"enabled": true
}'
The response includes the numeric id needed to associate resource types and resource instances.
Use https://api.example.com/fhir/* to match any sub-path. The AS uses longest-prefix matching, so more specific indicators win over wildcards.
Associate resource types with an RS is handled automatically during DCR or via the resource type admin API. An RS can serve multiple resource types.
Resource types
Resource types classify the data that RSes host. Each type carries a set of valid scopes.
Create a resource type:
curl -X POST https://pbac.example.com/admin/api/resource-types \
-H "X-Admin-API-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"typeUri": "urn:example:Patient",
"name": "Patient Record",
"description": "Clinical patient record",
"scopes": ["read", "write", "delete"],
"enabled": true
}'
| Field | Description |
|---|---|
typeUri | Unique URI identifying the type (e.g. urn:example:Patient) |
name | Display name |
scopes | Scopes valid for this type |
parentTypeId | Optional parent type for subtyping hierarchies |
AS-hosted resource types (built-in; no need to create):
| Type URI | Valid Scopes | Grants access to |
|---|---|---|
urn:as:userinfo | openid, profile, email | /userinfo endpoint |
urn:as:introspect | uma_protection, introspection | /introspect endpoint |
urn:as:authzen | authzen | /access/v1/evaluation endpoint |
Resource instances
A resource is a specific instance hosted by an RS with a given type.
curl -X POST https://pbac.example.com/admin/api/resources \
-H "X-Admin-API-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"resourceServerId": 1,
"resourceTypeId": 2,
"resourceIdentifier": "patient/123",
"scopes": ["read", "write"]
}'
| Field | Description |
|---|---|
resourceServerId | FK to resource_server |
resourceTypeId | FK to resource_type |
resourceIdentifier | RS-local identifier (e.g. patient/123) |
ownerSubjectId | Optional: FK to subject if user-owned |
scopes | Allowed scopes on this instance (subset of type scopes) |
Subjects
Subjects are the user/human principals that appear in user-delegated tokens. They are created automatically on first authorization code flow, but can be pre-registered:
curl -X POST https://pbac.example.com/admin/api/subjects \
-H "X-Admin-API-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"subjectId": "alice@example.com",
"identityProviderId": 1
}'
Next steps
- Policy Data — Configure denylists, entitlements, IdP selection, and trust issuers
- Registering Software — Register clients via DCR with software statements
- Getting Tokens — Request access tokens using all supported grant types