Skip to content

Environment Variables

All UNDERWRITE_* environment variables override the corresponding JSON configuration field at runtime. Additional variables control risk model loading, notification channels, and secrets backend access.


Configuration Overrides

Parsed by Configuration.__apply_env_overrides() in underwrite/config.py:402.

Variable Required Default Description
UNDERWRITE_BUS_BACKEND No local Event bus backend (local, sqs, modal)
UNDERWRITE_BUS_RATE_LIMIT No 0 Max events/second per subscriber (0 = unlimited)
UNDERWRITE_BUS_MAX_WORKERS No 0 Thread pool size (0 = synchronous dispatch)
UNDERWRITE_BUS_MAX_FUTURES No 10000 Max pending futures before backpressure
UNDERWRITE_SQS_QUEUE_URL No "" AWS SQS queue URL (required when BUS_BACKEND=sqs)
UNDERWRITE_SQS_REGION No "" AWS region for SQS
UNDERWRITE_MODAL_QUEUE_NAME No "" Modal queue name (required when BUS_BACKEND=modal)
UNDERWRITE_STORE_BACKEND No sqlite Store backend (sqlite, memory)
UNDERWRITE_STORE_PATH No ./store.db SQLite database path. Use :memory: for ephemeral.
UNDERWRITE_STORE_BUSY_TIMEOUT No 30.0 Seconds to wait for a busy SQLite lock before raising.
UNDERWRITE_LOG_LEVEL No INFO Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
UNDERWRITE_LOG_OUTPUT No stdout Log output target
UNDERWRITE_LOG_FORMAT No text Log format (text, json)
UNDERWRITE_DATA_DIR No ./data Filesystem store data directory
UNDERWRITE_AUTHZ_ENABLED No true Enable access control
UNDERWRITE_AUTHZ_POLICY_FILE No "" Path to Rego/OPA policy file
UNDERWRITE_METRICS_ENABLED No true Enable metrics collection
UNDERWRITE_METRICS_EXPORT_INTERVAL No 60 Metrics export interval in seconds
UNDERWRITE_TRACING_ENABLED No false Enable distributed tracing
UNDERWRITE_TRACING_EXPORTER No console Tracer exporter (console, otlp, noop)
UNDERWRITE_SAGA_ENABLED No true Enable saga orchestration
UNDERWRITE_IDENTITY_KEY_TTL No 86400 Key rotation interval in seconds
UNDERWRITE_IDENTITY_KEY_GRACE No 3600 Key overlap grace period in seconds
UNDERWRITE_SECRETS_BACKEND No env Secrets backend (env, vault, aws)
UNDERWRITE_SECRETS_VAULT_URL No "" HashiCorp Vault server URL
UNDERWRITE_SECRETS_VAULT_TOKEN No "" Vault authentication token
UNDERWRITE_SECRETS_AWS_REGION No "" AWS region for Secrets Manager
UNDERWRITE_RECOVERY_AUTO_RESTART No true Auto-restart crashed services
UNDERWRITE_RECOVERY_MAX_RESTARTS No 3 Maximum restart attempts per service
UNDERWRITE_RECOVERY_BACKOFF No 1.0 Initial backoff in seconds (exponential)
UNDERWRITE_AUDIT_MAX_LEDGER No 100000 Max audit ledger entries before rotation
UNDERWRITE_AUDIT_EXPORT_URL No "" Audit log export endpoint

Environment Selector

Variable Required Default Description
UNDERWRITE_ENV No "" When set, loads config.{value}.json if no explicit config path is given

HTTP Server

Variable Required Default Description
UNDERWRITE_API_TOKEN No "" Bearer token required for all HTTP API requests (see --require-auth)

Risk Model

Variable Required Default Description
RISK_MODEL_PATH No "" Path to serialized risk model file
RISK_MODEL_SHA256 No "" Expected SHA-256 hash of the model file (integrity check)
UNDERWRITE_ALLOW_JOBLIB No "" Set to true to enable joblib deserialization for pickle-based models

Secrets Backend

Variable Required Default Description
VAULT_TOKEN No "" Vault token (alternative to UNDERWRITE_SECRETS_VAULT_TOKEN)
UNDERWRITE_SECRET_<NAME> No Read secrets from environment; key is uppercased with / and - replaced by _

RBI Pricing Caps (India)

The pricing service has static rate-cap defaults that are read by compute_rate_cap and validate_interest_rate. The four product-specific caps are:

Loan type Default cap RBI norm
Home 0.12 (12% p.a.) 12%
Gold 0.18 (18% p.a.) 18%
Personal 0.28 (28% p.a.) 28%
Micro 0.30 (30% p.a.) 30%
Default (other) 0.30 30%

