---
title: "OIDC Unique Sub Auth"
description: "With this authentication strategy you can simply provide a valid JWT with a unique subject claim and the wallet-api will create or login a user to the associated wallet account. This way you can use your own…"
stack: "Community Stack (open source) — version 0.21.0"
stack_version: "0.21.0"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/community-stack/wallet/authentication/jwt-oidc/oidc-unique-sub-auth
generated: 2026-07-20
---
# OIDC Unique Sub Auth

With this authentication strategy you can simply provide a valid JWT with a unique subject claim and the wallet-api
will create or login a user to the associated wallet account. This way you can use your own authentication
flows
and just provide the result (valid JWT) to the walt.id system. To verify the JWT provided is coming from your auth
server, you need to configure the relevant OIDC endpoints via a config.

## Config

In `waltid-wallet-api/config/oidc.conf` update the value `oidcRealm` and `oidcJwks` with your auth server values.
Below you find an example using Keycloak:

```json [oidc.conf]
enableOidcLogin = true
providerName = keycloak
# Enter the realm URL
oidcRealm = "https://keycloak.walt-test.cloud/realms/waltid-keycloak-ktor"

# JWKS (to verify access keys the user claims to received through OIDC server)
oidcJwks = "${oidcRealm}/protocol/openid-connect/certs"
authorizeUrl = "${oidcRealm}/protocol/openid-connect/auth"
accessTokenUrl = "${oidcRealm}/protocol/openid-connect/token"
logoutUrl = "${oidcRealm}/protocol/openid-connect/logout"
clientId = "waltid_backend_localhost"
clientSecret = "Xp8fJG5RTtj6lYUlqqIG57iovXMvfD5j"

# JWKS is cached: jwksCache = {
cacheSize = 10
cacheExpirationHours = 24
rateLimit: {
bucketSize: 10
refillRateMinutes: 1
}
}

```

## Create / Login

When using the OIDC unique subject authentication strategy, the login endpoint creates a new account if the `subject`
claim in the JWT is not already associated with an account. Otherwise, it simply logs in the user.

**Option: CURL**

[API Reference](https://wallet.demo.walt.id/swagger/index.html#/Authentication/post_wallet_api_auth_login)

```bash
curl -X 'POST' \
 'http://0.0.0.0:7001/wallet-api/auth/login' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "oidc-unique-subject",
  "token": "<JWT>"
}'
```

**Body Parameters**

```json
{
  "type": "{type}"
  "token": "string"
}
```

- `type`: _[string]_ - type of the authentication strategy, e.g. `oidc-unique-subject`
- `token`: _[string]_ - the JWT from your OIDC authentication system holding a unique `subject` claim.

**Example Response**
<br />
Now a session is automatically created for cookie-based authentication. For Bearer Token Authentication, the `token`
returned
must be provided in the header for each request that needs authentication. Refer to
the [overview section](https://docs.walt.id/community-stack/wallet/authentication/overview.md#cookie-based-authentication) for more details.

```json
{
  "token": "KL-a_dk1qO8moCX4gxaGfb7_TS8RK-JWVKZk9BBP0-s",
  "id": "018045e5-942c-4362-b535-658c4dd581ef",
  "username": "c9234234234234-234234234-203942fasdfs"
}
```

## Logout

**Option: CURL**

[API Reference](https://wallet.demo.walt.id/swagger/index.html#/Authentication/post_wallet_api_auth_logout)

Deletes the session/invalidates the token.

```bash
curl -X 'POST' \
  'http://0.0.0.0:7001/wallet-api/auth/logout' \
  -H 'accept: */*' \
  -d ''
```
