Add Hardware-Backed Sign-In to Your Application

Building phishing-resistant authentication from scratch means implementing WebAuthn flows, managing attestation, and handling device lifecycle – a significant engineering investment for a startup. If you already have an OIDC-compatible application, you can get hardware-backed sign-in without any of that.

Vouch is a fully compliant OpenID Connect (OIDC) provider. You add “Sign in with Vouch” to any web application, single-page app, or native CLI tool using standard OIDC libraries. Every login is backed by a hardware security key, giving your application phishing-resistant authentication without building it yourself.

OpenID Certified

What you’ll build

By following this guide, you will integrate Vouch as an OIDC identity provider into your application. Users will authenticate with their YubiKey through Vouch, and your application will receive verified identity information including:

  • A unique, stable user identifier (sub claim) in the ID token
  • The user’s email address in the ID token
  • Hardware attestation claims (hardware_verified, hardware_aaguid) in the access token

This works with any framework or library that supports OpenID Connect or OAuth 2.0 authorization code flow. Beyond web applications, Vouch secures MCP tool servers with bearer token authentication and enables agent-to-agent (A2A) communication backed by hardware-verified identity.


Prerequisites

Before integrating Vouch into your application, you need:

  • A registered OAuth application at https://us.vouch.sh/applications
  • Your application’s client ID (client_id)
  • Your application’s client secret (client_secret)
  • A configured redirect URI (e.g., https://your-app.example.com/auth/callback)

To register an application, navigate to https://us.vouch.sh/applications and click New Application:

Register New Application form with application type, redirect URIs, and security profile options

After creating the application, you will see your client ID and client secret. The client secret is only shown once — store it securely.

Application Created page showing client ID and client secret

You can view and manage all your applications from the applications list:

My Applications page showing registered applications with type, scope, and status


Managing Applications

After creating an application, you can view its full configuration — including client ID, type, access scope, redirect URIs, and client secrets — from the application detail page:

Application detail page showing configuration, redirect URIs, and client secret management

From this page you can edit settings, rotate client secrets, or delete the application.


Access Scopes

Vouch supports two access scopes that control what identity information is included in tokens:

ScopeDescriptionClaims Included
openidRequired. Identifies this as an OIDC authentication request.sub, iss, aud, exp, iat
emailUser email address.email, email_verified

Request scopes in the authorization request by including them in the scope parameter, space-separated:

scope=openid email

Rich Authorization Requests

For fine-grained access control beyond what scopes can express, Vouch supports Rich Authorization Requests (RFC 9396). Instead of flat scope strings, your application can pass structured authorization_details objects that describe the type, actions, and resources being requested.

Format

The authorization_details parameter is a JSON array of objects. Each object must include a type field; all other fields are defined by your application:

[
  {
    "type": "account_access",
    "actions": ["read", "transfer"],
    "locations": ["https://api.example.com/accounts"]
  }
]

Using with PAR

Since Vouch uses Pushed Authorization Requests (RFC 9126), include authorization_details in the PAR request body alongside your other parameters:

curl -X POST https://us.vouch.sh/oauth/par \
  -d "client_id=your-client-id" \
  -d "client_secret=your-client-secret" \
  -d "response_type=code" \
  -d "redirect_uri=https://your-app.example.com/auth/callback" \
  -d "scope=openid email" \
  -d 'authorization_details=[{"type":"account_access","actions":["read","transfer"]}]'

Token response

The granted authorization_details are returned in the token response, so your application can confirm exactly what was authorized:

{
  "access_token": "eyJhbGciOiJFUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "authorization_details": [
    {
      "type": "account_access",
      "actions": ["read", "transfer"]
    }
  ]
}

Rich Authorization Requests can be used alongside scopes — they are complementary, not mutually exclusive.


Configuration Reference

Use the following endpoints and values to configure your OIDC client library. All URLs are relative to your Vouch server instance.

ParameterValue
Discovery URLhttps://us.vouch.sh/.well-known/openid-configuration
Issuerhttps://us.vouch.sh
Authorization Endpointhttps://us.vouch.sh/oauth/authorize
Token Endpointhttps://us.vouch.sh/oauth/token
UserInfo Endpointhttps://us.vouch.sh/oauth/userinfo
JWKS URIhttps://us.vouch.sh/.well-known/jwks.json
Signing AlgorithmES256
Supported Scopesopenid, email
Authorization DetailsSupported via authorization_details parameter (RFC 9396)
Device Authorization Endpointhttps://us.vouch.sh/oauth/device/code
Device Verification URLhttps://us.vouch.sh/oauth/device
PAR Endpointhttps://us.vouch.sh/oauth/par
Token Revocation Endpointhttps://us.vouch.sh/oauth/revoke
Token Introspection Endpointhttps://us.vouch.sh/oauth/introspect

