OAuth2 Authorization Server
The OAuth2 AS service provides a standards-compliant authorization server that you can embed in your Ktor application. It handles the protocol mechanics of OAuth2 and OpenID Connect while delegating authentication and consent to your application through the UserAuthenticationProvider and ConsentProvider interfaces. You provide the UI and the user database; the service takes care of the rest.
Supported Standards
| Standard | Description |
|---|---|
| RFC 6749 | OAuth 2.0 Authorization Framework |
| RFC 7636 | Proof Key for Code Exchange (PKCE) |
| RFC 8693 | OAuth 2.0 Token Exchange |
| RFC 9449 | Demonstrating Proof of Possession (DPoP) |
| RFC 9126 | Pushed Authorization Requests (PAR) |
| RFC 7662 | Token Introspection |
| RFC 7009 | Token Revocation |
| RFC 8414 | Authorization Server Metadata |
| OpenID Connect Core | ID Tokens, UserInfo, JWKS |
| draft-ietf-oauth-attestation-based-client-auth | Attestation-based client authentication |
Key Endpoints
| Method | Path | Description |
|---|---|---|
GET/POST | /authorize | Authorization endpoint for the code flow. Parses the request, validates the client and redirect URI, then hands control to your authentication and consent logic. After the user approves, it generates an authorization code and redirects back. |
POST | /token | Token endpoint for all grant types: authorization code, refresh token, client credentials, token exchange (RFC 8693), and pre-authorized code (OID4VCI). Follows a parse-then-branch pattern internally. |
POST | /introspect | Token introspection (RFC 7662). Accepts an access or refresh token and returns its active/inactive status along with associated metadata (scopes, subject, expiration). |
POST | /revoke | Token revocation (RFC 7009). Accepts a token and invalidates it. Responds with 200 regardless of whether the token existed, per the spec. |
POST | /par | Pushed Authorization Requests (RFC 9126). The client posts its authorization parameters to this endpoint first, receives a request_uri, then redirects the user to /authorize with that URI instead of inline parameters. |
GET | /.well-known/oauth-authorization-server | Server metadata (RFC 8414). Returns a JSON document describing supported grant types, scopes, endpoints, signing algorithms, and other capabilities. |
GET | /.well-known/jwks.json | JSON Web Key Set. Returns the public keys used by the server for signing tokens. Clients and resource servers use this to verify token signatures. |
Including in Your Server
dependencies {
implementation("com.sphereon.idk:services-oauth2-as-rest:0.25.0")
}
The OAuth2 AS adapter registers itself in the DI graph and is picked up automatically by installUniversalHttpAdapters().
Configuration
The authorization server is configured through a combination of the IDK property system and provider interfaces:
- Server metadata: Set the issuer identifier, supported scopes, grant types, and response types through YAML configuration or programmatically via
AuthorizationServerMetadata. - Client registration: Implement the
ClientStoreinterface to provide client records (client ID, secret, redirect URIs, allowed grant types). The IDK ships an in-memory implementation for development. - Token settings: Configure access token TTL, refresh token TTL, and ID token TTL.
- Signing keys: The server uses the
KeyManagerServiceto sign tokens. Configure which key alias or key ID the server uses for JWT signing. - DPoP: DPoP support is enabled automatically when clients include a
DPoPheader. No separate configuration is needed. - PKCE: PKCE is enforced by default for public clients and optional for confidential clients. You can make it mandatory for all clients via configuration.
The core API follows a parse, verify, create pattern: you parse raw HTTP input into a typed request, verify it (checking clients, scopes, PKCE, etc.), then create the output (tokens, codes, responses). The gaps between these steps are where your application-specific logic lives: authenticating the user, collecting consent, or enforcing custom policies.
See Authorization Server for the full API reference, including code examples for each grant type.
Docker
Each service ships with a Dockerfile and docker-compose configuration in its container/ directory.
Building the image
# Build the fat JAR first
./gradlew :services-oauth2-as-rest:buildFatJar
# Build the Docker image
docker compose -f services/oauth2-as/container/docker-compose.yaml build
Running with Docker Compose
docker compose -f services/oauth2-as/container/docker-compose.yaml up
The service starts on port 8080. Configuration is loaded from container/config/ inside the image. Override settings via environment variables in a .env file next to the docker-compose.yaml.
Image details
| Property | Value |
|---|---|
| Base image | eclipse-temurin:21-jre |
| Docker image | sphereon/idk-oauth2-as:latest |
| Exposed port | 8080 |
| Config location | /app/config/ |
Next Steps
- Services Overview for an introduction to all available IDK services and the
CommandBackedHttpAdapterpattern - Authorization Server Guide for the full API reference and code examples for each grant type
- OID4VCI Issuer to see how credential issuance integrates with the authorization server
- Ktor Integration for details on installing and configuring the
KotlinInjectPlugin