Technical

How eIDAS Verification Works: A Technical Deep Dive

A comprehensive technical breakdown of the eIDAS verification flow, from QR code generation to attribute validation, covering protocols, security measures, and integration patterns.

eIDAS Pro Team
January 22, 2026
12 min read

Overview of the Verification Flow

eIDAS-based identity verification follows a carefully choreographed sequence designed to balance security, privacy, and user experience. Understanding this flow is essential for developers integrating identity verification into their applications.

The complete verification process involves four main actors:

  1. Relying Party (Your Application): The service requesting identity verification
  2. eIDAS Service Provider: Middleware that connects your application to the eIDAS network
  3. National eID Wallet: The user's mobile app (e.g., ID Austria, Smart-ID, BankID)
  4. National Identity Provider: The government system that issues and validates digital identities

Let's walk through each step of this process in detail.

Step 1: Verification Session Initialization

When your application needs to verify a user's identity, the process begins with creating a verification session.

Session Creation Request

Your application makes an API call to your eIDAS service provider:

POST /api/verification/create
{
  "requestedAttributes": ["age_over_18"],
  "purpose": "Age verification for purchase",
  "returnUrl": "https://yourapp.com/verification/callback"
}

The requestedAttributes field specifies exactly what information you need. eIDAS Pro focuses on boolean attribute verification—you receive true/false answers, not personal data:

Age Verification:

  • age_over_18: Is the user 18 or older?
  • age_over_21: Is the user 21 or older?
  • age_over_25: Is the user 25 or older?

Location/Residency Verification:

  • is_eu_resident: Is the user an EU resident?
  • is_eu_citizen: Is the user an EU citizen?

Why Boolean Attributes?

This approach provides maximum privacy with minimum GDPR liability:

  • You learn only what you need to know (yes/no)
  • No names, birthdates, or addresses to store or secure
  • No special category data processing
  • Dramatically reduced breach liability

Privacy Note: eIDAS Pro intentionally limits available attributes to boolean responses. If you need full identity data (names, addresses), document-based verification approaches will be necessary, with their associated GDPR obligations and costs. Many organizations use eIDAS for EU-specific minimal-data use cases and document verification for scenarios requiring complete identity data.

Data Controller Note: While eIDAS minimizes data collection, your organization remains a data controller for any verification results you store. See our GDPR compliance guide for details on your remaining obligations.

Session Response

The service provider generates a unique verification session and returns:

{
  "sessionId": "vs_a8f2b3c1...",
  "qrCodeData": "eidas://verify?session=vs_a8f2b3c1...",
  "deepLink": "at.gv.eid://verify?session=vs_a8f2b3c1...",
  "expiresAt": "2026-01-22T15:30:00Z",
  "statusUrl": "https://api.provider.com/verification/vs_a8f2b3c1/status"
}

The session typically expires in 5-10 minutes to prevent stale verification requests.

Step 2: QR Code Generation and Display

The QR code serves as the bridge between your web application and the user's mobile device.

QR Code Contents

The QR code encodes several critical pieces of information:

  1. Protocol Handler: eidas:// or country-specific schemes like at.gv.eid://
  2. Session Identifier: Links this verification to your backend session
  3. Service Provider Endpoint: Where the wallet should send the verification request
  4. Requested Attributes: What information needs to be verified

Modern Standards: OpenID4VP

Modern eIDAS implementations use OpenID for Verifiable Presentations (OpenID4VP), which standardizes how verifiable credentials are requested and presented. The QR code contains:

openid4vp://?
  client_id=https://yourprovider.com
  &request_uri=https://yourprovider.com/request/vs_a8f2b3c1

The request_uri points to a signed JWT containing the full verification request, ensuring integrity and preventing tampering.

Display Best Practices

Responsive Design: On mobile devices, display a "tap to open" button instead of a QR code, using deep links to launch the appropriate wallet app directly.

Loading States: Show a scanning animation and clear instructions ("Scan with your national eID app").

Fallback Options: Provide alternative verification methods for users without eID wallets.

Step 3: Wallet App Authentication

Once the user scans the QR code, their national eID wallet app takes over.

Request Validation

The wallet app:

  1. Fetches the Full Request: Retrieves the signed request from the request_uri
  2. Validates Signatures: Ensures the request comes from a legitimate service provider
  3. Checks Scope: Verifies the requested attributes are appropriate and legal
  4. Displays Consent Screen: Shows the user exactly what information will be shared

User Authentication

Before releasing any information, the wallet requires strong authentication. Methods vary by country but typically include:

Biometric Authentication (most common):

  • Fingerprint scan
  • Face recognition
  • Iris scanning

PIN/Password: A numeric PIN or alphanumeric password

Hardware Security: Many national eID wallets use secure elements (SE) or trusted execution environments (TEE) on the device, ensuring cryptographic keys never leave the secure enclave.

Example: ID Austria Flow

  1. User launches ID Austria app by scanning QR code
  2. App displays: "eidas-pro.com requests: Age verification (over 18)"
  3. User reviews and taps "Approve"
  4. Biometric prompt: "Use fingerprint to confirm"
  5. User authenticates with fingerprint
  6. App generates and signs verification response