Most OIDC libraries can auto-configure themselves from the Discovery URL alone.


ID Token Claims

Vouch ID tokens follow the standard OIDC specification. The payload contains:

ClaimTypeDescription
issstringIssuer — your Vouch server URL
substringSubject — stable, unique user identifier
audstringAudience — your application’s client_id
expnumberExpiration time
iatnumberIssued-at time
emailstringUser’s email address (when email scope is requested)
email_verifiedbooleanWhether the email is verified (when email scope is requested)
amrarrayAuthentication methods used (e.g., ["hwk", "pin"])
acrstringAuthentication context class (e.g., NIST AAL3 for hardware MFA)
cnfobjectConfirmation claim containing key binding information per RFC 7800. Includes a kid field referencing the specific credential used.

Example ID token payload:

{
  "iss": "https://us.vouch.sh",
  "sub": "user_abc123",
  "aud": "your-client-id",
  "exp": 1700000000,
  "iat": 1699996400,
  "email": "alice@example.com",
  "email_verified": true,
  "amr": ["hwk", "pin"],
  "acr": "urn:nist:authentication:assurance-level:aal3",
  "cnf": {
    "kid": "credential_xyz789"
  }
}

Access Token Claims

Vouch issues access tokens as JWTs (RFC 9068). These include hardware attestation claims that your application can use to enforce security policies. These claims are not in the ID token or the UserInfo response.

ClaimTypeDescription
hardware_verifiedbooleantrue if the authentication was performed using a verified hardware security key. Always true for Vouch-issued tokens from the authorization code flow.
hardware_aaguidstringThe AAGUID (Authenticator Attestation GUID) of the hardware key used for authentication. This identifies the make and model of the security key (e.g., YubiKey 5 series).

To access these claims, decode the access token JWT payload. See the examples repository for working implementations in each framework.


Token Lifetime

Vouch access tokens are short-lived and Vouch does not issue refresh tokens (by design – every session requires hardware key interaction). Your application should handle token expiry gracefully:

  • Server-side applications – Check token expiry before using it. If expired, redirect the user through the authorization flow again.
  • Single-page applications – Check user.expired before making API calls. If the token has expired, redirect the user through the authorization flow again using signinRedirect().
  • Native CLI applications – Use the device authorization flow (RFC 8628) and prompt the user to re-authenticate when the token expires.

Service-to-Service (M2M) Authentication

For server-to-server communication where no human user is involved, Vouch supports Token Exchange (RFC 8693). A service with a valid Vouch token can exchange it for a new token scoped to a different audience, enabling secure service-to-service calls.

Token Exchange Flow

  1. Service A authenticates a user through the standard OIDC flow and obtains an access token.
  2. Service A calls Service B and needs to pass along the user’s identity.
  3. Service A exchanges its token for a new token with Service B’s audience by calling the token endpoint.

Token Exchange Request

curl -X POST https://us.vouch.sh/oauth/token \
  -d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
  -d "subject_token=<access-token>" \
  -d "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
  -d "audience=service-b-client-id" \
  -d "client_id=service-a-client-id" \
  -d "client_secret=service-a-client-secret"

Token Exchange Response

{
  "access_token": "eyJhbGciOiJFUzI1NiIs...",
  "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
  "token_type": "Bearer",
  "expires_in": 3600
}

The new token is scoped to Service B’s audience and inherits the user’s identity claims from the original token. Service B can validate this token by checking the aud claim and verifying the signature against the Vouch JWKS endpoint.


Client Credentials (Machine-to-Machine)

For automated systems that need to authenticate without any human interaction – CI/CD pipelines, background services, or daemon processes – Vouch supports the OAuth client credentials grant (RFC 6749 Section 4.4).

Unlike the authorization code flow (which requires a browser and a YubiKey tap), the client credentials flow lets a service authenticate directly using its client ID and client secret.

When to use client credentials

  • CI/CD pipelines that need Vouch tokens without a human in the loop
  • Background services or daemon processes that run unattended
  • Automated tooling that needs to call Vouch-protected APIs

