Configuration Guide
CalcBridge uses environment variables for all configuration, following the twelve-factor app methodology. This guide provides a complete reference for all available settings.
Quick Setup
Copy the example environment file and customize:
# Copy the example file
cp .env.example .env
# Generate secure keys
python -c "import secrets; print(f'JWT_SECRET_KEY={secrets.token_urlsafe(32)}')"
python -c "import secrets; print(f'ENCRYPTION_MASTER_KEY={secrets.token_urlsafe(32)}')"
# Edit .env with your settings
code .env # or vim, nano, etc.
Environment Overview
| Environment | ENVIRONMENT Value | Purpose |
| Development | development | Local development, insecure defaults allowed |
| Staging | staging | Pre-production testing, warnings for insecure settings |
| Production | production | Live environment, strict security enforcement |
Production Security
In production, CalcBridge will refuse to start if security-critical settings use insecure defaults. This protects against accidental deployment with test credentials.
Core Settings
Application Settings
| Variable | Type | Default | Description |
ENVIRONMENT | string | development | Environment: development, staging, production |
DEBUG | bool | false | Enable debug mode (never in production) |
LOG_LEVEL | string | INFO | Logging level: DEBUG, INFO, WARNING, ERROR |
API_PREFIX | string | /api/v1 | API route prefix |
API_TITLE | string | CalcBridge API | API title in OpenAPI docs |
API_VERSION | string | 1.0.0 | API version |
.envENVIRONMENT=development
DEBUG=false
LOG_LEVEL=INFO
API_PREFIX=/api/v1
Security Settings
JWT Authentication
| Variable | Type | Default | Description |
JWT_SECRET_KEY | string | (insecure) | REQUIRED: JWT signing key (32+ chars) |
JWT_ALGORITHM | string | HS256 | JWT algorithm |
JWT_ACCESS_TOKEN_EXPIRE_MINUTES | int | 30 | Access token lifetime (5-1440) |
JWT_REFRESH_TOKEN_EXPIRE_DAYS | int | 7 | Refresh token lifetime (1-30) |
Generate Secure Keys
python -c "import secrets; print(secrets.token_urlsafe(32))"
.envJWT_SECRET_KEY=your-secure-random-key-at-least-32-characters
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
Encryption (PII Protection)
| Variable | Type | Default | Description |
ENCRYPTION_MASTER_KEY | string | (insecure) | REQUIRED: AES-256 encryption key (32+ chars) |
ENCRYPTION_PREVIOUS_MASTER_KEY | string | (none) | Previous key for rotation |
ENCRYPTION_KEY_ROTATION_ENABLED | bool | false | Enable key rotation mode |
.envENCRYPTION_MASTER_KEY=your-secure-encryption-key-at-least-32-chars
# For key rotation:
# ENCRYPTION_PREVIOUS_MASTER_KEY=old-key
# ENCRYPTION_KEY_ROTATION_ENABLED=true
Database Settings
PostgreSQL Connection
| Variable | Type | Default | Description |
DATABASE_URL | string | (local) | PostgreSQL connection URL |
DATABASE_POOL_SIZE | int | 20 | Connection pool size (1-100) |
DATABASE_MAX_OVERFLOW | int | 10 | Max overflow connections (0-50) |
DATABASE_POOL_PRE_PING | bool | true | Verify connections before use |
DATABASE_POOL_RECYCLE | int | 3600 | Recycle connections after N seconds |
DATABASE_ECHO | bool | false | Log SQL queries (debug only) |
DATABASE_APP_ROLE | string | calcbridge_app | Database role for RLS |
Database SSL
| Variable | Type | Default | Description |
DATABASE_SSL_MODE | string | prefer | SSL mode (see below) |
DATABASE_SSL_CERT_PATH | string | (none) | Client certificate path |
DATABASE_SSL_KEY_PATH | string | (none) | Client key path |
DATABASE_SSL_CA_PATH | string | (none) | CA certificate path |
SSL Mode Options:
| Mode | Security | Description |
disable | None | No SSL |
allow | Low | Try SSL, fall back to unencrypted |
prefer | Low | Try SSL, fall back to unencrypted (default) |
require | Medium | Require SSL, no certificate verification |
verify-ca | High | Verify server certificate against CA |
verify-full | Highest | Verify server certificate and hostname |
Production SSL
Use verify-full for production deployments.
.envDATABASE_URL=postgresql+psycopg://calcbridge:password@localhost:5433/calcbridge
DATABASE_POOL_SIZE=20
DATABASE_SSL_MODE=verify-full
DATABASE_SSL_CA_PATH=/certs/ca-cert.pem
Cache Settings (Valkey/Redis)
| Variable | Type | Default | Description |
VALKEY_HOST | string | localhost | Valkey/Redis host |
VALKEY_PORT | int | 6379 | Valkey/Redis port |
VALKEY_PASSWORD | string | (none) | Valkey/Redis password |
VALKEY_DB | int | 0 | Database number (0-15) |
VALKEY_SSL | bool | false | Enable SSL |
VALKEY_SSL_CERT_REQS | string | required | SSL certificate requirements |
VALKEY_SSL_CA_CERTS | string | (none) | CA certificate path |
VALKEY_MAX_CONNECTIONS | int | 50 | Max connection pool size |
VALKEY_SOCKET_TIMEOUT | float | 5.0 | Socket timeout (seconds) |
VALKEY_RETRY_ON_TIMEOUT | bool | true | Retry on timeout |
.envVALKEY_HOST=localhost
VALKEY_PORT=6380
VALKEY_PASSWORD=your-cache-password
VALKEY_SSL=true
Rate Limiting
| Variable | Type | Default | Description |
RATE_LIMIT_ENABLED | bool | true | Enable rate limiting |
RATE_LIMIT_WINDOW_SECONDS | int | 60 | Sliding window size |
RATE_LIMIT_DEFAULT_PER_IP | int | 100 | Default limit per IP |
RATE_LIMIT_TIER_FREE | int | 100 | Free tier requests/min |
RATE_LIMIT_TIER_STARTER | int | 500 | Starter tier requests/min |
RATE_LIMIT_TIER_PROFESSIONAL | int | 2000 | Professional tier requests/min |
RATE_LIMIT_TIER_ENTERPRISE | int | 10000 | Enterprise tier requests/min |
RATE_LIMIT_BURST_MULTIPLIER | float | 1.1 | Burst allowance (1.0-2.0) |
RATE_LIMIT_VERIFY_UNAUTH_PER_MINUTE | int | 10 | Unauthenticated rate limit for /exports/verify |
RATE_LIMIT_VERIFY_AUTH_PER_MINUTE | int | 100 | Authenticated rate limit for /exports/verify |
RATE_LIMIT_VERIFY_PATHS | list | /api/v1/exports/verify | Paths that use verify rate limits |
Subscription Tiers
| Tier | Requests/Minute | Burst Limit | Use Case |
| Free | 100 | 110 | Individual users, trials |
| Starter | 500 | 550 | Small teams |
| Professional | 2,000 | 2,200 | Medium organizations |
| Enterprise | 10,000 | 11,000 | Large organizations, API integrations |
.envRATE_LIMIT_ENABLED=true
RATE_LIMIT_TIER_PROFESSIONAL=2000
RATE_LIMIT_VERIFY_UNAUTH_PER_MINUTE=10
RATE_LIMIT_VERIFY_AUTH_PER_MINUTE=100
File Processing
| Variable | Type | Default | Description |
FILE_PROCESSING_CELERY_THRESHOLD_BYTES | int | 5242880 | File size threshold for Celery (5MB) |
FILE_PROCESSING_EXECUTOR_MAX_WORKERS | int | 4 | Thread pool size for parsing |
FILE_PROCESSING_EXECUTOR_TIMEOUT_SECONDS | int | 1200 | Parser timeout (20 min) |
MAX_UPLOAD_SIZE_MB | int | 100 | Maximum upload size |
File Storage
| Variable | Type | Default | Description |
STORAGE_BACKEND | string | local | Storage backend: local or s3 |
STORAGE_LOCAL_ROOT | string | uploads | Local storage directory |
STORAGE_S3_BUCKET | string | (none) | S3 bucket name (required if backend=s3) |
STORAGE_S3_REGION | string | us-east-1 | AWS region |
STORAGE_S3_ACCESS_KEY | string | (none) | AWS access key |
STORAGE_S3_SECRET_KEY | string | (none) | AWS secret key |
STORAGE_S3_ENDPOINT_URL | string | (none) | Custom endpoint (MinIO) |
STORAGE_PRESIGNED_URL_EXPIRE_SECONDS | int | 3600 | Presigned URL expiration |
.env# Local storage (development)
STORAGE_BACKEND=local
STORAGE_LOCAL_ROOT=uploads
# S3 storage (production)
STORAGE_BACKEND=s3
STORAGE_S3_BUCKET=calcbridge-uploads
STORAGE_S3_REGION=us-east-1
Evidence Storage (Compliance)
| Variable | Type | Default | Description |
CALCBRIDGE_EVIDENCE_ENABLED | bool | false | Enable evidence storage |
CALCBRIDGE_EVIDENCE_BACKEND | string | local | Evidence storage backend |
CALCBRIDGE_EVIDENCE_LOCAL_ROOT | string | evidence | Local evidence root |
CALCBRIDGE_EVIDENCE_S3_BUCKET | string | (none) | S3 bucket for evidence storage |
CALCBRIDGE_EVIDENCE_S3_REGION | string | us-east-1 | Evidence bucket region |
CALCBRIDGE_EVIDENCE_S3_ENDPOINT_URL | string | (none) | Custom S3 endpoint (MinIO/LocalStack) |
CALCBRIDGE_EVIDENCE_OBJECT_LOCK_MODE | string | COMPLIANCE | Object Lock mode |
CALCBRIDGE_EVIDENCE_ENFORCE_OBJECT_LOCK | bool | true | Require Object Lock + versioning checks when using S3 |
CALCBRIDGE_EVIDENCE_RETENTION_YEARS | int | 7 | Default retention period (years) |
CALCBRIDGE_EVIDENCE_JURISDICTION_MIN_YEARS | map | (none) | Jurisdiction minimums (JSON or US:5,UK:5) |
CALCBRIDGE_EVIDENCE_KMS_KEY_ID | string | (none) | KMS key ARN/ID for SSE‑KMS |
CALCBRIDGE_EVIDENCE_SSE_MODE | string | kms | Server‑side encryption mode (kms, s3, none) |
Compliance Stream Keys
| Variable | Type | Default | Description |
CALCBRIDGE_STREAM_KEY_STRICT | bool | true | Enforce canonical deal:<scheme>:<id> keys |
CALCBRIDGE_STREAM_KEY_ALLOWED_SCHEMES | list | sui,trustee,internal,sec | Allowed schemes |
CALCBRIDGE_STREAM_KEY_DEFAULT_SCHEME | string | trustee | Scheme used when auto-normalizing |
CALCBRIDGE_STREAM_KEY_ALLOW_NON_DEAL_KEYS | list | tenant | Non-deal keys allowed when strict |
CALCBRIDGE_STREAM_KEY_AUTO_NORMALIZE | bool | true | Auto-normalize non-canonical keys |
CALCBRIDGE_STREAM_KEY_MAX_LENGTH | int | 100 | Maximum stream key length |
Timestamping (RFC3161 TSA)
| Variable | Type | Default | Description |
CALCBRIDGE_TSA_ENABLED | bool | false | Enable RFC3161 timestamping |
CALCBRIDGE_TSA_PRIMARY_URL | string | (none) | Primary TSA URL (GlobalSign) |
CALCBRIDGE_TSA_FALLBACK_URL | string | (none) | Fallback TSA URL (DigiCert) |
CALCBRIDGE_TSA_PRIMARY_NAME | string | globalsign | Primary TSA provider label |
CALCBRIDGE_TSA_FALLBACK_NAME | string | digicert | Fallback TSA provider label |
CALCBRIDGE_TSA_SECRETS_MANAGER_ENABLED | bool | false | Enable Secrets Manager lookups for TSA credentials |
CALCBRIDGE_TSA_USERNAME | string | (none) | Primary TSA username |
CALCBRIDGE_TSA_USERNAME_ARN | string | (none) | Secrets Manager ARN/name for primary TSA username |
CALCBRIDGE_TSA_PASSWORD | string | (none) | Primary TSA password |
CALCBRIDGE_TSA_PASSWORD_ARN | string | (none) | Secrets Manager ARN/name for primary TSA password |
CALCBRIDGE_TSA_FALLBACK_USERNAME | string | (none) | Fallback TSA username |
CALCBRIDGE_TSA_FALLBACK_USERNAME_ARN | string | (none) | Secrets Manager ARN/name for fallback TSA username |
CALCBRIDGE_TSA_FALLBACK_PASSWORD | string | (none) | Fallback TSA password |
CALCBRIDGE_TSA_FALLBACK_PASSWORD_ARN | string | (none) | Secrets Manager ARN/name for fallback TSA password |
CALCBRIDGE_TSA_API_KEY | string | (none) | Optional TSA API key |
CALCBRIDGE_TSA_API_KEY_ARN | string | (none) | Secrets Manager ARN/name for TSA API key |
CALCBRIDGE_TSA_AUTH_HEADER | string | Authorization | Header used for TSA API key |
CALCBRIDGE_TSA_TIMEOUT_SECONDS | int | 30 | TSA request timeout (seconds) |
CALCBRIDGE_TSA_VERIFY_SSL | bool | true | Verify TLS certificates |
CALCBRIDGE_TSA_HASH_ALGORITHM | string | sha256 | Hash algorithm for TSA requests |
CALCBRIDGE_TSA_SECRETS_MANAGER_REGION | string | (none) | Secrets Manager region override |
CALCBRIDGE_TSA_SECRETS_MANAGER_ENDPOINT_URL | string | (none) | Secrets Manager endpoint override |
Celery Settings
| Variable | Type | Default | Description |
CELERY_TASK_SOFT_TIME_LIMIT | int | 1200 | Soft time limit (20 min) |
CELERY_TASK_TIME_LIMIT | int | 1320 | Hard time limit (22 min) |
CELERY_WORKER_CONCURRENCY | int | 4 | Worker concurrency |
CELERY_WORKER_PREFETCH_MULTIPLIER | int | 4 | Task prefetch multiplier |
CELERY_WORKER_MAX_TASKS_PER_CHILD | int | 1000 | Tasks before worker restart |
.envCELERY_TASK_SOFT_TIME_LIMIT=1200
CELERY_WORKER_CONCURRENCY=4
CORS Settings
| Variable | Type | Default | Description |
CORS_ORIGINS | list | ["localhost:3002"] | Allowed origins |
CORS_METHODS | list | ["GET","POST",...] | Allowed HTTP methods |
CORS_HEADERS | list | ["Authorization",...] | Allowed headers |
CORS_ALLOW_CREDENTIALS | bool | true | Allow credentials |
CORS_MAX_AGE | int | 600 | Preflight cache (seconds) |
.envCORS_ORIGINS=["https://app.yourdomain.com","https://admin.yourdomain.com"]
Observability
OpenTelemetry
| Variable | Type | Default | Description |
OTEL_ENABLED | bool | false | Enable OpenTelemetry |
OTEL_SERVICE_NAME | string | calcbridge | Service name |
OTEL_SERVICE_VERSION | string | 1.0.0 | Service version |
OTEL_ENDPOINT | string | (none) | OTLP endpoint |
OTEL_EXPORTER_TYPE | string | otlp | Exporter: otlp, console, none |
OTEL_PROTOCOL | string | grpc | Protocol: grpc or http |
OTEL_TRACES_SAMPLE_RATE | float | 1.0 | Sampling rate (0.0-1.0) |
Sentry
| Variable | Type | Default | Description |
SENTRY_DSN | string | (none) | Sentry DSN |
SENTRY_ENVIRONMENT | string | (auto) | Sentry environment |
SENTRY_TRACES_SAMPLE_RATE | float | 0.1 | Transaction sample rate |
SENTRY_PROFILES_SAMPLE_RATE | float | 0.1 | Profiling sample rate |
SENTRY_SEND_DEFAULT_PII | bool | false | Send PII data |
Prometheus
| Variable | Type | Default | Description |
PROMETHEUS_ENABLED | bool | true | Enable metrics endpoint |
PROMETHEUS_ENDPOINT | string | /metrics | Metrics path |
PROMETHEUS_REQUIRE_AUTH | bool | false | Require authentication |
PROMETHEUS_AUTH_TOKEN | string | (none) | Bearer token for auth |
.env# OpenTelemetry
OTEL_ENABLED=true
OTEL_ENDPOINT=http://otel-collector:4317
OTEL_TRACES_SAMPLE_RATE=0.1
# Sentry
SENTRY_DSN=https://xxx@sentry.io/xxx
SENTRY_TRACES_SAMPLE_RATE=0.1
# Prometheus
PROMETHEUS_ENABLED=true
Alerting
| Variable | Type | Default | Description |
ALERTING_ENABLED | bool | false | Enable alerting |
ALERTING_DEFAULT_PROVIDER | string | pagerduty | Default provider |
ALERTING_PAGERDUTY_ROUTING_KEY | string | (none) | PagerDuty routing key |
ALERTING_OPSGENIE_API_KEY | string | (none) | OpsGenie API key |
ALERTING_SLACK_WEBHOOK_URL | string | (none) | Slack webhook URL |
ALERTING_RATE_LIMIT_PER_MINUTE | int | 10 | Alert rate limit |
.envALERTING_ENABLED=true
ALERTING_DEFAULT_PROVIDER=slack
ALERTING_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/xxx
| Variable | Type | Default | Description |
SECURITY_HEADERS_ENABLED | bool | true | Enable security headers |
SECURITY_HEADERS_HSTS_ENABLED | bool | true | Enable HSTS |
SECURITY_HEADERS_HSTS_MAX_AGE | int | 31536000 | HSTS max-age (1 year) |
SECURITY_HEADERS_CSP_ENABLED | bool | true | Enable CSP |
SECURITY_HEADERS_FRAME_OPTIONS | string | DENY | X-Frame-Options |
Request Limits
Size Limits
| Variable | Type | Default | Description |
REQUEST_SIZE_ENABLED | bool | true | Enable size limits |
REQUEST_SIZE_DEFAULT_LIMIT_BYTES | int | 10485760 | Default limit (10MB) |
REQUEST_SIZE_UPLOAD_LIMIT_BYTES | int | 104857600 | Upload limit (100MB) |
Timeout Settings
| Variable | Type | Default | Description |
REQUEST_TIMEOUT_ENABLED | bool | true | Enable timeouts |
REQUEST_TIMEOUT_DEFAULT_SECONDS | float | 30.0 | Default timeout |
REQUEST_TIMEOUT_HEALTH_CHECK_SECONDS | float | 5.0 | Health check timeout |
REQUEST_TIMEOUT_UPLOAD_ENDPOINT_SECONDS | float | 1200.0 | Upload timeout (20 min) |
REQUEST_TIMEOUT_CALCULATION_ENDPOINT_SECONDS | float | 60.0 | Calculation timeout |
Export Verification & Provenance
| Variable | Type | Default | Description |
CALCBRIDGE_HMAC_SECRET | string | INSECURE-DEFAULT-HMAC-CHANGE-IN-PRODUCTION | HMAC secret for export provenance |
CALCBRIDGE_HMAC_SECRET_ARN | string | (none) | Secrets Manager ARN/name for HMAC secret |
CALCBRIDGE_HMAC_SECRETS_MANAGER_ENABLED | bool | false | Enable Secrets Manager lookups for HMAC secrets |
CALCBRIDGE_HMAC_PREVIOUS_SECRETS | list | (none) | Previous HMAC secrets for rotation |
CALCBRIDGE_HMAC_PREVIOUS_SECRET_ARNS | list | (none) | Previous HMAC secret ARNs/names |
CALCBRIDGE_HMAC_SECRETS_MANAGER_REGION | string | (none) | Secrets Manager region override |
CALCBRIDGE_HMAC_SECRETS_MANAGER_ENDPOINT_URL | string | (none) | Secrets Manager endpoint (LocalStack) |
CALCBRIDGE_VERIFY_TIMEOUT_SECONDS | float | 15.0 | Timeout for verification hashing |
CALCBRIDGE_VERIFY_MAX_UNCOMPRESSED_BYTES | int | 262144000 | Max decompressed bytes for verify uploads |
CALCBRIDGE_VERIFY_MAX_COMPRESSION_RATIO | int | 100 | Max compression ratio for verify uploads |
CALCBRIDGE_VERIFY_MAX_FILE_COUNT | int | 5000 | Max file count inside verify uploads |
CALCBRIDGE_VERIFY_SANDBOX_ENABLED | bool | true | Run verify pipeline in sandbox |
CALCBRIDGE_VERIFY_SANDBOX_MODE | string | process | Sandbox mode (process or container) |
CALCBRIDGE_VERIFY_SANDBOX_CPU_SECONDS | int | 10 | CPU limit for verify sandbox |
CALCBRIDGE_VERIFY_SANDBOX_MEMORY_MB | int | 512 | Memory limit for verify sandbox |
CALCBRIDGE_VERIFY_SANDBOX_CONTAINER_IMAGE | string | calcbridge-verify-sandbox:latest | Container image for sandbox mode |
CALCBRIDGE_VERIFY_SANDBOX_CONTAINER_RUNTIME | string | (none) | Container runtime override (e.g., runsc) |
CALCBRIDGE_VERIFY_SANDBOX_CONTAINER_SECCOMP_PROFILE | string | (none) | Seccomp profile path for container sandbox |
CALCBRIDGE_VERIFY_SANDBOX_CONTAINER_CPUS | float | 1.0 | CPU limit for container sandbox |
CALCBRIDGE_VERIFY_TEMP_RETENTION_HOURS | int | 24 | Retention for temporary verify uploads |
List values accept comma-separated strings or JSON arrays.
Signing Service
| Variable | Type | Default | Description |
CALCBRIDGE_SIGNING_ENABLED | bool | false | Enable external signing service |
CALCBRIDGE_SIGNING_BASE_URL | string | (none) | Signing service base URL |
CALCBRIDGE_SIGNING_API_KEY | string | (none) | Signing service API key |
CALCBRIDGE_SIGNING_AUTH_HEADER | string | Authorization | Auth header name |
CALCBRIDGE_SIGNING_PDF_ENDPOINT | string | /sign/pdf | PDF signing endpoint |
CALCBRIDGE_SIGNING_OOXML_ENDPOINT | string | /sign/ooxml | OOXML signing endpoint |
CALCBRIDGE_SIGNING_TIMEOUT_SECONDS | int | 30 | Signing request timeout |
CALCBRIDGE_SIGNING_VERIFY_SSL | bool | true | Verify TLS when calling signing service |
CALCBRIDGE_EVIDENCE_PACKAGING_SEAL_ENABLED | bool | false | Enable sealing of evidence packages |
CALCBRIDGE_EVIDENCE_PACKAGING_SEAL_PROVIDER | string | signing_service | Sealing provider |
Dead Letter Queue
| Variable | Type | Default | Description |
DLQ_MESSAGE_TTL_DAYS | int | 7 | DLQ entry retention |
DLQ_MAX_ENTRIES | int | 10000 | Max DLQ entries |
DLQ_ALERT_THRESHOLD_TOTAL | int | 100 | Alert threshold |
DLQ_CLEANUP_INTERVAL_HOURS | int | 24 | Cleanup interval |
Complete Example
Here is a complete production .env file:
.env.production# Environment
ENVIRONMENT=production
DEBUG=false
LOG_LEVEL=INFO
# Security (REQUIRED - Replace with real values)
JWT_SECRET_KEY=your-production-jwt-secret-key-minimum-32-chars
ENCRYPTION_MASTER_KEY=your-production-encryption-key-minimum-32-chars
# Database
DATABASE_URL=postgresql+psycopg://calcbridge:strong-password@db.internal:5432/calcbridge
DATABASE_POOL_SIZE=20
DATABASE_SSL_MODE=verify-full
DATABASE_SSL_CA_PATH=/certs/ca.pem
# Cache
VALKEY_HOST=cache.internal
VALKEY_PORT=6379
VALKEY_PASSWORD=strong-cache-password
VALKEY_SSL=true
# Storage
STORAGE_BACKEND=s3
STORAGE_S3_BUCKET=calcbridge-prod
STORAGE_S3_REGION=us-east-1
# CORS
CORS_ORIGINS=["https://app.calcbridge.com"]
# Rate Limiting
RATE_LIMIT_ENABLED=true
# Observability
OTEL_ENABLED=true
OTEL_ENDPOINT=http://otel-collector:4317
SENTRY_DSN=https://xxx@sentry.io/xxx
# Alerting
ALERTING_ENABLED=true
ALERTING_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/xxx
Validation
CalcBridge validates configuration at startup:
# Test configuration
PYTHONPATH=. python -c "from src.core.config import get_settings; s = get_settings(); print(f'Environment: {s.environment}')"
# View all settings (development only)
PYTHONPATH=. python -c "from src.core.config import get_settings; print(get_settings().model_dump_json(indent=2))"
If production has insecure settings, you will see:
CRITICAL SECURITY ERROR: Insecure settings detected in production!
============================================================
The following issues MUST be resolved before starting:
- JWT_SECRET_KEY contains insecure default value
- ENCRYPTION_MASTER_KEY contains insecure default value