Authorization-server configuration
An authorization server (AS) is the OAuth/OIDC control plane used by a wallet, application, or credential issuer. It is not the credential issuer itself. This guide explains the options that affect an AS resource and the order in which those options become usable.
Audience: tenant administrators and developers automating tenant configuration.
Prerequisites
Complete these guides first:
- Platform foundations and authentication boundaries: obtain a token for your service client, a tenant confidential client. AS administration uses that token; it never uses the platform operator token or a wallet token.
- Tenant provisioning and confidential-client access: create or select the tenant and record its tenant id, subdomain, and hosted AS URL.
- Credential designs and claims: when the AS will be used by an issuer.
- Issuer configuration: complete this after the AS exists when you need to bind an AS to an issuer. The issuer and AS are separate guides.
Choose the resource type
| Choice | Use it when | Lifecycle |
|---|---|---|
| Hosted | The tenant operates the authorization endpoints and token service | Create, configure metadata, activate, register clients and identities |
| External | The tenant delegates authorization to an existing upstream server | Create from discovery, validate, refresh when it changes, activate |
| Federation binding | A hosted server must trust or consume an external federation provider | Create disabled, validate, enable only after validation succeeds |
A hosted AS is enough for the normal developer journey. Do not create an external resource merely because a credential issuer exists; the issuer selects an AS later through an explicit binding.
Hosted AS options
| Option | Meaning | Guidance |
|---|---|---|
displayName | Human-readable operator label | Keep it stable; it is not an API identifier. |
slug | Hosted route and discovery namespace | Use a DNS-safe stable value. Changing it changes public URLs. |
| public origin | URL in discovery and token claims | Use the tenant public HTTPS origin, never an internal service URL. |
| metadata | Advertised endpoints, scopes, grants, and capabilities | Replace only when the deployment supports the advertised behavior. |
| status | Draft, active, suspended, or decommissioned | Activate only after metadata and signing material validate. |
| default | Whether this is the tenant’s default hosted AS | Keep exactly one default for the normal journey. |
A hosted wallet AS in FEDERATED_ONLY mode still requires a slug: it hosts the wallet-facing
authorization server and sends user authentication upstream. A fully external AS must omit slug;
a supplied string, including an empty string, is rejected.
The create response returns the administration UUID. Use that UUID in every later API path; never reconstruct it from the slug or issuer URL.
Hosted AS: a complete configuration recipe
The tenant configuration API exposes the hosted AS lifecycle through these operations:
For the normal developer journey create one hosted AS per tenant. The values below are functional settings, not display-only metadata:
{
"slug": "acme-login",
"displayName": "Acme login",
"issuer": "https://acme.example.com/as/acme-login",
"deployment": "HOSTED",
"authenticationMode": "HYBRID",
"purposes": ["GENERAL", "CREDENTIAL_ISSUANCE", "WALLET_LOGIN"],
"allowedGrantTypes": ["authorization_code", "refresh_token"]
}
slug becomes part of authorization, discovery, JWKS, and login URLs. issuer must be the public
HTTPS issuer URL wallets and browsers use, <tenant origin>/as/<slug>, never an internal hostname.
authenticationMode
controls which authentication mechanisms the AS can use; it does not create clients or users.
purposes (GENERAL, CREDENTIAL_ISSUANCE, WALLET_LOGIN) record what the server is for;
they do not gate selection. An issuer can bind any active server of the tenant whose
allowedGrantTypes include an OID4VCI grant. allowedGrantTypes must include each
grant used by the issuer, but enabling a grant here does not enable it on a client.
After POST /api/platform/config/v1/tenants/{tenantId}/authorization-servers, save the response
id as authorizationServerId and retain revision. Then GET the resource and PUT corrected
metadata if needed. For an EXTERNAL server only, POST /{authorizationServerId}/validate and
activate only after validation succeeds; HOSTED servers reject validation. Finally read discovery and JWKS through the tenant gateway; an HTTP 200 from the
admin API does not prove the public protocol endpoints work.
Client configuration is separate from AS configuration
Once the AS exists, inspect and register its clients with the tenant configuration operations:
For Postman or a backend service, create a confidential client with client_credentials, no redirect
URIs, explicit audiences, and an explicit authentication method:
{
"clientId": "acme-service",
"clientName": "Acme developer service",
"clientType": "confidential",
"enabled": true,
"grantTypes": ["client_credentials"],
"responseTypes": [],
"redirectUris": [],
"tokenEndpointAuthMethod": "client_secret_post",
"principalRoles": ["tenant-admin"],
"defaultAccessTokenAudience": "enterprise-platform",
"allowedAccessTokenAudiences": ["enterprise-tenant-kms", "enterprise-tenant-did", "enterprise-tenant-as", "enterprise-issuer", "enterprise-verifier"],
"clientCredential": {"method": "client_secret_post", "clientId": "acme-service", "secretValue": "<generated secret>"}
}
client_secret_post sends credentials in the form body. A client registered as
client_secret_basic must receive an HTTP Basic header. The methods are not interchangeable and
produce invalid_client when mismatched. You supply the secret once in
clientCredential.secretValue; it is stored through secret management and reads return only
clientCredential.secretReference, so keep your copy. Never reuse the platform operator secret.
Browser/native clients instead use authorization_code, exact
HTTPS redirect URIs, and PKCE S256; they must not receive client_credentials or a service role.
Create hosted identities only after the AS is active. Their account-action link/token is a one-time activation credential, not a platform or tenant access token.
Client options
| Client type | Typical use | Options that matter |
|---|---|---|
| Public | Browser or native app that cannot protect a secret | Client id, redirect URIs, response/grant types, scopes, and PKCE requirements. |
| Confidential | Backend service or Postman automation | Client id, authentication method, grants, scopes, redirect URIs, and a write-only secret. Store the secret immediately. |
| Operator/platform client | One-time administrative sign-in | Keep it separate from the tenant confidential client and never reuse it for tenant APIs. |
For this journey, register one confidential service client on the tenant hosted AS and use its
client_credentials secret to obtain a tenant token. This is the hand-off from bootstrap login
to repeatable API work.
Identity and external-discovery options
Hosted identities choose the account email/name, activation flow, role or group mapping, and enabled state. Activation is temporary bootstrap state; it does not replace the tenant service token.
External resources choose a public HTTPS discovery/issuer URL, client authentication metadata when needed, accepted scopes/grants, refresh policy, and activation state. Inspect the resolved issuer, authorization endpoint, token endpoint, supported grants, algorithms, and JWKS before activation. An HTTP 200 from discovery alone is not validation.
Federation bindings choose the provider, order, enabled state, and validation snapshot. Create them disabled, validate, and enable only if validation names the expected provider. Revalidate after any provider or discovery change.
Admin Console
Open Protocols > Authorization Servers. Work through the resource tabs in this order: Details, Metadata or Discovery, Clients, Identities, Federation, Validation, and Activation. The console should show the same UUID and effective values returned by REST. If a field is not visible, inspect the REST representation before assuming a default.
The Console sections map directly to ownership: Details owns slug, issuer, deployment and purposes; Capabilities/Grants owns protocol behavior; Clients owns grants, redirects, audiences and token authentication; Identities owns people; and Activation changes lifecycle. Do not fix issuer credential failures by changing client redirects, or browser login failures by changing credential claims.
Use the dedicated reference pages for the actual screens and fields: AS settings, AS grants, clients, and users. The corresponding deep links are:
#tenant={tenant}&surface=as&instance={authorizationServerId}&tab=settings§ion=tokens
#tenant={tenant}&surface=as&instance={authorizationServerId}&tab=clients
#tenant={tenant}&surface=as&instance={authorizationServerId}&tab=users
REST API
Use the tenant-scoped platform configuration API with the service client's token:
POST .../authorization-serverscreates hosted or external resources.GETandPUT .../authorization-servers/{id}read or replace metadata.- For
EXTERNALservers only,POST .../{id}/validateand.../{id}/discovery/refreshrun the external lifecycle; activate after validation. ActivateHOSTEDservers without validation. POST .../{id}/clientsregisters public or confidential clients.POST .../{id}/identitiescreates hosted identities, followed by one-time account actions.- Federation endpoints create, validate, enable, reorder, or delete bindings by UUID.
- Issuer binding endpoints select this AS for an issuer; they do not configure the AS.
Carry forward response-derived ids, revisions, client ids, and write-only secrets. Use revision/CAS fields where provided. Management endpoints use the service client's OAuth token; public discovery, metadata, JWKS, and authorization endpoints do not carry a management bearer token.
Postman correlation
In the canonical EDK Enterprise collection,
2. Tenant owner: create a service client finds the tenant default AS with 1. List authorization servers and registers the service client with 3. Create the service client. 3. Tenant APIs
then uses Postman's Client Credentials helper. Requests inherit its OAuth token without a bearer
variable. 3. Tenant APIs > Authorization server reads the authorization servers, their settings
and clients, and the OpenID configuration.
For upstream Keycloak sign-in, use 3. Tenant APIs > Keycloak wallet login (optional) > Set up the
wallet proxy. Run 2. Create the wallet proxy, 4. Register the wallet client, and
5. Register Keycloak, then validate and activate the external resource. Create, validate and
enable its federation binding, followed by 14. Allow the issuer to use the wallet proxy. The
default tenant AS remains local-only; the separate hosted proxy owns wallet tokens and redirects user
authentication to Keycloak.
Credential issuer and Define your own credential remain separate stages for issuer configuration and presentation. The federation guide explains the Keycloak callback, returned resource IDs and the subsequent authorization-code credential request. Use the discovered token endpoint, rather than deriving it from an issuer URL.
Binding an AS to an issuer
Configure and validate the AS first, then bind its UUID from the issuer. The effective selection order is credential-configuration override, issuer override, then issuer default. If a credential uses the wrong token endpoint, inspect those three levels and the published issuer metadata before changing URLs.