OIDC Integration Guide
Beta — Sandbox / Test environment only
The OIDC flow is currently in beta. It is only available in the test/sandbox environment (https://test.eideasy.com). Production support is not yet available. Do not use this flow in production applications until general availability is announced.
This guide walks you through a complete integration with the eID Easy OpenID Connect provider.
Before you start
Make sure you have the following ready:
- Your
client_idfrom the eID Easy admin panel - Your registered
redirect_uri - A decision on which token endpoint authentication method to use:
private_key_jwt
- For
private_key_jwt: your private key and a registered public key or JWKS URL
Registering your public key
Send us your public JWKS URL or the public key as a JWKS JSON object so we can register it for your client.
Environments
| Environment | Base URL |
|---|---|
| Test (default) | https://test.eideasy.com |
| Production (coming soon) | https://id.eideasy.com |
All OIDC endpoint paths are identical between environments. Only the base URL changes.
What is supported
- Flow: Authorization Code Flow only (
response_type=code) - Token endpoint authentication:
private_key_jwt - Signing algorithm: RS256
- Scopes:
openid,profile,pid(for verified wallet identity claims) - Identity wallets: Austria EUDI Wallet / Valera (
at-eudi-wallet-login), with more coming
If you have not yet obtained API credentials, follow the API credentials guide first.
Discovery
eID Easy publishes a standard OIDC discovery document. Always start here — it is the authoritative source for all endpoint URLs:
https://test.eideasy.com/.well-known/openid-configuration
The discovery document advertises these key endpoints:
| Endpoint | URL |
|---|---|
| Issuer | https://test.eideasy.com |
| Authorization endpoint | https://test.eideasy.com/oidc/oauth/authorize |
| Token endpoint | https://test.eideasy.com/oidc/oauth/token |
| JWKS URI | https://test.eideasy.com/.well-known/jwks.json |
Supported OIDC profile
| Requirement | Value |
|---|---|
| Supported flow | Authorization Code Flow only |
response_type | code |
response_mode | query |
| Token endpoint auth method | private_key_jwt (recommended) |
Signing algorithm for private_key_jwt | RS256 |
| ID token signing algorithm | RS256 |
Step 1 — Start the authorization request
Redirect your user to the authorization endpoint:
GET https://test.eideasy.com/oidc/oauth/authorize
Required parameters
| Parameter | Description |
|---|---|
response_type | Always code |
client_id | Your registered client ID |
redirect_uri | Your registered redirect URI |
scope | Space-separated list of scopes; must include at least openid |
state | A unique, unpredictable value to prevent CSRF attacks |
nonce | A unique value tied to this session; included in the ID token for replay protection |
Scopes
| Scope | Description |
|---|---|
openid | Required for any OIDC request |
profile | Standard profile claims (name, given_name, family_name, birthdate). Returned for all supported methods. |
pid | Verified identity claims from supported wallets (see Wallet identity claims) |
TIP
When the profile scope is requested, standard profile claims are always returned for all supported methods. The list of supported methods will be expanded and documented over time.
Example request
GET /oidc/oauth/authorize?
response_type=code&
client_id=your-client-id&
redirect_uri=https%3A%2F%2Fyour-app.example.com%2Fcallback&
scope=openid%20profile%20pid&
state=9f4c8e2d1a&
nonce=2b7f1b4e65 HTTP/1.1
Host: test.eideasy.com
Step 2 — Handle the authorization response
After the user authenticates, eID Easy redirects them back to your redirect_uri with an authorization code:
HTTP/1.1 302 Found
Location: https://your-app.example.com/callback?code=SplxlOBeZQQYbYS6WxSbIA&state=9f4c8e2d1a
Before proceeding:
- Verify that the
statevalue matches what you sent in Step 1 - Extract the
codevalue - Exchange the code at the token endpoint (Step 3)
Step 3 — Exchange the code at the token endpoint
Send a POST request to:
POST https://test.eideasy.com/oidc/oauth/token
Build your client assertion JWT
Your client_assertion must be a JWT signed with your registered private key using RS256.
JWT header:
{
"alg": "RS256",
"kid": "your-key-id",
"typ": "JWT"
}
JWT claims:
{
"iss": "your-client-id",
"sub": "your-client-id",
"aud": "https://test.eideasy.com/oidc/oauth/token",
"jti": "4d0f3a90-c7a1-4f96-8b14-1d3eb3a3a001",
"iat": 1776900000,
"exp": 1776900300
}
| Claim | Rule |
|---|---|
iss | Set to your client_id |
sub | Set to your client_id |
aud | Set to the full token endpoint URL |
jti | Must be unique per assertion (use a UUID) |
exp | Short-lived; no more than 5 minutes after iat |
WARNING
The aud claim must exactly match the token endpoint URL. An incorrect value is one of the most common causes of invalid_client errors.
Token request
POST /oidc/oauth/token HTTP/1.1
Host: test.eideasy.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=SplxlOBeZQQYbYS6WxSbIA&
redirect_uri=https%3A%2F%2Fyour-app.example.com%2Fcallback&
client_id=your-client-id&
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
client_assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6InlvdXIta2V5LWlkIiwidHlwIjoiSldUIn0...
Required token request parameters
| Parameter | Description |
|---|---|
grant_type | Always authorization_code |
code | The authorization code from Step 2 |
redirect_uri | Must match the value used in Step 1 |
client_id | Your registered client ID |
client_assertion_type | Always urn:ietf:params:oauth:client-assertion-type:jwt-bearer |
client_assertion | Your signed JWT (see above) |
Step 4 — Process the token response
A successful response:
{
"access_token": "<access_token>",
"id_token": "<id_token>",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid profile pid"
}
After receiving the response:
- Store the tokens securely
- Validate the ID token (Step 5)
- Optionally call the UserInfo endpoint with the access token
Step 5 — Validate the ID token
Fetch the signing keys from the JWKS endpoint:
https://test.eideasy.com/.well-known/jwks.json
Your validation must check all of the following:
| Check | Expected value |
|---|---|
| Signature | Valid, using a key from the JWKS URI |
iss | https://test.eideasy.com |
aud | Contains your client_id |
exp | Has not passed |
nonce | Matches the value from your authorization request |
| Signing algorithm | RS256 |
DANGER
Never accept an ID token without validating all of the above. Skipping signature or nonce validation opens your application to security vulnerabilities.
Wallet identity claims
If you request the pid scope, the ID token may include a verified_claims object conforming to the OpenID Identity Assurance spec with government-issued identity data.
Supported wallet methods
| Method code | Wallet | Guide |
|---|---|---|
at-eudi-wallet-login | Austria EUDI Wallet (Valera) | Austria Valera EUDI Wallet |
TIP
verified_claims is only present when the user authenticated through a wallet method that returns verified data. Other methods return standard profile claims without verification metadata. See the individual wallet guides above for the exact claims structure and integration steps.
UserInfo endpoint
Currently unavailable
The UserInfo endpoint is not yet available. Use the claims in the ID token instead.
The discovery document advertises support for the following claims: sub, name, family_name, given_name, birthdate, email, phone_number, document_number, id_expiry_date, language, and verified_claims.
Error handling
eID Easy returns standard OAuth 2.0 error responses.
{
"error": "invalid_client",
"error_description": "Client authentication failed"
}
Common error causes
| Error | Common causes |
|---|---|
invalid_client | Wrong or missing client_assertion, unknown kid, or a client auth method not enabled for your application |
invalid_grant | Authorization code expired, already used, or redirect_uri does not match |
unauthorized_client | Client not permitted to use the requested grant type |
invalid_request | Missing or malformed parameters |
Quick reference
| Item | Value |
|---|---|
| Discovery document | https://test.eideasy.com/.well-known/openid-configuration |
| Authorization endpoint | https://test.eideasy.com/oidc/oauth/authorize |
| Token endpoint | https://test.eideasy.com/oidc/oauth/token |
| JWKS URI | https://test.eideasy.com/.well-known/jwks.json |
| Supported flow | Authorization Code Flow only |
response_type | code |
| Token auth | private_key_jwt |
| Minimum scopes | openid profile |
| Wallet verified-claims scope | pid |
| Signing algorithm | RS256 |
Integration checklist
- [ ] Load metadata from the discovery URL
- [ ] Redirect the user with
response_type=code - [ ] Include
stateandnoncein the authorization request - [ ] Request
openid profile(and optionallypidfor wallet claims) - [ ] Verify
stateon callback - [ ] Exchange the code using
private_key_jwtat the token endpoint - [ ] Set the correct
audin the client assertion JWT - [ ] Validate the ID token: signature,
iss,aud,exp, andnonce