← Back to Table of Contents ← Back to Deployment

8.1 Environment Setup and Variables

This page documents the environment contract for the current application. The managed Azure deployment is authoritative for production; local development and historical single-database containers use smaller profiles.

Do not copy a production environment from an old MySQL example or from the retired installer. For Azure, use deploy/azure/main.bicep and its parameter files so web and job roles receive the same database, secret, storage, mail, and telemetry settings.

Configuration profiles

Profile Database Tenancy Cache/session Secrets Storage
Managed Azure production PostgreSQL default + platform + tenant databases Enabled Redis + cache-backed sessions Encrypted platform database, master key supplied by Key Vault Azure Blob through managed identity
Managed Azure POC/staging PostgreSQL default + platform + tenant databases Enabled Redis when provisioned; local fallback is not production-safe Same database driver after bootstrap/import Azure Blob through managed identity
Local development/test MySQL or PostgreSQL Optional APCu/file/PHP, or local Redis chain (environment then local file) Local by default
Historical self-hosted MariaDB/MySQL or BYO Single database Local, optional Redis Legacy environment/file Local or legacy cloud credentials

The historical profile is unsupported for new managed deployments.

Loading and precedence

Production should inject process environment variables and should not ship app/config/.env. KMP loads a local dotenv file only when that file exists and one of these conditions is true:

When loaded, the dotenv loader is configured to overwrite existing values. Consequently, an unexpected app/config/.env can override process settings. Keep it out of managed images and deployments.

CakePHP then loads app/config/app.php and optional app/config/app_local.php overrides. The production image generates app_local.php from the runtime environment.

Never commit environment files, connection URLs, SMTP passwords, storage keys, database passwords, recovery keys, or KEKs.

Managed application and role variables

Variable Purpose Managed value/notes
KMP_ENV Runtime environment label production in production
DEBUG CakePHP debug output false
APP_NAME Deployment/application label Set by Bicep
RELEASE_CHANNEL / IMAGE_TAG Health and telemetry release identity Bicep sets the channel; the image normally supplies config/version.txt, and IMAGE_TAG is an optional override
REQUIRE_HTTPS Secure-cookie and HTTPS behavior true
TRUST_PROXY Honor approved proxy headers true behind Container Apps
TRUSTED_PROXY_IPS Optional explicit proxy allowlist Prefer an explicit list where the platform provides stable ranges
KMP_TENANCY_ENABLED Enable host-based tenant resolution true in managed environments
KMP_SKIP_MIGRATIONS Suppress production-image startup migrations true on web and worker jobs; the migration job runs the command chain explicitly
KMP_SKIP_CRON Suppress in-container cron true on every managed web/job role

Do not use the web process as a scheduler or migration authority.

Database and tenancy

Variable Purpose Notes
KMP_DB_DRIVER Database family postgres for managed Azure
DATABASE_URL Default application datasource Secret URL for the default/rehearsal database
PLATFORM_DATABASE_URL Platform metadata datasource Required for managed tenancy
DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD, DB_DATABASE Split default datasource settings Useful locally when no URL is supplied
PLATFORM_DB_HOST, PLATFORM_DB_PORT, PLATFORM_DB_USERNAME, PLATFORM_DB_PASSWORD, PLATFORM_DB_DATABASE Split platform datasource settings Useful for local POC/rehearsal
DATABASE_TEST_URL / PLATFORM_DATABASE_TEST_URL Test datasources Never point tests at production

The platform database stores the tenant registry, host mappings, platform users, encrypted secret rows, job/schedule state, backup metadata, and audit events. It must not be used for tenant application records. Each managed tenant registry row selects its own PostgreSQL database and secret references.

The Azure migration job owns the required order documented in Deployment. Do not run migrations from multiple web replicas.

Cache and sessions

Variable Purpose Managed value/notes
CACHE_ENGINE Application cache backend redis in production
REDIS_URL Redis endpoint including TLS/password when required Key Vault-backed Container Apps secret
REDIS_PERSISTENT Reuse PHP worker Redis connections Enabled by the current production profile
KMP_SESSION_DEFAULTS CakePHP session backend cache with Redis
KMP_SESSION_CACHE_CONFIG Cache config used for sessions default
KMP_SESSION_COOKIE_SECURE Require secure session cookies true outside local HTTP development

If Redis is requested but unavailable, KMP logs a warning and falls back to a local cache. /health treats that fallback as degraded when shared Redis/cache sessions were requested. Do not serve multi-replica production traffic with per-process APCu/file caches or PHP file sessions.

