Technical Users and Delegation
Overview
Non-Core services — Bridge, BFF, WRPR, and any custom services you integrate — do not interact with Core as human users. Instead, each service authenticates as a technical user: a non-human actor with its own IAM identity and a defined set of permissions within the platform.
Both the service's permissions and the conditions under which it can exercise them are defined by you as the integrator. This doc explains how technical user authentication works and how to configure permissions correctly, including delegation.
How it works
Each non-Core service authenticates with your IAM provider as a technical user and exchanges the resulting authorization token with the STS for an application token. The service presents this token when calling Core.
The STS supports two token types depending on the operation:
- App token: issued to the service based on its own IAM role and permissions.
- Delegated token: issued to the service on behalf of a user. The
token carries the user's identity as its subject and identifies the
service in an
actclaim, preserving user attribution. Delegated tokens are ephemeral; the duration is configurable at the STS level.
For many calls driven by an end user, the user's own token is sufficient and the service needs no permissions of its own. See Configuring permissions for when to grant a service explicit permissions.
Permission patterns
Technical users require explicit permissions in two situations: when a service performs operations independently of a user, and when delegation is required. The following examples cover three use cases you may encounter. For UI and API instructions for each of these patterns, see Setup: Map IAM roles and permissions.
Service permission
For operations a service performs independently of any user, create a role with the required permissions and no delegation configuration.
When WRPR runs a cron job to check Access or Registration Certificate
status, it needs the permission TASK_CREATE. No user is involved.
Delegated permission, any user
For operations where a service acts on behalf of any authenticated user, enable delegation with no required user permissions. The service must present a user token, but that token needs no specific permissions.
When the BFF issues login credentials on behalf of users signing in to the Desk, it needs permission to retrieve credential schemas, and retrieve, issue, share, and revoke credentials. But any authenticated user should be able to trigger this flow regardless of their own permissions regarding credentials.
Delegated permission, conditional
For operations where a service should only act on behalf of users with specific permissions, enable delegation and specify the required user permissions. This is the most restrictive pattern and the most common for least-privilege configurations.
Consider giving an end user the ability to create an Access Certificate via WRPR, which calls the Core Signature service for signing. You do not want the end user to have direct access to the Core Signature service — this would let them bypass WRPR's validations and create arbitrary signatures. You also do not want to give WRPR blanket permission to call the Core Signature service without user attribution.
Instead:
- Grant the user permission to create Access Certificates on WRPR
(
ACCESS_CERTIFICATE_CREATE). - Grant WRPR permission to sign Access Certificates
(
ACCESS_CERTIFICATE_SIGN), but only when it holds a delegated token representing a user with Access Certificate creation permission.
The STS issues a delegated token scoped to that specific operation, valid only for a configurable short duration. Neither the user nor WRPR can exceed their intended scope.
Setup
1. Configure delegated token duration
Set the duration of delegated tokens produced by the STS:
sts:
token:
delegatedTokenValidity: 30 # In seconds
2. Configure IAM credentials per service
Each service needs credentials to authenticate with your IAM provider. How you create and manage those credentials depends on your IAM setup — refer to your IAM provider's documentation for creating service accounts or clients. Once you have credentials, configure each service as follows:
| Service | Config key | Description |
|---|---|---|
| BFF | sts.iam.loginCredential.clientId | IAM client ID |
| BFF | sts.iam.loginCredential.clientSecret | IAM client secret |
| WRPR | auth.technicalUserCredentials.clientId | IAM client ID |
| WRPR | auth.technicalUserCredentials.clientSecret | IAM client secret |
| WRPR | auth.technicalUserCredentials.iamTokenEndpointUrl | IAM token endpoint URL |
| WRPR | auth.technicalUserCredentials.stsTokenEndpointUrl | STS token endpoint URL |
| Bridge | auth.iamTechnicalClient.client-id | IAM client ID |
| Bridge | auth.iamTechnicalClient.client-secret | IAM client secret |
| Bridge | auth.iamTechnicalClient.iss | IAM issuer URL |
3. Map IAM roles and permissions
For each service, you need to recreate its IAM role within Procivis One and map it to the permissions that service requires. This involves three things: creating a role (or roles) with the appropriate permissions, creating an access control entry for the service's IAM role, and assigning the Procivis One role(s) to it.
For UI instructions, see Mapping an IAM Role to System Permissions.
Service permission
For a service that acts independently of any user:
POST /api/sts/role/v1
{
"name": "wrpr-independent",
"permissions": [
"TASK_CREATE"
]
}
Delegated permission, any user
For a service that acts on behalf of any authenticated user:
POST /api/sts/role/v1
{
"name": "bff-login-credential",
"permissions": [
"CREDENTIAL_DETAIL",
"CREDENTIAL_CREATE",
"CREDENTIAL_REVOKE",
"CREDENTIAL_SHARE",
"CREDENTIAL_SCHEMA_DETAIL"
],
"userDelegation": {
"enabled": true
}
}
Delegated permission, conditional
For a service that acts on behalf of users with specific permissions:
POST /api/sts/role/v1
{
"name": "wrpr-access-certificate",
"permissions": [
"ACCESS_CERTIFICATE_SIGN"
],
"userDelegation": {
"enabled": true,
"requiredPermissions": [
"ACCESS_CERTIFICATE_CREATE"
]
}
}
Assign roles to the service's IAM role
Once you have created all necessary roles, register the service's IAM role and assign the roles to it. The IAM role name must match exactly what is configured in your IAM system:
POST /api/sts/iam-role/v1
{
"description": "Wallet-Relying Party Registry service technical user.",
"name": "WRPR_SERVICE",
"organisationRoles": {
"{{ORGANIZATION-ID}}": [
"{{ROLE-ID}}"
]
}
}
A service may be assigned multiple roles across one or more organizations.