The entire in-app flow takes 3-5 seconds for returning users.

Step 4: Attribute Exchange and Validation

After user authentication, the wallet prepares a cryptographically signed response containing the requested attributes.

Response Structure

The wallet generates a Verifiable Presentation using SD-JWT VC (Selective Disclosure JWT Verifiable Credentials), the actual format used by the EU Digital Identity Wallet:

// SD-JWT VC with selective disclosure - only revealing age_over_18
eyJhbGciOiJFUzI1NiIsInR5cCI6InZjK3NkLWp3dCJ9.
eyJpc3MiOiJodHRwczovL2lzc3Vlci5laWRhcy5ldSIsImlhdCI6MTY0MzI4NDgwMCwiZXhwIjoxNjQzMjg4NDAwLCJ2Y3QiOiJodHRwczovL2V4YW1wbGUuZXUvcGlkIiwic3ViIjoiZGlkOmp3azpleUp1SWpvaVJGTkJJaXdpZVNJNklqWTNOell4TWpFMk15SjkiLCJfc2QiOlsiRzVFbmhPQU9vVTlYXzhRQUFBQUFBQUFBQUEiLCJKNlVWck9uQUFBQUFBQUFBQUFBQUFBQSJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.
kLJkC5RhcvkKU-VU8-U5Ng7Iq4r8KxP9I_gKU8U8U8U8U

// Disclosures array (only age_over_18 disclosed, other attributes hidden)
~WyJhQUFBQUFBQSIsImFnZV9vdmVyXzE4Iix0cnVlXQ

// Key Binding JWT (proves holder controls the wallet)
eyJhbGciOiJFUzI1NiIsInR5cCI6ImtiK2p3dCJ9.
eyJub25jZSI6IjEyMzQ1Njc4OTAiLCJhdWQiOiJodHRwczovL3ZlcmlmaWVyLmNvbSIsImlhdCI6MTY0MzI4NDgwMCwic2RfaGFzaCI6ImtoMlA1LVl0QmQzSnVIbVFQQUFBQUFBIn0.
signature_proving_holder_possession

Note on Selective Disclosure: The example above uses SD-JWT VC (Selective Disclosure JSON Web Token Verifiable Credential), which is the current standard mandated by eIDAS 2.0 implementing acts. While Zero-Knowledge Proofs (ZKP) are being researched for future privacy enhancements, the current EUDI Wallet implementation uses selective disclosure via SD-JWT VC and mdoc formats. Age verification works by disclosing only the age_over_18: true attribute, not through cryptographic ZKP.

Key components of SD-JWT VC:

  • Header + Payload: Contains issuer, issuance date, and selectively disclosable claims (hashed)
  • Disclosures: Only the attributes the user chooses to reveal (in this case, age_over_18: true)
  • Key Binding: Cryptographic proof that the person presenting the credential controls the wallet

Privacy benefit: The verifier learns ONLY that age_over_18 is true. Other attributes like name, birthdate, and address remain cryptographically hidden.

Cryptographic Validation

Your service provider validates:

  1. Signature Verification: Confirms the response was signed by the legitimate national identity provider
  2. Certificate Chain: Validates the entire trust chain back to the national root certificate authority
  3. Revocation Status: Checks that the signing certificate hasn't been revoked
  4. Timestamp Validation: Ensures the response is fresh and hasn't been replayed

This validation happens in milliseconds using pre-cached public keys and certificate revocation lists.

Attribute Extraction

Once validated, the specific attributes are extracted and returned to your application:

{
  "status": "success",
  "sessionId": "vs_a8f2b3c1...",
  "attributes": {
    "age_over_18": true
  },
  "verifiedAt": "2026-01-22T12:00:05Z",
  "providerId": "AT",  // Austria
  "assuranceLevel": "high"  // eIDAS assurance level
}

Step 5: Real-Time Status Updates

While the user is authenticating on their mobile device, your web application needs to know when the process completes.

Server-Sent Events (SSE)

The most elegant solution is using Server-Sent Events for real-time updates:

const eventSource = new EventSource(
  `https://api.provider.com/verification/${sessionId}/stream`
);

eventSource.addEventListener('status', (event) => {
  const data = JSON.parse(event.data);

  if (data.status === 'scanned') {
    // User scanned QR code
    showMessage('Waiting for authentication...');
  } else if (data.status === 'completed') {
    // Verification successful
    redirectToSuccessPage();
  } else if (data.status === 'failed') {
    // Verification failed
    showError(data.reason);
  }
});

Polling Alternative

For environments that don't support SSE, implement polling with exponential backoff:

async function pollStatus(sessionId) {
  const maxAttempts = 60;  // 5 minutes
  let attempts = 0;

  while (attempts < maxAttempts) {
    const response = await fetch(
      `https://api.provider.com/verification/${sessionId}/status`
    );
    const data = await response.json();

    if (data.status !== 'pending') {
      return data;
    }

    // Exponential backoff: 1s, 2s, 4s, 8s, then 10s
    const delay = Math.min(1000 * Math.pow(2, attempts), 10000);
    await sleep(delay);
    attempts++;
  }

  throw new Error('Verification timeout');
}