Database-backed secrets

Variable Purpose Managed value/notes
KMP_SECRETS_DRIVER Secret-store driver database
KMP_SECRETS_DB_CONNECTION Datasource containing encrypted secret rows platform
KMP_SECRETS_DB_NAMESPACE Secret row namespace platform
KMP_SECRETS_DB_MASTER_DRIVER Source of the database store’s master key env
KMP_SECRETS_DB_MASTER_KEY_NAME Portable master-key name platform.master_kek
KMP_SECRET_PLATFORM_MASTER_KEK Master wrapping key resolved by the env driver Key Vault-backed; never stored in the platform DB
KMP_SECRETS_DB_KEY_NAME / KMP_SECRETS_DB_KEY_VERSION Metadata for encrypted rows Defaults platform-secrets / v1
KMP_SECRETS_FILE Local writable file store Local/dev only
KMP_SECRETS_ENV_PREFIX Legacy env secret prefix Defaults KMP_SECRET_

The migration job runs:

bin/cake platform secrets import-env
bin/cake platform backup-keys ensure --allow-read-only

import-env is a transition step. It imports only missing legacy values after platform migrations; database values and tombstones win. Remove legacy KMP_SECRET_* values only after a successful import deployment. A missing database master key is a hard failure once the database driver is active.

BACKUP_ENCRYPTION_KEY is the passphrase for the bundled destructive POC seed archive. It is not the KEK used by new managed tenant or platform backups.

Platform Admin

Platform Admin runs in the same web application on reserved hosts. It is not a separate Container App and does not trust an upstream identity header.

Variable Purpose Safe production value
KMP_PLATFORM_ADMIN_PORTAL_ENABLED Enable Platform Admin routes true only on an environment with an approved reserved host
KMP_PLATFORM_ADMIN_HOSTS Comma-separated reserved admin hosts Explicit host(s), or the Container App default host when intentionally used
KMP_PLATFORM_ADMIN_ALLOWED_STATUSES Permitted platform_users.status values active
KMP_PLATFORM_ADMIN_DETAILED_LOGIN_ERRORS Distinguish password/MFA errors false
KMP_PLATFORM_DATA_CONSOLE_ENABLED Enable privileged data-console routes false unless separately reviewed
PLATFORM_ADMIN_TOTP_WINDOW, PLATFORM_ADMIN_TOTP_PERIOD, PLATFORM_ADMIN_TOTP_DIGITS, PLATFORM_ADMIN_TOTP_ALGORITHM TOTP validation parameters Keep defaults unless an approved migration changes them

Authentication uses platform-user email/password plus TOTP, lockout, allowed status, and a host-bound session. Bootstrap a local operator only after platform migrations:

bin/cake platform admin bootstrap --email admin@example.org

The command emits one-time credentials and recovery material. Capture them in an approved password manager, never in a ticket or screenshot.

Email

The production image supports SMTP and API transports. The managed template uses SMTP:

Variable Purpose
EMAIL_DRIVER smtp, azure, sendgrid, or resend
EMAIL_SMTP_HOST / EMAIL_SMTP_PORT SMTP endpoint
EMAIL_SMTP_USERNAME / EMAIL_SMTP_PASSWORD SMTP credentials
EMAIL_SMTP_TLS Enable SMTP TLS
EMAIL_FROM Sender address
EMAIL_TRANSPORT_DEFAULT_URL Optional complete CakePHP transport URL

Do not use the stale SMTP_* or EMAIL_FROM_ADDRESS names from historical examples unless an application-specific override explicitly reads them.

Documents and managed backup objects

Variable Purpose Managed value/notes
DOCUMENT_STORAGE_ADAPTER local, azure, or s3 azure
AZURE_STORAGE_AUTH_MODE Azure authentication method managedIdentity
AZURE_STORAGE_ACCOUNT_NAME Storage account Non-secret
AZURE_CLIENT_ID User-assigned managed identity client ID Non-secret
AZURE_STORAGE_CONTAINER_PREFIX Prefix for derived tenant document containers documents by default
AZURE_STORAGE_CONNECTION_STRING Legacy/dev shared-key authentication Do not use in managed Azure
AWS_S3_BUCKET / AWS_DEFAULT_REGION Canonical S3 bucket/region Historical or alternate deployment
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN S3 credentials Prefer workload identity/IAM roles
AWS_S3_PREFIX / AWS_S3_ENDPOINT / AWS_S3_USE_PATH_STYLE_ENDPOINT S3-compatible tuning Optional