These are constructed as kwargs at PricingService construction time and not overridden by environment variables. Construct a PricingService with custom caps:

from underwrite.services.pricing.service import PricingService

service = PricingService(
    service_id="pricing",
    rate_cap=0.24,
    penal_interest_cap=0.24,
)

UNDERWRITE_COOLING_OFF_DAYS is similarly not honoured at the Configuration layer — pass cooling_off_days=... to KfsService directly.

Over-cap requests are rejected with ProtocolError, not silently clamped to the cap. This is the RBI-required behaviour: the rate must be refused at origination, not laundered through post-hoc clamping.


AML / KYC (India)

Variable Required Default Description
AML_BLOCKLIST_PATH No "" Path to JSON blocklist for AML screening (PEPs, sanctions, etc.)
AML_THRESHOLD_LOW No 10 Score threshold for low-risk AML clearance
AML_THRESHOLD_FROZEN No 7 Score threshold above which borrower is frozen

Credit Bureau / CKYC (India)

Variable Required Default Description
UNDERWRITE_CREDIT_BUREAU_CIBIL_ENABLED No true Enable CIBIL credit report check
UNDERWRITE_CREDIT_BUREAU_CIBIL_API_KEY No "" CIBIL API key
UNDERWRITE_CREDIT_BUREAU_CIBIL_API_BASE No https://api.cibil.com/v1 CIBIL API base URL
UNDERWRITE_CREDIT_BUREAU_EXPERIAN_ENABLED No false Enable Experian credit report check
UNDERWRITE_CREDIT_BUREAU_EQUIFAX_ENABLED No false Enable Equifax credit report check
UNDERWRITE_CREDIT_BUREAU_CKYC_ENABLED No true Enable CKYC identity verification
UNDERWRITE_CREDIT_BUREAU_CKYC_API_KEY No "" CKYC registry API key
UNDERWRITE_CREDIT_BUREAU_CKYC_API_BASE No https://api.ckycindia.in/v1 CKYC API base URL

Razorpay Payment Gateway (India)

Variable Required Default Description
UNDERWRITE_RAZORPAY_KEY_ID No "" Razorpay API key ID
UNDERWRITE_RAZORPAY_KEY_SECRET No "" Razorpay API key secret
UNDERWRITE_RAZORPAY_WEBHOOK_SECRET No "" Razorpay webhook signing secret
UNDERWRITE_RAZORPAY_API_BASE_URL No https://api.razorpay.com/v1 Razorpay API base URL

DPDPA 2023 Compliance (India)

Variable Required Default Description
UNDERWRITE_DPDPA_DATA_RETENTION_YEARS No 8 Borrower data retention period per IT Act/DPDPA
UNDERWRITE_DPDPA_KYC_RETENTION_YEARS No 5 KYC data retention period per PMLA rules
UNDERWRITE_DPDPA_BREACH_NOTIFICATION_HOURS No 72 Breach notification window to Data Protection Board
UNDERWRITE_DPDPA_CONSENT_VALIDITY_DAYS No 365 Consent validity period for data processing
UNDERWRITE_DPDPA_DSR_RESPONSE_DAYS No 30 Data Subject Request fulfillment timeline
UNDERWRITE_DPDPA_DSR_GRIEVANCE_RESPONSE_DAYS No 15 Grievance response timeline
UNDERWRITE_DPDPA_DPO_EMAIL No "" Data Protection Officer email
UNDERWRITE_DPDPA_DPO_PHONE No "" Data Protection Officer phone

KFS (Key Fact Statement — India)

Variable Required Default Description
UNDERWRITE_KFS_COOLING_OFF_DAYS No 3 Free-look period after KFS issuance per RBI DLG
UNDERWRITE_KFS_DISCLOSURE_VERSION No 1.0 KFS template version

Notification Service

Variable Required Default Description
NOTIFICATION_EMAIL_ENABLED No false Enable email dispatch via SES
NOTIFICATION_SMS_ENABLED No false Enable SMS dispatch via Twilio
NOTIFICATION_EMAIL_SENDER No noreply@underwrite.local SES sender address
AWS_REGION No "" AWS region for SES (leave empty to log instead of sending)
TWILIO_ACCOUNT_SID No "" Twilio account SID
TWILIO_AUTH_TOKEN No "" Twilio auth token
TWILIO_FROM_NUMBER No "" Twilio SMS source phone number

Testing

Variable Required Default Description
UNDERWRITE_TEST_PG_DSN No "" Reserved. PostgreSQL backend is no longer supported; ignore.

Boolean Coercion

When an environment variable maps to a bool field, the string is considered true if it equals (case-insensitive) 1, true, or yes. All other values produce false.