SSS Key Management Config
Configure and deploy SSS key management for your LearnCard instance
This guide covers the environment variables and infrastructure needed to deploy LearnCard with the self-hosted Shamir Secret Sharing (SSS) key management system.
Prerequisites
A running lca-api server instance
Redis (for OTP codes, QR login sessions, and caching)
MongoDB (for UserKey records)
A Firebase project (or other supported auth provider) with Admin SDK credentials
Postmark account (for email delivery in production) — optional, falls back to logging
LCA API Server Environment Variables
Required
SEED
Server-side encryption seed. Used to derive the KEK for AES-256-GCM auth share encryption at rest. Critical for security — if lost, all stored auth shares become unrecoverable.
A long, random, secret string
REDIS_HOST
Redis hostname. Must be REDIS_HOST, not REDIS_URL — the cache module reads this specific variable.
redis.example.com
REDIS_PORT
Redis port.
6379
GOOGLE_APPLICATION_CREDENTIAL
Firebase Admin SDK service account JSON (stringified). Used for token verification, user management, and custom token generation.
{"type":"service_account",...}
Email Delivery (Production)
Emails are rendered locally via @learncard/email-templates and delivered through Postmark as raw HTML. Tenant branding (brand name, logo, colors, from-domain) is applied automatically based on the X-Tenant-Id / Origin header on each request. See Configure Tenant-Branded Emails for how to register new tenants.
POSTMARK_SERVER_TOKEN
Postmark API key. If unset, email delivery falls back to console logging.
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
POSTMARK_FROM_EMAIL
Default "From" email address. Overridden per-email by getFrom() when tenant fromDomain is set.
noreply@example.com
POSTMARK_BRAND_NAME
Legacy brand name. Used only when the active tenant has no brandName override.
LearnCard
DEFAULT_TENANT_ID
(Optional) Fallback tenant ID used when neither X-Tenant-Id nor Origin resolves to a known tenant. Useful for per-tenant deploys and cron jobs. Defaults to learncard.
vetpass
POSTMARK_LOGIN_CODE_TEMPLATE_ALIAS
(Optional override) Real Postmark template alias for login OTP emails. When set, the adapter still renders locally first; this value is only used if local rendering fails.
login-code
POSTMARK_ENDORSEMENT_REQUEST_TEMPLATE_ALIAS
(Optional override) Same as above, for endorsement request emails.
endorsement-request
POSTMARK_RECOVERY_EMAIL_CODE_TEMPLATE_ALIAS
(Optional override) Same as above, for recovery email verification codes.
recovery-email-code
POSTMARK_RECOVERY_KEY_TEMPLATE_ALIAS
(Optional override) Same as above, for recovery key backup emails.
recovery-key
Migration from plain-text fallbacks (pre-LC-1749)
Earlier deployments required POSTMARK_RECOVERY_EMAIL_CODE_TEMPLATE_ALIAS and POSTMARK_RECOVERY_KEY_TEMPLATE_ALIAS to avoid falling back to unstyled plain-text emails. These env vars are now pure overrides — the server always renders the React Email template from @learncard/email-templates with full tenant branding. You may remove them from your deployment configuration.
The template variables changed from numeric IDs to string aliases in an earlier release:
POSTMARK_LOGIN_CODE_TEMPLATE_ID→POSTMARK_LOGIN_CODE_TEMPLATE_ALIASPOSTMARK_ENDORSEMENT_REQUEST_TEMPLATE_ID→POSTMARK_ENDORSEMENT_REQUEST_TEMPLATE_ALIAS
Update your deployment configuration accordingly.
Monitoring (Optional)
SENTRY_DSN
Sentry DSN for error tracking. If unset, Sentry is disabled.
https://xxx@sentry.io/123
SENTRY_ENV
Sentry environment label.
production
Test / Development Modes
IS_OFFLINE
Set to 'true' to bypass Firebase token verification (parses JWT locally). For local development.
IS_E2E_TEST
Set to 'true' to enable E2E test mode: email delivery uses log adapter, Firebase Admin SDK calls are bypassed.
Frontend Environment Variables (LearnCard App)
The frontend reads environment variables with a dual-prefix fallback: VITE_* first, then REACT_APP_*.
SSS Configuration
VITE_KEY_DERIVATION
REACT_APP_KEY_DERIVATION_PROVIDER
'sss'
Key derivation strategy. Set to 'sss' for SSS or 'web3auth' for legacy.
VITE_SSS_SERVER_URL
REACT_APP_SSS_SERVER_URL
'http://localhost:5100/api'
LCA API base URL for SSS key operations.
VITE_AUTH_PROVIDER
REACT_APP_AUTH_PROVIDER
'firebase'
Auth provider. Currently only 'firebase' is implemented.
Feature Flags
VITE_ENABLE_EMAIL_BACKUP_SHARE
'true'
Auto-send backup share to user's email during key setup. Set 'false' to disable.
VITE_REQUIRE_EMAIL_FOR_PHONE_USERS
'true'
Require phone-only users to link an email before proceeding.
VITE_ENABLE_AUTH_DEBUG_WIDGET
'false'
Show auth/key debug overlay. Auto-enabled in dev mode.
Web3Auth (Migration Period)
These are still read to support the legacy web3auth key derivation fallback during migration:
VITE_WEB3AUTH_CLIENT_ID
REACT_APP_WEB3AUTH_CLIENT_ID
Web3Auth dashboard client ID
VITE_WEB3AUTH_NETWORK
REACT_APP_WEB3AUTH_NETWORK
Web3Auth network
VITE_WEB3AUTH_VERIFIER_ID
REACT_APP_WEB3AUTH_VERIFIER_ID
Web3Auth verifier name
VITE_WEB3AUTH_RPC_TARGET
REACT_APP_WEB3AUTH_RPC_TARGET
Ethereum RPC URL
Once all users are migrated, these can be removed.
Infrastructure Requirements
Redis
Redis is required for:
OTP codes for login and recovery email verification (stored with short TTLs)
QR login sessions (ephemeral, auto-evicted)
General caching
A single Redis instance is sufficient. The lca-api connects via REDIS_HOST + REDIS_PORT.
MongoDB
MongoDB stores the UserKey collection, which contains:
The user's encrypted auth share
Previous auth share versions (for share versioning)
Recovery method metadata
Contact method and DID associations
Firebase Admin SDK
The Firebase Admin SDK is used for:
Token verification — validating Firebase ID tokens from the frontend
User management — updating user email/phone during contact method upgrades
Custom tokens — issuing new Firebase auth tokens after contact method changes
The service account JSON is provided via GOOGLE_APPLICATION_CREDENTIAL.
Deployment Checklist
Set
SEEDon the lca-api server. This is the most critical secret — back it up securely. If lost, all stored auth shares become permanently unrecoverable.Set
REDIS_HOST(notREDIS_URL) andREDIS_PORTon the lca-api server.Set
GOOGLE_APPLICATION_CREDENTIALwith the Firebase Admin SDK service account JSON.Configure Postmark (production only): set
POSTMARK_SERVER_TOKEN,POSTMARK_FROM_EMAIL,POSTMARK_BRAND_NAME, and the template alias variables.Set frontend env vars:
VITE_KEY_DERIVATION=sssandVITE_SSS_SERVER_URLpointing to your lca-api instance.Verify by logging in with a new account and checking that the AuthCoordinator reaches the
readystate.
Troubleshooting
OTP codes not working
lca-api using in-memory Redis mock
Verify REDIS_HOST is set (not REDIS_URL)
"Failed to verify token" errors
Missing or invalid Firebase credentials
Check GOOGLE_APPLICATION_CREDENTIAL
Auth shares not persisting
MongoDB connection issue
Check LCA_API_MONGO_URI and LCA_API_MONGO_DB_NAME
Emails not sending
Postmark not configured
Set POSTMARK_SERVER_TOKEN and POSTMARK_FROM_EMAIL
Last updated
Was this helpful?