For deployments where you want a human to explicitly authorize each action (e.g., production deploys), use the CI/CD human approval gate pattern instead.

Request

curl -X POST https://us.vouch.sh/oauth/token \
  -d "grant_type=client_credentials" \
  -d "client_id=your-client-id" \
  -d "client_secret=your-client-secret" \
  -d "scope=openid email"

Response

{
  "access_token": "eyJhbGciOiJFUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600
}

The access token can be used as a Bearer token in API requests to any service that validates tokens against the Vouch JWKS endpoint.

Setup

  1. Register an application at https://us.vouch.sh/applications (or via the Admin Dashboard).
  2. Note the client ID and client secret.
  3. Store the client secret securely (e.g., as a CI/CD secret, not in source code).
  4. Use the token endpoint with grant_type=client_credentials to obtain tokens.

Troubleshooting

Discovery endpoint not reachable

Error: unable to fetch OpenID configuration from https://us.vouch.sh/.well-known/openid-configuration
  • Verify the Vouch server URL is correct and accessible from your application server.
  • Check that your application can reach the Vouch server (no firewall or network restrictions).
  • Ensure the URL does not have a trailing slash.

Invalid client_id or client_secret

error: invalid_client
  • Verify the client_id and client_secret match what was registered on the Vouch applications page.
  • Check that the client credentials are not expired or revoked.
  • Ensure the credentials are being sent correctly (as form parameters for the token endpoint, not as JSON).

Redirect URI mismatch

error: redirect_uri_mismatch

The redirect URI in your authorization request does not match any URI registered for this client. Ensure:

  • The redirect URI exactly matches what was registered (including protocol, host, port, and path).
  • There are no trailing slashes or query parameters that differ.
  • If using localhost for development, the port must match exactly.

ID token validation fails

Error: ID token signature verification failed
  • Ensure your library is configured to use the ES256 signing algorithm. Vouch uses ECDSA with P-256, not RSA.
  • Verify the JWKS endpoint is reachable: https://us.vouch.sh/.well-known/jwks.json
  • Check that the iss claim matches your configured issuer URL exactly.
  • Ensure your server’s clock is synchronized (token validation is time-sensitive).

CORS errors in browser applications

Access to fetch at 'https://us.vouch.sh/oauth/token' has been blocked by CORS policy

For single-page applications, ensure your application’s origin is registered as an allowed origin on the Vouch applications page. The Vouch server must include your origin in its CORS Access-Control-Allow-Origin response header.

Device code expired

error: expired_token

The user did not complete authentication within the allowed time window. Request a new device code and display the new user_code to the user. The default expiration is 10 minutes.

Startups

Skip IAM users, access keys, and IAM Identity Center. Go from Google Workspace to AWS in minutes with OIDC federation.

Getting Started

Install the Vouch CLI, enroll your YubiKey, and replace static secrets with hardware-backed credentials in minutes.

More

Applications (OIDC)

Integrate Vouch as an OIDC provider in your web, SPA, or native app for hardware-verified authentication.

CLI Reference

Complete command reference for the Vouch CLI — login, credentials, setup, and configuration.

Admin Dashboard

Manage organization members, view audit logs, configure SCIM tokens, and enforce device posture policies from the Vouch admin dashboard.

Architecture

System components, protocols, and trust boundaries — how the Vouch CLI, agent, and server work together.

SCIM Provisioning

Sync users and groups from your identity provider to Vouch automatically using SCIM 2.0.

Security

How Vouch protects credentials at every layer — data flow, threat model, credential lifecycle, and supply chain integrity.

Device Posture

Enforce security requirements on developer devices before issuing credentials — disk encryption, firewalls, screen lock, endpoint protection, and more.

Threat Model

STRIDE-based threat analysis — threat actors, trust boundaries, assumptions, threats, and mitigations for the Vouch credential broker.

Availability

What happens when the Vouch server is unreachable — offline behavior, credential expiry, and blast radius.

SAML

Use SAML 2.0 identity providers with Vouch — Okta, Microsoft Entra ID, Google Workspace, and more.

CI/CD

Require a YubiKey tap before production deployments — hardware-verified identity embedded in every CI/CD credential.

Migration

Migrate from static credentials to Vouch — phased rollout, integration-by-integration checklist, and rollback plan.

FAQ

Common questions about Vouch — supported hardware, session behavior, platform support, and cost.