Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

S3 Configuration Schema

For production deployments, Vouch supports loading configuration from an S3 object. This enables:

  • Centralized management — Single source of truth for multi-instance deployments
  • Dynamic updates — Configuration changes without server restart (for supported fields)
  • TLS hot-reload — Automatic certificate rotation without downtime
  • Secrets management — Leverage S3 server-side encryption and IAM for credential protection

Enabling S3 Configuration

Set the following environment variables to enable S3-based configuration:

# Required: bucket name
VOUCH_S3_CONFIG_BUCKET=my-bucket

# Optional: object key (default: config/vouch-server.json)
VOUCH_S3_CONFIG_KEY=config/vouch-server.json

# Optional: AWS region (uses default credential chain region if not set)
VOUCH_S3_CONFIG_REGION=us-west-2

# Optional: polling interval in seconds (default: 60)
VOUCH_S3_CONFIG_POLL_INTERVAL=60

When S3 configuration is enabled, it overrides environment variables. This allows for centralized configuration management with dynamic updates.

JSON Schema

The S3 configuration file is a JSON document with the following schema:

{
  "version": 1,
  "listen_addr": "0.0.0.0:443",
  "rp_id": "vouch.example.com",
  "rp_name": "Example Corp",
  "base_url": "https://vouch.example.com",
  "database_url": "postgres://...",
  "dsql_endpoints": {
    "us-east-1": "postgres://vouch@abc123.dsql.us-east-1.on.aws/postgres"
  },
  "jwt_secret": "32+ character secret",
  "session_hours": 8,
  "org_name": "Example Corp",
  "tls": {
    "cert": "<base64-encoded PEM certificate>",
    "key": "<base64-encoded PEM private key>"
  },
  "oidc": {
    "issuer_url": "https://accounts.google.com",
    "client_id": "...",
    "client_secret": "..."
  },
  "saml": {
    "idp_metadata_url": "https://idp.example.com/saml/metadata",
    "sp_entity_id": "https://vouch.example.com",
    "email_attribute": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
    "domain_attribute": "department"
  },
  "allowed_domains": ["example.com"],
  "ssh_ca_key": "<base64-encoded PEM Ed25519 private key>",
  "ssh_ca_kms_key_id": "mrk-1234abcd5678efgh",
  "oidc_signing_key": "<base64-encoded PEM EC P-256 private key>",
  "oidc_signing_kms_key_id": "mrk-abcd1234efgh5678",
  "oidc_rsa_signing_key": "<base64-encoded PEM RSA-3072 private key>",
  "oidc_rsa_signing_kms_key_id": "mrk-rsa1234abcd5678",
  "jwt_hmac_kms_key_id": "mrk-5678abcd1234efgh",
  "document_key": {
    "kms_key_id": "mrk-<key-id>",
    "encrypted_private_key": "<base64-encoded KMS ciphertext>"
  },
  "dpop": {
    "max_age_seconds": 300
  },
  "cors_origins": ["https://app.example.com"],
  "github": {
    "app_id": 12345,
    "app_name": "my-vouch-app",
    "app_key": "<PEM RSA private key>",
    "webhook_secret": "<secret>",
    "client_id": "<oauth-client-id>",
    "client_secret": "<oauth-client-secret>"
  },
  "cleanup_interval_minutes": 15,
  "auth_events_retention_days": 90,
  "oauth_events_retention_days": 90,
  "cli_download_macos": "https://example.com/vouch-macos",
  "cli_download_linux": "https://example.com/vouch-linux",
  "cli_download_windows": "https://example.com/vouch-windows",
  "device_code_expires_seconds": 600,
  "device_poll_interval_seconds": 5
}

Field Descriptions

