Verifier Configuration
This guide provides detailed configuration options for the SIROS ID verifier. For conceptual background, see Concepts & Architecture. For deployment setup, see Deployment.
After reading this guide, you will understand how to:
- Connect your application to verify credentials
- Configure presentation requests
- Map verified claims to user sessions
- Deploy your own verifier (optional)
Endpoints
The SIROS ID verifier exposes standard OIDC endpoints. For a self-hosted or on-premise deployment at verifier.example.org:
| Endpoint | URL |
|---|---|
| Discovery | https://verifier.example.org/.well-known/openid-configuration |
| Authorization | https://verifier.example.org/authorize |
| Token | https://verifier.example.org/token |
| JWKS | https://verifier.example.org/jwks |
| Registration | https://verifier.example.org/register |
When using the SIROS ID hosted service, verifiers use subdomain-based multi-tenancy:
https://<instance>.<tenant>.verifier.id.siros.org
For example, tenant acme-corp with verifier instance main:
https://main.acme-corp.verifier.id.siros.org/.well-known/openid-configurationhttps://main.acme-corp.verifier.id.siros.org/authorize
Each tenant has isolated configuration, and each verifier instance has its own client registrations and presentation policies.
Deployment Options
| Option | Best For | Requirements |
|---|---|---|
| SIROS ID Hosted | Quick integration, SaaS model | API credentials only |
| Self-Hosted (Docker) | On-premise, data sovereignty | Docker, MongoDB |
| Self-Hosted (Binary) | Custom infrastructure | Go 1.25+, MongoDB |
Start with the hosted service for development and testing. Move to self-hosted when you need data sovereignty or to integrate with internal trust frameworks.
Overview
The SIROS ID verifier implements two protocol interfaces:
- OpenID Connect Provider – Standard OIDC interface for existing IAM systems
- OpenID4VP – Direct verification for custom applications
This means you can add credential verification to your application without changing your existing authentication flow.
Integration Options
Option 1: OIDC Identity Provider (Recommended)
Add the SIROS ID verifier as an identity provider in your IAM system. This works with:
- Keycloak – See Keycloak Integration
- Auth0 – Configure as Generic OIDC connection
- Okta – Add as Identity Provider
- Microsoft Entra ID – Add as External Identity Provider
- Google Workspace – Configure SAML app
- Any OIDC-compatible IAM
Benefits:
- No code changes to your application
- Leverage existing session management
- Works with federation and SSO
Option 2: Direct OIDC Integration
Integrate directly as an OIDC Relying Party:
// Example: Standard OIDC authorization request
const authUrl = new URL('https://verifier.example.org/authorize');
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('client_id', 'your-client-id');
authUrl.searchParams.set('redirect_uri', 'https://your-app.com/callback');
authUrl.searchParams.set('scope', 'openid profile pid');
authUrl.searchParams.set('state', generateState());
authUrl.searchParams.set('code_challenge', generatePKCE());
authUrl.searchParams.set('code_challenge_method', 'S256');
window.location = authUrl.toString();
Option 3: Direct OpenID4VP
For maximum control, use the OpenID4VP API directly:
// Start a presentation request
const response = await fetch('https://verifier.example.org/verification/start', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
credential_types: ['urn:eudi:pid:arf-1.8:1'],
claims: ['given_name', 'family_name', 'birth_date']
})
});
const { session_id, qr_code, deep_link } = await response.json();
Client Registration
Dynamic Registration (Recommended)
Use RFC 7591 dynamic client registration:
curl -X POST https://verifier.example.org/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "My Application",
"redirect_uris": ["https://my-app.com/callback"],
"token_endpoint_auth_method": "client_secret_post",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"scope": "openid profile pid ehic"
}'
Response:
{
"client_id": "abc123",
"client_secret": "secret456",
"client_id_issued_at": 1704067200,
"client_secret_expires_at": 0
}
Static Registration
For production deployments, contact your verifier administrator or use the admin API to pre-register clients.
Configuring Presentation Requests
Scope-Based Requests
Map OIDC scopes to credential types:
| Scope | Credential | Claims |
|---|---|---|
profile | PID | given_name, family_name, birth_date |
pid | PID | All PID claims |
ehic | EHIC | Health insurance claims |
diploma | Diploma | Educational credentials |
DCQL Queries (Advanced)
For fine-grained control, use Digital Credentials Query Language (DCQL):
# presentation_request.yaml
credentials:
- id: pid_credential
format: vc+sd-jwt
meta:
vct_values:
- urn:eudi:pid:arf-1.8:1
claims:
- path: ["given_name"]
- path: ["family_name"]
- path: ["birth_date"]
- id: ehic_credential
format: vc+sd-jwt
meta:
vct_values:
- urn:eudi:ehic:1
claims:
- path: ["card_number"]
- path: ["institution"]
Claim Mapping
Verified credentials are mapped to standard OIDC claims in the ID token:
{
"iss": "https://verifier.example.org",
"sub": "pairwise-user-id",
"aud": "your-client-id",
"exp": 1704153600,
"iat": 1704067200,
"given_name": "Alice",
"family_name": "Smith",
"birthdate": "1990-01-15",
"nationality": "SE"
}
Custom Claim Mapping
Configure how credential claims map to OIDC claims:
verifier:
claim_mapping:
# Standard mappings
given_name: "$.vc.credentialSubject.given_name"
family_name: "$.vc.credentialSubject.family_name"
birthdate: "$.vc.credentialSubject.birth_date"
# Custom mappings
employee_id: "$.vc.credentialSubject.employee_number"
W3C Digital Credentials API
For browser-based verification, the SIROS ID verifier supports the W3C Digital Credentials API:
// Browser-native credential request
const credential = await navigator.credentials.get({
digital: {
providers: [{
protocol: "openid4vp",
request: requestObject
}]
}
});
When enabled, users can present credentials with a single click—no QR code scanning needed.
Browser Support
| Browser | Status |
|---|---|
| Chrome 116+ | ✅ Supported (with flag) |
| Edge 116+ | ✅ Supported (with flag) |
| Safari 17+ | ⚠️ Partial support |
| Firefox | 🔜 Planned |
The verifier automatically falls back to QR code when the DC API is unavailable.
Security Features
PKCE Enforcement
Public clients must use PKCE (RFC 7636):
// Generate code verifier and challenge
const verifier = generateRandomString(64);
const challenge = base64url(sha256(verifier));
Pairwise Subject Identifiers
By default, users receive different sub claims for each relying party, preventing cross-site tracking:
verifier:
oidc:
subject_type: "pairwise" # or "public"
subject_salt: "random-secret-value"
Credential Verification
The verifier automatically:
- ✅ Validates credential signature
- ✅ Checks issuer trust (via trust framework)
- ✅ Verifies credential status (revocation)
- ✅ Validates credential expiration
- ✅ Confirms credential type matches request
API Endpoints
OIDC Provider Endpoints
| Endpoint | Method | Description |
|---|---|---|
/.well-known/openid-configuration | GET | OIDC discovery metadata |
/jwks | GET | JSON Web Key Set |
/authorize | GET | Start authorization |
/token | POST | Exchange code for tokens |
/userinfo | GET | Get user claims |
/register | POST | Dynamic client registration |
OpenID4VP Endpoints
| Endpoint | Method | Description |
|---|---|---|
/verification/start | POST | Create presentation request |
/verification/request-object/{id} | GET | Get signed request object |
/verification/direct_post | POST | Receive wallet response |
/verification/status/{id} | GET | Check verification status |
Testing
Development Environment
For testing, you can use the SIROS ID demo environment or deploy a local verifier instance.
The SIROS ID demo environment is available at:
- Demo Verifier:
https://main.demo.verifier.id.siros.org - Demo Wallet:
https://id.siros.org
Test Credentials
Obtain test credentials from a demo issuer:
- Open id.siros.org on your phone
- Navigate to "Add Credential"
- Scan the demo issuer QR code
- Accept the test credential
Integration Testing
# Test OIDC discovery
curl https://verifier.example.org/.well-known/openid-configuration
# Verify JWKS
curl https://verifier.example.org/jwks
Self-Hosted Deployment
If you need to run the verifier in your own infrastructure, you can deploy it using Docker or as a standalone binary.
Docker Deployment (Recommended)
The verifier is available as a Docker image:
# Pull the standard verifier image
docker pull ghcr.io/sirosfoundation/vc-verifier:latest
# Or pull the full image with SAML and VC 2.0 support
docker pull ghcr.io/sirosfoundation/vc-verifier-full:latest
Use vc-verifier-full if you need SAML authentication or W3C VC 2.0 format support. See Docker Images for details.
Docker Compose
Create a docker-compose.yaml:
services:
verifier:
image: ghcr.io/sirosfoundation/vc-verifier:latest # or vc-verifier-full for SAML support
restart: always
ports:
- "8080:8080"
volumes:
- ./config.yaml:/config.yaml:ro
- ./pki:/pki:ro
- ./presentation_requests:/presentation_requests:ro
environment:
- VC_CONFIG_YAML=config.yaml
depends_on:
- mongo
mongo:
image: mongo:7
restart: always
volumes:
- mongo-data:/data/db
ports:
- "27017:27017"
# Optional: go-trust for trust evaluation
go-trust:
image: ghcr.io/sirosfoundation/go-trust:latest
restart: always
ports:
- "8081:8081"
volumes:
- ./trust-config.yaml:/config.yaml:ro
command: ["serve", "--config", "/config.yaml"]
volumes:
mongo-data:
Verifier Configuration
Create config.yaml:
verifier:
api_server:
addr: :8080
tls:
enabled: false # Use reverse proxy for TLS in production
external_url: "https://verifier.example.com"
verifier_proxy:
api_server:
addr: :8080
external_url: "https://verifier.example.com"
oidc:
issuer: "https://verifier.example.com"
signing_key_path: "/pki/oidc_signing_key.pem"
signing_alg: "RS256"
session_duration: 900
code_duration: 300
access_token_duration: 3600
id_token_duration: 3600
subject_type: "pairwise"
subject_salt: "${SUBJECT_SALT}"
openid4vp:
presentation_timeout: 300
supported_credentials:
- vct: "urn:eudi:pid:arf-1.8:1"
scopes: ["openid", "profile"]
- vct: "urn:eudi:ehic:1"
scopes: ["ehic"]
# Trust evaluation via go-trust (AuthZEN)
trust:
authzen_endpoint: "http://go-trust:8081"
enabled: true
digital_credentials:
enabled: true
use_jar: true
allow_qr_fallback: true
common:
mongo:
uri: mongodb://mongo:27017
production: true
Start the Services
# Generate signing keys
openssl genrsa -out pki/oidc_signing_key.pem 2048
# Start all services
docker compose up -d
# Check logs
docker compose logs -f verifier
# Verify health
curl http://localhost:8080/health
Binary Deployment
For non-Docker environments:
# Clone the repository
git clone https://github.com/dc4eu/vc.git
cd vc
# Build the verifier
make build-verifier
# Run
export VC_CONFIG_YAML=config.yaml
./bin/vc_verifier
Kubernetes Deployment
For production Kubernetes deployments:
apiVersion: apps/v1
kind: Deployment
metadata:
name: verifier
spec:
replicas: 2
selector:
matchLabels:
app: verifier
template:
metadata:
labels:
app: verifier
spec:
containers:
- name: verifier
image: ghcr.io/sirosfoundation/vc-verifier:latest # or vc-verifier-full
ports:
- containerPort: 8080
env:
- name: VC_CONFIG_YAML
value: /config/config.yaml
- name: SUBJECT_SALT
valueFrom:
secretKeyRef:
name: verifier-secrets
key: subject-salt
volumeMounts:
- name: config
mountPath: /config
- name: pki
mountPath: /pki
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8080
volumes:
- name: config
configMap:
name: verifier-config
- name: pki
secret:
secretName: verifier-pki