Configuration & Secrets
This guide documents all configuration options, environment variables, and recommended settings for Terragnos Core deployments.
Configuration Overview
Terragnos Core is configured via environment variables. Set these in your .env file, Docker Compose configuration, Kubernetes secrets, or your deployment platform's configuration system.
Required Configuration
Database
DATABASE_URL=postgres://user:password@host:5432/database
Format: PostgreSQL connection string
Required: Yes
Example: postgres://terragnos:secret@db:5432/terragnos
The database must have PostGIS extensions installed:
postgispgcryptouuid-ossppg_trgm
Authentication
AUTH_JWT_SECRET=your-secret-key-minimum-32-characters
Type: String
Required: Yes
Minimum length: 32 characters
Purpose: Secret key for JWT token signing and validation
Recommendation: Use a cryptographically random string. Generate with:
openssl rand -base64 32
Optional Configuration
Application Settings
# Port the API listens on
PORT=3000
# Node environment
NODE_ENV=production
# Logging level
LOG_LEVEL=info
LOG_LEVEL options: fatal, error, warn, info, debug, trace
Default: info
Authentication Settings
# Default tenant for tokens without tenant claim
AUTH_DEFAULT_TENANT=default
# JWT issuer (optional)
AUTH_JWT_ISSUER=your-issuer-name
# JWT audience (optional)
AUTH_JWT_AUDIENCE=your-audience-name
# Disable authentication (development only!)
AUTH_DISABLED=false
Warning: Never set
AUTH_DISABLED=truein production.
Licensing
# License key from Terragnos
LICENSE_KEY=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
# Public key for license verification
LICENSE_PUBLIC_KEY=-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----
# Encryption key for license storage
LICENSE_STORAGE_SECRET=optional-32-byte-key
LICENSE_STORAGE_SECRET: If provided, licenses are encrypted at rest in the database. Use a 32-byte random string.
Caching & Performance
# Redis connection for caching (optional)
REDIS_URL=redis://redis:6379
# Rate limiting: time window in seconds
RATE_LIMIT_TTL=60
# Rate limiting: max requests per window
RATE_LIMIT_LIMIT=120
# Layer cache TTL in seconds
LAYER_CACHE_TTL_SECONDS=3600
REDIS_URL: If not provided, the system uses in-memory caching (lost on restart).
RATE_LIMIT_TTL / RATE_LIMIT_LIMIT: Global rate limiting. Default: 120 requests per 60 seconds.
LAYER_CACHE_TTL_SECONDS: How long GeoJSON/MVT responses are cached. Default: 60 seconds (can be overridden per layer definition).
Event Stream
# Disable event stream (for testing/snapshots)
EVENT_STREAM_DISABLED=false
Set to true to disable the PostgreSQL LISTEN/NOTIFY event stream.
Configuration by Environment
Development
NODE_ENV=development
LOG_LEVEL=debug
AUTH_DISABLED=false
AUTH_JWT_SECRET=dev-secret-change-me
DATABASE_URL=postgres://terragnos:terragnos@localhost:5432/terragnos
Staging
NODE_ENV=production
LOG_LEVEL=info
AUTH_DISABLED=false
AUTH_JWT_SECRET=<strong-secret>
DATABASE_URL=<staging-database-url>
LICENSE_KEY=<staging-license>
LICENSE_PUBLIC_KEY=<staging-public-key>
REDIS_URL=redis://redis-staging:6379
Production
NODE_ENV=production
LOG_LEVEL=warn
AUTH_DISABLED=false
AUTH_JWT_SECRET=<production-secret>
DATABASE_URL=<production-database-url>
LICENSE_KEY=<production-license>
LICENSE_PUBLIC_KEY=<production-public-key>
LICENSE_STORAGE_SECRET=<encryption-key>
REDIS_URL=redis://redis-prod:6379
RATE_LIMIT_TTL=60
RATE_LIMIT_LIMIT=1000
LAYER_CACHE_TTL_SECONDS=7200
Secrets Management
Docker Compose
Use Docker secrets or .env files (never commit .env to version control):
services:
api:
env_file:
- .env
secrets:
- jwt_secret
- database_url
secrets:
jwt_secret:
file: ./secrets/jwt_secret.txt
database_url:
file: ./secrets/database_url.txt
Kubernetes
Use Kubernetes secrets:
apiVersion: v1
kind: Secret
metadata:
name: terragnos-secrets
type: Opaque
stringData:
AUTH_JWT_SECRET: your-secret
DATABASE_URL: postgres://...
LICENSE_KEY: ...
External Secret Managers
Integrate with:
- AWS Secrets Manager
- HashiCorp Vault
- Azure Key Vault
- Google Secret Manager
Configuration Validation
Terragnos Core validates configuration on startup. Invalid configuration causes the service to fail with a clear error message.
Common validation errors:
- Missing
DATABASE_URL - Invalid
DATABASE_URLformat - Missing
AUTH_JWT_SECRET - Invalid
REDIS_URLformat (if provided)
Best Practices
- Use strong secrets – Minimum 32 characters, randomly generated
- Rotate secrets regularly – Update JWT secrets periodically
- Separate by environment – Use different secrets for dev/staging/prod
- Never commit secrets – Use
.gitignorefor.envfiles - Use secret managers – Store secrets in dedicated secret management systems
- Limit access – Restrict who can view/modify secrets
- Monitor changes – Log secret rotations for audit trails
- Test configuration – Validate configuration in staging before production
Configuration Reference
| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL | Yes | - | PostgreSQL connection string |
AUTH_JWT_SECRET | Yes | - | JWT signing secret (min 32 chars) |
PORT | No | 3000 | API port |
NODE_ENV | No | development | Node environment (development, test, production) |
LOG_LEVEL | No | info | Logging level (fatal, error, warn, info, debug, trace) |
AUTH_DEFAULT_TENANT | No | default | Default tenant ID |
AUTH_JWT_ISSUER | No | - | JWT issuer claim (optional) |
AUTH_JWT_AUDIENCE | No | - | JWT audience claim (optional) |
AUTH_DISABLED | No | false | Disable authentication (development only) |
LICENSE_KEY | No | - | License key from Terragnos (JWT format) |
LICENSE_PUBLIC_KEY | No | - | License verification key (RSA/PEM format) |
LICENSE_STORAGE_SECRET | No | - | License encryption key (32-byte string) |
REDIS_URL | No | - | Redis connection string (optional, for distributed caching) |
RATE_LIMIT_TTL | No | 60 | Rate limit window (seconds) |
RATE_LIMIT_LIMIT | No | 120 | Max requests per window |
LAYER_CACHE_TTL_SECONDS | No | 60 | Layer cache TTL (seconds) |
EVENT_STREAM_DISABLED | No | false | Disable PostgreSQL LISTEN/NOTIFY event stream |