Security Protocols and Encryption

eIDAS verification employs multiple layers of security to protect against various attack vectors.

Transport Layer Security

All communications use TLS 1.3 with strong cipher suites. Certificate pinning is recommended for mobile applications to prevent man-in-the-middle attacks.

Request Signing

Verification requests are signed using JSON Web Signatures (JWS) with:

  • Algorithm: ES256 (ECDSA using P-256 and SHA-256)
  • Key Storage: Hardware Security Modules (HSMs) for service provider keys
  • Rotation: Regular key rotation with overlapping validity periods

Response Validation

Responses are validated through:

  1. Digital Signatures: Every response is digitally signed by the national identity provider
  2. Timestamp Checks: Responses must be used within a short time window (typically 60 seconds)
  3. Nonce Verification: Each request includes a cryptographic nonce that must be echoed in the response
  4. Session Binding: Responses are bound to specific sessions and cannot be reused

Privacy-Preserving Techniques

Selective Disclosure: Users can choose which attributes to share, even if more were requested.

Zero-Knowledge Proofs (coming in eIDAS 2.0): Prove properties about data without revealing the data itself. For example, prove you're over 18 without revealing your birthdate.

Attribute Encryption: In transit, attributes are encrypted with session-specific keys, ensuring even the service provider infrastructure cannot access them until delivered to your application.

Integration Patterns

Different application architectures require different integration approaches.

Pattern 1: Backend-to-Backend (Server-Side)

Best for server-rendered applications or native mobile apps:

// 1. Create session on your backend
POST /api/verification/create
→ { sessionId, qrCodeData }

// 2. Display QR code to user
// 3. Poll or stream status on backend
GET /api/verification/:sessionId/status

// 4. Once complete, retrieve attributes
GET /api/verification/:sessionId/result
→ { attributes: { age_over_18: true } }

Advantages: Full control, better security, attributes never touch the frontend.

Pattern 2: JavaScript Widget (Client-Side)

Best for SPAs and quick integrations:

import { EidasWidget } from '@eidaspro/widget';

const widget = new EidasWidget({
  apiKey: 'your_api_key',
  onSuccess: (attributes) => {
    console.log('Verified:', attributes);
  },
  onError: (error) => {
    console.error('Verification failed:', error);
  }
});

widget.verify({ requestedAttributes: ['age_over_18'] });

Advantages: Fast integration, handles UI automatically, responsive design.

Pattern 3: E-Commerce Plugin

Pre-built plugins for platforms like WooCommerce and Shopify handle the entire flow:

  • Adds verification checkpoint to checkout
  • Stores verification status with order
  • Provides admin dashboard for compliance reporting
  • Handles edge cases and errors automatically

Error Handling and Edge Cases

Robust implementations must handle various failure scenarios.

Common Error Scenarios

Timeout: User doesn't scan QR code within expiration window

  • Solution: Display new QR code, extend session if user is still present

User Cancellation: User declines to share attributes

  • Solution: Provide alternative verification methods or explanation of why verification is needed

Network Failures: Connection issues during verification

  • Solution: Implement retries with exponential backoff, preserve session state

Unsupported Attributes: Requested attribute not available for user's eID scheme

  • Solution: Gracefully degrade or request alternative attributes

Assurance Level Mismatch: User's eID doesn't meet required assurance level

  • Solution: Request additional authentication factor or reject verification with clear explanation

Logging and Monitoring

Implement comprehensive logging for:

  • Verification request details (without PII)
  • Success/failure rates by country
  • Average verification duration
  • Error types and frequencies

This data is crucial for optimizing conversion rates and identifying technical issues.

Performance Optimization

Caching Strategies

Public Key Caching: Cache national identity provider public keys with appropriate TTL (typically 24 hours) to avoid repeated fetches.

Certificate Chain Validation: Pre-fetch and validate certificate chains during low-traffic periods.

Geographic Distribution: Use CDN edge locations close to national identity provider endpoints to minimize latency.

Response Time Targets

  • Session Creation: < 200ms
  • QR Code Generation: < 50ms
  • Attribute Validation: < 500ms
  • End-to-End User Flow: 5-10 seconds (primarily user authentication time)

Conclusion

eIDAS verification is built on robust cryptographic foundations, standardized protocols, and privacy-preserving architectures. By understanding the technical flow—from session initialization through attribute validation—developers can build integrations that are both secure and user-friendly.

The combination of OpenID4VP, verifiable credentials, and decentralized identity creates a system that scales across all of Europe while protecting user privacy and maintaining legal validity.

As you implement eIDAS verification, focus on error handling, performance optimization, and clear user communication. The technical complexity is handled by the underlying protocols; your job is to create an experience that feels seamless and trustworthy.


Need technical support for your integration? Our engineering team is available to help with architecture reviews, implementation questions, and performance optimization. Get in touch →

Related Articles

Share this article

Help others learn about eIDAS verification