Architecture Overview
Understand how Vouch components interact to issue and manage credentials
This page describes the components that make up Vouch, the protocols they use, and how they interact to turn a YubiKey tap into short-lived credentials for SSH, AWS, GitHub, Docker, and more.
Components
Vouch CLI (vouch)
The command-line interface that developers interact with directly. It handles:
- Enrollment – Registers a FIDO2 key with the Vouch server. An account that already has a registered key must verify with it before another key can be added.
- Login – Performs a FIDO2 assertion and establishes a session.
- Credential helpers – Provides credentials to tools like
aws,git,ssh,docker, andcargoon demand. - Setup commands – Configures local tool integrations (
vouch setup aws,vouch setup codecommit, etc.).
The CLI communicates with the Vouch agent over a local Unix domain socket and with the Vouch server over HTTPS. Authenticated credential-API requests to the server carry HTTP Message Signatures (RFC 9421) (opens in new tab) for cryptographic proof of request authenticity.
Vouch Agent
A background process that holds session state in memory. The agent:
- Caches the active session so that credential requests do not require repeated FIDO2 assertions.
- Serves as an SSH agent (implementing the SSH agent protocol) so that
sshcan request certificates without additional configuration. - Listens on a Unix domain socket with filesystem permissions restricting access to the owning user.
- Holds no persistent state of its own – cached credentials live in process memory; after a restart the agent recovers the session token from the CLI config file, so a new
vouch loginis only needed once the session expires or is revoked.
On macOS, the agent runs as a Homebrew service (brew services start vouch). On Linux, it runs as a systemd user service.
Vouch Server
The server is the identity broker. It:
- Authenticates users via FIDO2/WebAuthn assertions, with identity federation through your organization’s OIDC or SAML 2.0 identity provider.
- Issues OIDC ID tokens (signed with ES256 via AWS KMS) that AWS and other services consume via standard OIDC federation.
- Signs SSH certificates using an Ed25519 certificate authority key managed by AWS KMS.
- Exchanges tokens with GitHub Apps, AWS STS, and other external services on behalf of authenticated users.
- Manages the user directory via SCIM 2.0 integration with identity providers.
- Publishes OIDC metadata at
/.well-known/openid-configuration, JWKS at/oauth/jwks, and Protected Resource Metadata at/.well-known/oauth-protected-resource(RFC 9728 (opens in new tab)). When mTLS is configured, the discovery document includesmtls_endpoint_aliasesfor mTLS-capable clients. - Provides OIDC discovery for automatic identity provider detection during enrollment.
The server does not store AWS credentials, SSH private keys, or GitHub tokens. It brokers short-lived credentials from external services.
Protocol details
FIDO2 / WebAuthn
Used for all user authentication. The FIDO2 exchange happens between the YubiKey (authenticator), the Vouch CLI (client), and the Vouch server (relying party).
- Registration (enrollment): The YubiKey generates a key pair. The public key is sent to the server along with an attestation certificate. The private key never leaves the hardware. When attestation verification is enabled, the server validates the certificate chain against pinned Yubico root CA certificates to confirm the key is a genuine hardware device. If the account already has a registered key, the server requires an assertion with it before accepting a new registration.
- Authentication (login): The server sends a challenge. The YubiKey signs it with the private key after PIN + touch verification. The server validates the signature against the stored public key.
OIDC (OpenID Connect)
The Vouch server acts as an OIDC identity provider. After FIDO2 authentication, it issues a signed JWT (ID token) containing:
| Claim | Description |
|---|---|
iss | Vouch server URL (e.g., https://us.vouch.sh) |
sub | Subject. For cloud federation ID tokens (AWS, Kubernetes), this is the user’s email — what the consuming service matches in trust policies. For OAuth 2.0 access tokens issued under RFC 9068 (opens in new tab), this is a stable opaque user identifier; the email is carried in a separate email claim when the email scope is granted. |
aud | Audience. Cloud federation: the Vouch issuer URL (AWS) or a configurable value (Kubernetes — default kubernetes, matches the API server’s --oidc-client-id). Standard OIDC auth-code flow: the registered client_id. Tokens can be re-scoped to a different audience via RFC 8707 (opens in new tab) resource indicators or RFC 8693 (opens in new tab) token exchange. |
exp | Token expiration (default 8 hours, configurable via VOUCH_SESSION_HOURS) |
iat | Token issued-at timestamp |
hd | Google Workspace hosted domain |
amr | Authentication methods (e.g., ["hwk", "pin"]) |
acr | Authentication context class (NIST AAL3) |
cnf | Confirmation claim for sender-constrained tokens — contains jkt (DPoP key thumbprint) or x5t#S256 (mTLS certificate thumbprint) |
External services (AWS, Kubernetes, custom OIDC applications) validate these tokens using the Vouch server’s JWKS endpoint.
ES256 (ECDSA over P-256)
Used to sign OIDC ID tokens and access tokens. The signing key is managed by AWS KMS — the private key never exists outside the KMS boundary. External services fetch the public key from /oauth/jwks to verify token signatures. The JWKS endpoint supports key rotation — consuming services should re-fetch the JWKS when they encounter a token signed with an unknown kid.
Ed25519
Used for SSH certificate signing. The Ed25519 CA key is managed by AWS KMS. The Vouch server delegates each signing operation to KMS and returns the signed certificate. The CA private key never leaves KMS.
SSH Agent Protocol
The Vouch agent implements the SSH agent protocol (opens in new tab), making certificates available to ssh via the SSH_AUTH_SOCK environment variable. This is the same protocol used by ssh-agent and compatible with all standard SSH clients.
AWS STS (AssumeRoleWithWebIdentity)
The Vouch CLI calls AssumeRoleWithWebIdentity (opens in new tab) with the OIDC ID token. AWS validates the token against the Vouch JWKS endpoint and returns temporary credentials (access key ID, secret access key, session token).
FAPI 2.0
The Vouch CLI operates as a FAPI 2.0 (opens in new tab) client. On first use, it generates an ES256 key pair, stores it in the OS keychain, and auto-registers with the server (RFC 7591 (opens in new tab)). Token requests use DPoP (RFC 9449 (opens in new tab)) for sender-constrained tokens, RAR (RFC 9396 (opens in new tab)) for structured authorization details, and private_key_jwt (RFC 7523 (opens in new tab)) for client authentication — no shared secrets between CLI and server. Browser-based authorization flows use PAR (RFC 9126 (opens in new tab)) to keep authorization parameters out of URLs. FAPI 2.0 also accepts Mutual TLS (RFC 8705 (opens in new tab)) as an alternative sender-constraining mechanism — see Mutual TLS below.
HTTP Message Signatures (RFC 9421)
Authenticated credential-API requests (under /v1/) from the CLI to the Vouch server include HTTP Message Signatures (opens in new tab), enforced deny-by-default — the server rejects in-scope requests with a missing or invalid signature before processing. The CLI signs each request using the FAPI key pair stored in the OS keychain, providing cryptographic proof that the request was not tampered with in transit and originated from the registered client. OAuth endpoints are protected by private_key_jwt client assertions and DPoP proofs instead.
Supported algorithms: ECDSA P-256/P-384, EdDSA, and RSA-PSS-SHA512.
Mutual TLS (RFC 8705)
The Vouch server supports OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (opens in new tab) as an alternative to DPoP for sender-constrained tokens. When configured, a separate mTLS listener runs on port 8443 and verifies client certificates during the TLS handshake.
Two client authentication methods are supported: tls_client_auth (PKI-validated certificates where the server verifies the certificate chain against a configured Client Certificate CA) and self_signed_tls_client_auth (self-signed certificates registered via the client’s jwks or jwks_uri with x5c certificate representations).
Certificate-bound access tokens include an x5t#S256 thumbprint (SHA-256 hash of the client’s DER-encoded X.509 certificate) in the cnf claim. Resource servers validate that the certificate presented at the TLS layer matches the thumbprint bound to the token. The Client Certificate CA can be managed locally or via AWS KMS, following the same pattern as the SSH CA.
The OpenID Configuration discovery document advertises mTLS support via mtls_endpoint_aliases, which provides alternative endpoint URLs for token, revocation, and introspection endpoints on the mTLS port.
Protected Resource Metadata (RFC 9728)
The Vouch server publishes OAuth 2.0 Protected Resource Metadata (opens in new tab) at /.well-known/oauth-protected-resource. This document describes the resource’s authorization policy: which authorization server to use, the JWKS URI, supported scopes, bearer token presentation methods, DPoP and mTLS binding requirements, and descriptive URLs.
Every response includes a signed_metadata field — an ES256 JWS with typ=oauth-protected-resource+jwt, verifiable via the advertised jwks_uri. When a protected endpoint returns a 401, the WWW-Authenticate header includes a resource_metadata parameter pointing clients to the metadata document for automatic authorization server discovery.
Descriptive metadata fields are configurable via environment variables: VOUCH_RESOURCE_NAME, VOUCH_RESOURCE_DOCUMENTATION, VOUCH_RESOURCE_POLICY_URI, and VOUCH_RESOURCE_TOS_URI.
Step-Up Authentication (RFC 9470)
The Vouch server supports the OAuth 2.0 Step-Up Authentication Challenge Protocol (opens in new tab). When a protected resource requires a higher authentication assurance level than the current token provides, it returns a WWW-Authenticate challenge with error="insufficient_user_authentication" and acr_values or max_age parameters specifying the required authentication strength or recency. Clients use these parameters in a new authorization request to obtain a token meeting the elevated requirements. Vouch’s FIDO2 hardware authentication satisfies NIST AAL3 (acr claim), the highest NIST authentication assurance level.
SAML 2.0
For organizations using SAML-based identity providers, the Vouch server acts as a SAML Service Provider. It publishes SP metadata at /saml/metadata and accepts assertions at the Assertion Consumer Service endpoint (/saml/acs). Both HTTP-POST and HTTP-Redirect bindings are supported. See SAML Identity Providers for configuration details.
SCIM 2.0
The Vouch server implements SCIM 2.0 (opens in new tab) endpoints for automated user provisioning. Identity providers (Google Workspace, Okta, Azure AD) push user lifecycle events to synchronize the Vouch user directory.
Standards compliance
The Vouch server implements the following standards, each with dedicated test coverage:
| Standard | Title | Usage in Vouch |
|---|---|---|
| OIDC Core (opens in new tab) | OpenID Connect Core 1.0 | Identity provider, ID tokens, UserInfo |
| FAPI 2.0 SP (opens in new tab) | FAPI 2.0 Security Profile | Security controls for CLI and application clients |
| FAPI 2.0 MS (opens in new tab) | FAPI 2.0 Message Signing | HTTP Message Signatures on requests and responses |
| RFC 6749 (opens in new tab) | OAuth 2.0 Authorization Framework | Core authorization flows |
| RFC 7009 (opens in new tab) | Token Revocation | /oauth/revoke endpoint |
| RFC 7523 (opens in new tab) | JWT Bearer Client Authentication | private_key_jwt client authentication |
| RFC 7591 (opens in new tab) | Dynamic Client Registration | CLI auto-registration |
| RFC 7592 (opens in new tab) | Dynamic Client Registration Management | Client registration updates |
| RFC 7636 (opens in new tab) | PKCE | Code challenge for public clients |
| RFC 7644 (opens in new tab) | SCIM 2.0 | User provisioning |
| RFC 7662 (opens in new tab) | Token Introspection | /oauth/introspect endpoint |
| RFC 7800 (opens in new tab) | Proof-of-Possession Key Semantics | cnf claim in tokens |
| RFC 8176 (opens in new tab) | Authentication Method Reference Values | amr claim values |
| RFC 8414 (opens in new tab) | Authorization Server Metadata | /.well-known/openid-configuration |
| RFC 8628 (opens in new tab) | Device Authorization Grant | CLI and native app authentication |
| RFC 8693 (opens in new tab) | Token Exchange | Service-to-service delegation |
| RFC 8705 (opens in new tab) | Mutual-TLS | mTLS client auth, certificate-bound tokens |
| RFC 8707 (opens in new tab) | Resource Indicators | Audience-restricted tokens |
| RFC 8725 (opens in new tab) | JWT Best Current Practices | JWT security hardening |
| RFC 9068 (opens in new tab) | JWT Profile for Access Tokens | Access token format |
| RFC 9101 (opens in new tab) | JWT-Secured Authorization Request | Signed authorization requests |
| RFC 9126 (opens in new tab) | Pushed Authorization Requests | Back-channel authorization |
| RFC 9207 (opens in new tab) | AS Issuer Identification | Mix-up attack prevention via iss parameter |
| RFC 9396 (opens in new tab) | Rich Authorization Requests | Structured authorization details |
| RFC 9421 (opens in new tab) | HTTP Message Signatures | Request-level integrity |
| RFC 9449 (opens in new tab) | DPoP | Sender-constrained tokens |
| RFC 9470 (opens in new tab) | Step-Up Authentication | Authentication challenge protocol |
| RFC 9728 (opens in new tab) | Protected Resource Metadata | /.well-known/oauth-protected-resource |
| SAML 2.0 (opens in new tab) | SAML 2.0 | Identity provider federation |
Authentication flow
The complete flow from YubiKey tap to credential consumption:
┌──────────┐ ┌──────────┐ ┌──────────────┐ ┌─────────────────┐
│ YubiKey │ │ Vouch CLI│ │ Vouch Server │ │ External Service│
│ (FIDO2) │ │ + Agent │ │ (IdP/CA) │ │(AWS/GitHub/etc.)│
└─────┬────┘ └─────┬────┘ └──────┬───────┘ └───────┬─────────┘
│ │ │ │
│ 1. Challenge │ │ │
│◄──────────────┤ Get challenge │ │
│ ├──────-────────►│ │
│ │ │ │
│ 2. Sign │ │ │
│ (PIN+touch) │ │ │
├──────────────►│ │ │
│ │ 3. Assertion │ │
│ ├─────-─────────►│ │
│ │ │ 4. Validate │
│ │ │ │
│ │ 5. Session │ │
│ │◄───────-───────┤ │
│ │ │ │
│ │ 6. Credential │ │
│ │ request │ │
│ ├─────────────-─►│ │
│ │ │ 7. Exchange │
│ │ ├──────────────────-►│
│ │ │ 8. Short-lived │
│ │ │◄──────────────────-┤
│ │ 9. Credential │ │
│ │◄────────────-──┤ │
│ │ │ │
│ │ 10. Tool uses │ │
│ │ credential │ │
│ ├─────────────────────────────--─────►│
Steps 1–5 happen once during vouch login. Steps 6–10 happen on demand each time a tool needs a credential.
Agent architecture
The Vouch agent is a long-running process that provides two services:
Unix domain socket
The CLI communicates with the agent over a Unix domain socket at a well-known path. The socket is protected by multiple layers:
- Filesystem permissions — The socket file has restrictive permissions (owner-only) to prevent other users on the system from accessing session material.
- Peer credential verification — Every incoming connection is checked using OS-level peer credentials (
SO_PEERCREDon Linux,getpeereidon macOS) to verify the connecting process has the same UID as the agent. Connections from a different UID are rejected and audit-logged, following the same approach used bygpg-agent. - Directory safety — On startup, the agent validates that its socket directory (
$XDG_RUNTIME_DIR/vouch/, or~/.cache/vouch/whereXDG_RUNTIME_DIRis unset) is not a symlink and is owned by the current user, preventing symlink-based directory hijacking where an attacker pre-creates the directory pointing to an attacker-controlled location.
In-memory credential cache
The agent caches:
- Session token – Used to authenticate requests to the Vouch server.
- SSH certificate – Served to SSH clients via the agent protocol.
- Cached STS credentials – AWS credentials are cached until their 1-hour expiry to avoid redundant STS calls.
All cached material is held in process memory, and cached credentials are lost when the agent process stops (logout, reboot, crash). On startup the agent recovers the session token from the CLI config file (persisted with owner-only permissions), so a restart resumes the session until it expires; brokered credentials are re-issued on demand. A new vouch login is only needed after the session expires or is revoked.
Network requirements
The Vouch CLI and agent need to reach the following endpoints:
| Destination | Port | Protocol | Purpose |
|---|---|---|---|
Vouch server (e.g., us.vouch.sh) | 443 | HTTPS | Authentication, credential exchange, OIDC |
| Vouch server mTLS endpoint | 8443 | mTLS (HTTPS) | Certificate-bound token requests, mTLS client authentication (when configured) |
AWS STS (sts.amazonaws.com) | 443 | HTTPS | AssumeRoleWithWebIdentity |
| Target SSH hosts | 22 | SSH | SSH connections (if SSH integration is used) |
The Vouch server additionally requires outbound access to GitHub (api.github.com, port 443, HTTPS) for installation token exchange when the GitHub integration is enabled.
The Vouch server must be reachable from the internet so that AWS can fetch the JWKS endpoint for token validation. If your organization uses a firewall or proxy, ensure these destinations are allowed.
Data residency
Vouch server instances are deployed in specific geographic regions:
| Instance | Region | Status |
|---|---|---|
us.vouch.sh | United States | Active |
| EU instance | Europe | Coming soon |
| APAC instance | Asia-Pacific | Coming soon |
All user data (enrolled keys, user metadata, audit logs) resides in the region of the Vouch server instance you enroll with. Credentials brokered through AWS STS, GitHub, and other external services are subject to those services’ own data residency policies.