All configuration is via environment variables. Set them in .env (Docker Compose) or your deployment environment.

Runtime

VariableRequiredDefaultDescription
UNISAVE_ENVNolocalEnvironment name (local, staging, production)
UNISAVE_PORTNo8080HTTP server listen port

Database

VariableRequiredDefaultDescription
UNISAVE_DATABASE_URLYesPostgres connection string. Example: postgres://unisave:unisave@localhost:5432/unisave?sslmode=disable
UNISAVE_DB_MAX_CONNSNo10Max pool connections (must be > 0)
UNISAVE_DB_MIN_CONNSNo1Min pool connections (0 ≤ min ≤ max)
UNISAVE_DB_MAX_CONN_LIFETIME_SECONDSNo1800Max connection age in seconds
UNISAVE_DB_MAX_CONN_IDLE_SECONDSNo300Max idle time before connection is closed
UNISAVE_DB_HEALTH_CHECK_PERIOD_SECONDSNo30Health check interval (must be > 0)

Authentication

Change these from the defaults before deploying. The example values in .env.example are placeholders only.
VariableRequiredDefaultDescription
UNISAVE_JWT_HMAC_KEYYesHMAC signing key for JWT access tokens. Minimum 32 bytes.
UNISAVE_REFRESH_TOKEN_PEPPERYesPepper for hashing refresh tokens. Minimum 16 bytes.

OAuth Providers

VariableRequiredDefaultDescription
UNISAVE_GOOGLE_OAUTH_CLIENT_IDNo*Google OAuth client ID for ID token verification
UNISAVE_APPLE_OAUTH_CLIENT_IDNo*Apple OAuth client ID (Services ID)
*Required if you want Google/Apple sign-in. Without these, only anonymous auth works.

AI & Embeddings

VariableRequiredDefaultDescription
UNISAVE_EMBEDDING_DIMNo768Vector embedding dimension for semantic search
UNISAVE_OPENAI_API_KEYNo*API key for generating embeddings
*Required for semantic search. Without this, search falls back to FTS + fuzzy only.

Rate Limiting & Quotas

VariableRequiredDefaultDescription
UNISAVE_FREE_ENRICH_PER_MINUTENo5Max enrichments per minute for free users
UNISAVE_FREE_ENRICH_PER_MONTHNo200Max enrichments per month for free users

Testing

These variables are only used by go test — ignored by runtime binaries.
VariableRequiredDefaultDescription
UNISAVE_TEST_DATABASE_URLNoPostgres URL for integration tests. Tests skip if unset.
UNISAVE_TEST_ALLOW_NON_LOCAL_DBNo0Set to 1 to allow tests against non-localhost databases

Generating Secrets

# JWT HMAC key (32+ bytes)
openssl rand -base64 32

# Refresh token pepper (16+ bytes)
openssl rand -hex 16

Minimal Production .env

UNISAVE_ENV=production
UNISAVE_PORT=8080
UNISAVE_DATABASE_URL=postgres://user:pass@db-host:5432/unisave?sslmode=require
UNISAVE_JWT_HMAC_KEY=<your-32-byte-random-key>
UNISAVE_REFRESH_TOKEN_PEPPER=<your-16-byte-random-pepper>
UNISAVE_GOOGLE_OAUTH_CLIENT_ID=<your-google-client-id>
UNISAVE_APPLE_OAUTH_CLIENT_ID=<your-apple-services-id>
UNISAVE_OPENAI_API_KEY=<your-openai-key>