No description
  • EJS 44.8%
  • JavaScript 34.2%
  • CSS 19.8%
  • Dockerfile 1.2%
Find a file
2026-04-02 19:36:45 +02:00
app Init id-austria test repository 2026-04-02 19:36:45 +02:00
.dockerignore Init id-austria test repository 2026-04-02 19:36:45 +02:00
.env.example Init id-austria test repository 2026-04-02 19:36:45 +02:00
docker-compose.yml Init id-austria test repository 2026-04-02 19:36:45 +02:00
README.md Init id-austria test repository 2026-04-02 19:36:45 +02:00

ID Austria OIDC Test Client

A minimal Node.js OIDC test client for the ID Austria reference environment (idp.ref.id-austria.gv.at).

Implements the Authorization Code Flow, displays all returned claims (including Austria-specific claims like bPK, eIDAS level, and PVP version), and handles iOS Safari's ITP cookie restrictions via a state-encoded session strategy.

Features

Feature Details
Flow Authorization Code (response_type=code)
Auth method client_secret_post — required by ID Austria
client_id format URL (required by ID Austria)
Scopes openid profile
Logout RP-Initiated Logout via end_session_endpoint
Session strategy State-encoded (cookie-independent, iOS Safari ITP-compatible)
Claims display All ID Austria claims: bPK, eIDAS level, PVP version, representation/Vollmacht claims
Debug endpoint /debug/discovery — OIDC Discovery metadata as JSON

ID Austria Specifics

  • client_secret is mandatory — even without PKCE. Public clients are not supported.
  • client_id must be a URL — e.g. https://idaustria-test.example.com
  • request_uri is not supported — results in an error
  • response_mode=form_post is not supported — results in an error
  • sub is transient — use the bPK claim for persistent user identification
  • No nonce in id_token — do not send a nonce in the authorization request
  • Discovery URL (reference env): https://idp.ref.id-austria.gv.at/.well-known/openid-configuration

iOS Safari / App2App (Simplified Continuation)

Standard session-over-cookie fails on iOS Safari due to ITP: the callback request arrives without the session cookie, breaking the OIDC state check. This client works around this by encoding the session ID (HMAC-secured with a nonce) inside the state parameter. The callback reconstructs the session from state directly, without relying on a cookie.

Quick Start

1. Register in IDA-SPR

Go to the IDA-SPR and create a new service provider:

Field Value
Application identifier (client_id) https://your-domain.example.com
redirect_uri https://your-domain.example.com/callback
post_logout_redirect_uri https://your-domain.example.com/
Test identities enable

Save the generated client_secret immediately — it is shown only once.

2. Configure

cp .env.example .env

Edit .env:

  • Set APP_DOMAIN to your domain (without https://)
  • Set OIDC_CLIENT_SECRET to the secret from IDA-SPR
  • Generate SESSION_SECRET with openssl rand -hex 32

3. Run

With Traefik (the default docker-compose.yml includes Traefik labels for automatic TLS via Let's Encrypt):

docker compose up -d
docker compose logs -f

Standalone (without Traefik, for local development):

docker build -t idaustria-client ./app
docker run --rm -p 3000:3000 \
  -e APP_DOMAIN=localhost:3000 \
  -e OIDC_CLIENT_SECRET=your_secret \
  -e SESSION_SECRET=$(openssl rand -hex 32) \
  -e TRUST_PROXY=false \
  idaustria-client

4. Test

  1. Create a test identity in the Test Identity Manager
  2. Open https://your-domain.example.com → click Anmelden
  3. Authenticate with the test identity

Mobile / Simplified Continuation (App2App):

  1. Open the ID Austria app → Info → tap the version number 10× → enable Developer functions
  2. Set Backend environment to Referenz → re-link the app
  3. Open the test client on your mobile device → tap Anmelden → the app launches automatically

Endpoints

URL Description
/ Landing page / claims display after login
/login Initiate login (redirect to IdP)
/callback OIDC callback — register this URL in IDA-SPR
/logout RP-Initiated Logout
/debug/discovery OIDC Discovery metadata (JSON)
/health Health check

Environment Variables

Variable Required Default Description
APP_DOMAIN Yes Domain, e.g. idaustria-test.example.com (without https://)
OIDC_CLIENT_SECRET Yes From IDA-SPR
SESSION_SECRET Yes random Session signing secret — openssl rand -hex 32
OIDC_ISSUER_URL No Reference env OIDC Discovery endpoint
TRUST_PROXY No true Trust X-Forwarded-* headers from a reverse proxy
PORT No 3000 HTTP listen port

OIDC_CLIENT_ID, OIDC_REDIRECT_URI, and OIDC_POST_LOGOUT_URI are derived from APP_DOMAIN by docker-compose.yml. You can override them individually if needed (e.g. when running without Docker Compose).

ID Austria Error Codes

These appear as error_description in the callback when a flow fails:

Code Cause
UserCancel User cancelled the flow
UserNotLoggedIn ID Austria app not linked to an account
UserLoggedOut Logged out for security reasons
UserLockedOut Too many failed attempts
SystemInMaintenance Scheduled maintenance
SystemNotReachable No internet connection

Stack

  • Runtime: Node.js 24 (Alpine)
  • Framework: Express 5
  • OIDC: openid-client v6
  • Sessions: express-session (in-memory store — restart clears sessions)

References