The managed Azure identity currently has Blob Data Contributor at the storage account scope. Tenant-specific container names and object prefixes are logical application isolation, not separate per-tenant Azure identities or RBAC grants. The same configured Flysystem backend stores encrypted managed backup objects under scoped tenants/<slug>/ and platform/ keys.

Local managed-backup adapters are disabled by default. The KMP_LOCAL_BACKUPS_ENABLED, KMP_LOCAL_BACKUPS_PATH, KMP_PLATFORM_LOCAL_BACKUPS_ENABLED, and KMP_PLATFORM_LOCAL_BACKUPS_PATH overrides exist for local/historical recovery, not ephemeral production replicas.

Telemetry and health

The production Bicep profile enables Application Insights and managed OTLP transport. Important controls include:

Variable Purpose
APPINSIGHTS_TRANSPORT otlp for the managed agent or direct as a rollback path
APPINSIGHTS_CONNECTION_STRING Required only for direct application export
OTEL_EXPORTER_OTLP_ENDPOINT OTLP endpoint when supplied to the app runtime
APPINSIGHTS_LOG_ENABLED / APPINSIGHTS_ERROR_LOG_ENABLED Trace/error export
APPINSIGHTS_QUERY_LOG_ENABLED / APPINSIGHTS_QUERY_SAMPLE_RATE Sanitized sampled query telemetry
APPINSIGHTS_CLOUD_ROLE Deployment role label
PERF_REQUEST_LOG_ENABLED / PERF_LOG_ALL_REQUESTS Request timing
PERF_DB_QUERY_LOG_ENABLED Database query timing
PLATFORM_TENANT_TELEMETRY_ENABLED / PLATFORM_TENANT_SLOW_REQUEST_MS Per-tenant fleet health inputs

Validate effective non-secret settings and writable paths:

cd app
bin/cake telemetry_check
bin/cake telemetry_check --send

Use /livez for liveness, /health for default DB plus cache readiness, and bin/cake platform_health --json for the platform datasource.

Platform audit WORM mirror

Variable Purpose Current status
PLATFORM_AUDIT_WORM_SINK disabled or file Defaults to disabled
PLATFORM_AUDIT_WORM_FILE_PATH Local append-only JSONL path Local/dev only
PLATFORM_AUDIT_WORM_FAIL_CLOSED Propagate mirror failure Defaults to false

The azure_blob sink throws a not-implemented error. The Azure template does not provision an immutable audit container or set PLATFORM_AUDIT_WORM_*. The file sink adds redaction, digests, and a mirror hash chain, but filesystem append is not storage-enforced WORM. Production immutability, retention/legal hold, monitoring, and continuity evidence are external prerequisites until the cloud sink is implemented.

Minimal non-secret managed profile

Secure values below are supplied through Key Vault references, not a committed file:

KMP_ENV=production
KMP_DB_DRIVER=postgres
KMP_TENANCY_ENABLED=true
KMP_SECRETS_DRIVER=database
KMP_SECRETS_DB_MASTER_DRIVER=env
KMP_SECRETS_DB_MASTER_KEY_NAME=platform.master_kek
CACHE_ENGINE=redis
KMP_SESSION_DEFAULTS=cache
KMP_SESSION_CACHE_CONFIG=default
DOCUMENT_STORAGE_ADAPTER=azure
AZURE_STORAGE_AUTH_MODE=managedIdentity
REQUIRE_HTTPS=true
TRUST_PROXY=true
KMP_SKIP_MIGRATIONS=true
KMP_SKIP_CRON=true
DEBUG=false

Required secret references include DATABASE_URL, PLATFORM_DATABASE_URL, SECURITY_SALT, KMP_SECRET_PLATFORM_MASTER_KEK, REDIS_URL, SMTP credentials, and the POC seed BACKUP_ENCRYPTION_KEY where that destructive job is enabled.

Rotation and verification

A Key Vault value change is not automatically a complete application rotation. Container Apps secret references, web revisions, and every affected job must resolve the new version. Database-stored tenant passwords and KEKs have their own audited rotation paths; changing a similarly named Key Vault value does not rotate those rows.

After configuration changes, verify the affected role rather than restarting only web:

bin/cake platform_health --json
bin/cake platform backup-keys ensure --allow-read-only
bin/cake telemetry_check
curl -fsS https://<approved-host>/livez
curl -fsS https://<approved-host>/health

For the complete production values and resource wiring, read deploy/azure/main.bicep and the Azure runbook. For local defaults, read app/config/.env.example, app/config/app.php, and app/config/secrets.php.