FieldTypeDescription
versionintegerSchema version. Must be 1.
listen_addrstringAddress and port to listen on (e.g., 0.0.0.0:443).
rp_idstringRelying Party ID (domain). Used as the WebAuthn RP ID.
rp_namestringRelying Party display name for browser prompts and UI.
base_urlstringExternal base URL for the server.
database_urlstringDatabase connection URL (sqlite:, postgres:, or Aurora DSQL).
dsql_endpointsobjectRegional DSQL endpoints. Maps AWS region to full connection string.
jwt_secretstringJWT signing secret (minimum 32 characters). Not required if jwt_hmac_kms_key_id is set.
session_hoursintegerSession duration in hours.
org_namestringOrganization display name for branding in the UI.
tls.certstringTLS certificate (base64-encoded PEM).
tls.keystringTLS private key (base64-encoded PEM).
oidc.issuer_urlstringExternal OIDC issuer URL for enrollment.
oidc.client_idstringOIDC client ID from the external identity provider.
oidc.client_secretstringOIDC client secret from the external identity provider.
saml.idp_metadata_urlstringURL to the SAML IdP metadata XML document.
saml.sp_entity_idstringSAML SP entity ID (defaults to base_url).
saml.email_attributestringSAML attribute name for email extraction.
saml.domain_attributestringSAML attribute name for domain extraction.
allowed_domainsarray of stringsAllowed email domains for enrollment.
ssh_ca_keystringSSH CA private key (base64-encoded PEM, Ed25519).
ssh_ca_kms_key_idstringAWS KMS key ID for SSH CA signing (Ed25519). Overrides ssh_ca_key.
oidc_signing_keystringOIDC signing key (base64-encoded PEM, P-256 ECDSA).
oidc_signing_kms_key_idstringAWS KMS key ID for OIDC token signing (P-256). Overrides oidc_signing_key.
oidc_rsa_signing_keystringOIDC RSA signing key (base64-encoded PEM, RSA-3072). Signs ID tokens with RS256.
oidc_rsa_signing_kms_key_idstringAWS KMS key ID for OIDC RSA signing (RSA-3072). Overrides oidc_rsa_signing_key.
jwt_hmac_kms_key_idstringAWS KMS key ID for HMAC state token signing. Overrides jwt_secret.
document_keyobjectP-384 document encryption key. Contains kms_key_id and encrypted_private_key.
dpop.max_age_secondsintegerMaximum age of DPoP proofs in seconds.
cors_originsarray of stringsCORS allowed origins.
github.app_idintegerGitHub App ID.
github.app_namestringGitHub App name (slug from github.com/apps/{name}).
github.app_keystringGitHub App private key (PEM RSA).
github.webhook_secretstringGitHub webhook secret for signature verification.
github.client_idstringGitHub App OAuth client ID.
github.client_secretstringGitHub App OAuth client secret.
cleanup_interval_minutesintegerBackground cleanup task interval in minutes.
auth_events_retention_daysintegerRetention period for authentication events in days.
oauth_events_retention_daysintegerRetention period for OAuth usage events in days.
cli_download_macosstringCLI download URL for macOS, displayed in the server UI.
cli_download_linuxstringCLI download URL for Linux, displayed in the server UI.
cli_download_windowsstringCLI download URL for Windows, displayed in the server UI.
device_code_expires_secondsintegerDevice code expiration in seconds.
device_poll_interval_secondsintegerDevice code polling interval in seconds.

Base64 Encoding

All certificate and key fields in the S3 configuration must be base64-encoded PEM strings. To encode a PEM file:

# Encode a PEM file for S3 config
base64 -i cert.pem | tr -d '\n'

This ensures proper handling of newlines and special characters within JSON values.

Hot-Reloadable vs Startup-Only Fields

The server polls S3 at the configured interval and detects changes via ETag comparison. However, only certain fields support hot-reload without a server restart:

FieldHot-ReloadableNotes
tls.cert, tls.keyYesAutomatic reload on change
All other fieldsNoRequires server restart

Non-hot-reloadable fields include: jwt_secret, database_url, listen_addr, rp_id, rp_name, session_hours, cors_origins, allowed_domains, dpop.*, OIDC settings, SAML settings, GitHub App settings, SSH CA key, OIDC signing keys, and all KMS key IDs.

Note: The oidc and saml blocks are mutually exclusive. If both are present, the server will refuse to start.

Changes to non-hot-reloadable fields in S3 are silently ignored. A server restart is required to apply them.

TLS Certificate Hot-Reload

Vouch supports automatic TLS certificate reloading without dropping connections:

  1. Via S3 polling — Update tls.cert and tls.key in the S3 config; the server detects the change via ETag and reloads automatically.
  2. Via SIGHUP — Send SIGHUP to the server process to reload TLS certificates.
# Manual TLS certificate reload (Unix only)
kill -SIGHUP $(pgrep vouch-server)

Note: SIGHUP only reloads TLS certificates. It does not reload any other configuration fields.