--- since: 1.2.1 --- # DjangoPlay Environment Configuration Reference This document provides detailed information about the four configuration files created by: ```bash curl -fsSL https://install.djangoplay.org/config | sudo bash ``` Every key is marked **Required** or **Optional**. Optional means it is not needed for a normal installation; it becomes relevant when its feature or integration is enabled. This document is the complete key-by-key reference for the four configuration files used by DjangoPlay: ```text ~/.dplay/ ├── .secrets ├── .authx ├── config.yaml └── .appdata ```` This is a **configuration reference**, not a deployment checklist. Each configuration key is classified according to when it is needed: | Requirement | Meaning | | ------------------------------ | ------------------------------------------------------------------------------- | | **Setup — Required** | Required by installation, bootstrap, or initial application setup. | | **Runtime — Required** | Required by the running DjangoPlay/AuthX service. | | **Setup + Runtime — Required** | Required during setup and subsequently required by the running service. | | **Runtime — Optional** | Required only when the corresponding runtime feature or integration is enabled. | | **Tooling — Optional** | Used only by optional development, reference-data, or maintenance tooling. | Optional configuration should only be populated when the corresponding feature is actually being used. > **Security:** `.secrets` and `.authx` contain sensitive values. Never commit > them to source control or expose private keys and service credentials to > clients. --- ## 1. Configuration Files | File | Purpose | Consumer | | ---------------------- | --------------------------------------------------------------------- | ---------------------- | | `~/.dplay/.secrets` | DjangoPlay secrets, credentials, and optional integration credentials | DjangoPlay | | `~/.dplay/.authx` | AuthX Identity service configuration | AuthX | | `~/.dplay/config.yaml` | Structured, non-secret DjangoPlay configuration | DjangoPlay | | `~/.dplay/.appdata` | Optional reference-data configuration | Reference-data tooling | The files are intentionally separated by responsibility. * `.secrets` contains sensitive DjangoPlay configuration. * `.authx` contains the environment configuration expected by AuthX. * `config.yaml` contains structured, non-secret DjangoPlay configuration. * `.appdata` contains optional reference-data configuration. The scaffold creates these files with restrictive permissions: ```text ~/.dplay/ 700 configuration files 600 ``` --- ## 2. `~/.dplay/.secrets` `.secrets` contains DjangoPlay's sensitive application configuration. ### DjangoPlay Core | Key | Value / Example | Requirement | Used by | Description / When needed | | ------------------- | --------------------------------------------- | ---------------------- | ---------- | ---------------------------------------------------------------------------------------------------------- | | `ENCRYPTION_KEY` | `` | **Runtime — Required** | DjangoPlay | Master key used by DjangoPlay's environment-encryption workflow. | | `DJANGO_SECRET_KEY` | `` | **Runtime — Required** | DjangoPlay | Django cryptographic secret key. | | `DB_PASSWORD` | `` | **Runtime — Required** | DjangoPlay | Password for the DjangoPlay PostgreSQL user defined by `database.user` in `config.yaml`. | | `DATABASE_URL` | `postgresql://user:password@host:5432/dbname` | **Runtime — Required** | DjangoPlay | PostgreSQL connection URL for DjangoPlay. | | `JWT_SIGNING_KEY` | `` | **Runtime — Required** | DjangoPlay | Secret used by DjangoPlay's own JWT-related functionality. This is separate from AuthX's RSA signing keys. | ### Initial Superuser | Key | Value / Example | Requirement | Used by | Description / When needed | | -------------------- | --------------- | -------------------- | ---------------- | ----------------------------------------------- | | `SUPERUSER_USERNAME` | `` | **Setup — Required** | DjangoPlay setup | Username for the initial Django superuser. | | `SUPERUSER_EMAIL` | `` | **Setup — Required** | DjangoPlay setup | Email address for the initial Django superuser. | | `SUPERUSER_PASSWORD` | `` | **Setup — Required** | DjangoPlay setup | Password for the initial Django superuser. | These values are required for the initial bootstrap flow. They should not be interpreted as credentials that DjangoPlay requires for every subsequent runtime process. ### Platform Administration | Key | Value / Example | Requirement | Used by | Description / When needed | | -------------------------- | ----------------------------------- | ---------------------- | ---------- | ------------------------------------------------------------------ | | `PLATFORM_ADMIN_EMAILS` | `admin@example.com,ops@example.com` | **Runtime — Optional** | DjangoPlay | Comma-separated email addresses granted platform-admin privileges. | | `PLATFORM_ADMIN_USERNAMES` | `admin,operator` | **Runtime — Optional** | DjangoPlay | Comma-separated usernames granted platform-admin privileges. | Leave both values empty when additional platform administrators are not required. ### Redis | Key | Value / Example | Requirement | Used by | Description / When needed | | ---------------- | --------------- | ---------------------- | ---------- | ----------------------------------------------------------------------------------------- | | `REDIS_PASSWORD` | `` | **Runtime — Optional** | DjangoPlay | Redis authentication password. Only needed when the Redis server requires authentication. | The Redis host, port, and database are configured in `config.yaml`. ### Google OAuth / SSO | Key | Value / Example | Requirement | Used by | Description / When needed | | ---------------------------- | ------------------------ | ---------------------- | ---------- | ------------------------------------------------------------------------------------------------------- | | `GOOGLE_CLIENT_ID_HTTPS` | `` | **Runtime — Optional** | DjangoPlay | Google OAuth client ID for HTTPS. Needed only when HTTPS Google SSO is enabled or tested. | | `GOOGLE_CLIENT_SECRET_HTTPS` | `` | **Runtime — Optional** | DjangoPlay | Google OAuth client secret for HTTPS. Needed only when HTTPS Google SSO is enabled or tested. | | `GOOGLE_CLIENT_ID_HTTP` | `` | **Runtime — Optional** | DjangoPlay | Google OAuth client ID for HTTP development. Needed only when HTTP Google SSO is enabled or tested. | | `GOOGLE_CLIENT_SECRET_HTTP` | `` | **Runtime — Optional** | DjangoPlay | Google OAuth client secret for HTTP development. Needed only when HTTP Google SSO is enabled or tested. | Google OAuth redirect URIs must match the host and port configured for the environment in which the OAuth flow is used. ### Email | Key | Value / Example | Requirement | Used by | Description / When needed | | --------------------- | ----------------- | ---------------------- | ---------- | --------------------------------------------------------------------------- | | `EMAIL_HOST_PASSWORD` | `` | **Runtime — Optional** | DjangoPlay | SMTP password. Needed when authenticated SMTP/email delivery is configured. | The non-secret email configuration is stored under `email` in `config.yaml`. ### Abuse Detection | Key | Value / Example | Requirement | Used by | Description / When needed | | ------------------- | --------------- | ---------------------- | ---------- | --------------------------------------------------------------------------------------------------------- | | `ABUSEIPDB_API_KEY` | `` | **Runtime — Optional** | DjangoPlay | AbuseIPDB API credential. Needed only when AbuseIPDB-backed abuse/IP reputation functionality is enabled. | A normal DjangoPlay installation does not require an AbuseIPDB account. ### Cloudflare Turnstile All Turnstile values are optional. Only the key pair for an environment where Turnstile is enabled needs to be populated. | Key | Value / Example | Requirement | Used by | Description / When needed | | ------------------------------ | --------------- | ---------------------- | ---------- | --------------------------------------------- | | `TURNSTILE_SITE_KEY_DEV` | `` | **Runtime — Optional** | DjangoPlay | Turnstile site key for development. | | `TURNSTILE_SECRET_KEY_DEV` | `` | **Runtime — Optional** | DjangoPlay | Turnstile server-side secret for development. | | `TURNSTILE_SITE_KEY_STAGING` | `` | **Runtime — Optional** | DjangoPlay | Turnstile site key for staging. | | `TURNSTILE_SECRET_KEY_STAGING` | `` | **Runtime — Optional** | DjangoPlay | Turnstile server-side secret for staging. | | `TURNSTILE_SITE_KEY_PROD` | `` | **Runtime — Optional** | DjangoPlay | Turnstile site key for production. | | `TURNSTILE_SECRET_KEY_PROD` | `` | **Runtime — Optional** | DjangoPlay | Turnstile server-side secret for production. | These values are needed only when Cloudflare Turnstile bot protection is enabled for the corresponding environment. ### Cloudflare R2 | Key | Value / Example | Requirement | Used by | Description / When needed | | ---------------------- | ------------------------- | ---------------------- | ---------------------- | --------------------------------------------------- | | `R2_ACCOUNT_ID` | `` | **Runtime — Optional** | DjangoPlay/CDN tooling | Cloudflare account ID for R2 operations. | | `R2_ACCESS_KEY_ID` | `` | **Runtime — Optional** | DjangoPlay/CDN tooling | R2 access key used for authenticated R2 operations. | | `R2_SECRET_ACCESS_KEY` | `` | **Runtime — Optional** | DjangoPlay/CDN tooling | R2 secret used for authenticated R2 operations. | These values are only needed when the frontend/CDN workflow performs authenticated operations against Cloudflare R2. ### AI Providers | Key | Value / Example | Requirement | Used by | Description / When needed | | -------------------- | ---------------------------------------------------------- | ---------------------- | -------- | ----------------------------------------------------------------------------------------------------------- | | `XAI_API_KEY` | `` | **Runtime — Optional** | `aicore` | Needed only when `aicore` is configured to use xAI. | | `AI_CUSTOM_API_KEY` | `` | **Runtime — Optional** | `aicore` | API credential for the selected custom AI provider. Needed only when that provider requires authentication. | | `AI_CUSTOM_BASE_URL` | `https://generativelanguage.googleapis.com/v1beta/openai/` | **Runtime — Optional** | `aicore` | OpenAI-compatible API base URL for the selected custom AI provider. | | `AI_CUSTOM_MODEL` | `gemini-flash-lite-latest` | **Runtime — Optional** | `aicore` | Model identifier used by the selected custom AI provider. | `AI_CUSTOM_BASE_URL` and `AI_CUSTOM_MODEL` are relevant only when `aicore` is configured to use the custom provider. --- ## 3. `~/.dplay/.authx` `.authx` contains the configuration consumed by the standalone AuthX Identity service. It uses AuthX's actual environment-variable names. AuthX has its own PostgreSQL database and its own JWT signing authority. ### AuthX Application | Key | Value / Example | Requirement | Used by | Description / When needed | | -------------- | ----------------------- | ---------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------- | | `APP_ENV` | `development` | **Runtime — Required** | AuthX | AuthX runtime environment. | | `APP_HOST` | `0.0.0.0` | **Runtime — Required** | AuthX | Address on which AuthX listens. | | `APP_PORT` | `8100` | **Runtime — Required** | AuthX | Port on which AuthX listens. | | `APP_BASE_URL` | `http://localhost:8100` | **Runtime — Required** | AuthX/DjangoPlay integration | Address where the AuthX service is reachable. This is the service endpoint, not the JWT issuer. | ### AuthX PostgreSQL | Key | Value / Example | Requirement | Used by | Description / When needed | | ------------------- | ------------------------------------------------------------- | ---------------------- | ------------- | ------------------------------------------------------------------------------------------ | | `POSTGRES_USER` | `authx` | **Runtime — Required** | AuthX | PostgreSQL role used by AuthX. | | `POSTGRES_PASSWORD` | `` | **Runtime — Required** | AuthX | Password for the AuthX PostgreSQL role. | | `POSTGRES_DB` | `authx` | **Runtime — Required** | AuthX | PostgreSQL database used by AuthX. | | `DATABASE_URL` | `postgresql+asyncpg://authx:@127.0.0.1:5432/authx` | **Runtime — Required** | AuthX | Async PostgreSQL connection URL. | | `DATABASE_URL_SYNC` | `postgresql+psycopg2://authx:@127.0.0.1:5432/authx` | **Runtime — Required** | AuthX/tooling | Synchronous PostgreSQL connection URL used by AuthX operations such as migrations/tooling. | > **Important:** `POSTGRES_PASSWORD` is AuthX's PostgreSQL password. It is > separate from DjangoPlay's `DB_PASSWORD`. Do not introduce or use an `AUTHX_DB_PASSWORD` key. ### AuthX JWT Signing | Key | Value / Example | Requirement | Used by | Description / When needed | | --------------------------------- | ----------------------------- | ---------------------- | --------------------- | -------------------------------------------------------------------------------- | | `JWT_PRIVATE_KEY` | `` | **Runtime — Required** | AuthX | RSA private key used by AuthX to sign identity JWTs. Must remain private. | | `JWT_PUBLIC_KEY` | `` | **Runtime — Required** | AuthX / JWT consumers | Public key corresponding to `JWT_PRIVATE_KEY`, used to verify AuthX-issued JWTs. | | `JWT_ALGORITHM` | `RS256` | **Runtime — Required** | AuthX | JWT signing algorithm. | | `JWT_ACCESS_TOKEN_EXPIRE_MINUTES` | `60` | **Runtime — Required** | AuthX | Access-token lifetime in minutes. | | `JWT_REFRESH_TOKEN_EXPIRE_DAYS` | `30` | **Runtime — Required** | AuthX | Refresh-token lifetime in days. | | `JWT_ISSUER` | `https://auth.djangoplay.org` | **Runtime — Required** | AuthX / DjangoPlay | JWT `iss` claim identifying AuthX as the identity authority. | | `JWT_AUDIENCE` | `djangoplay` | **Runtime — Required** | AuthX / DjangoPlay | JWT `aud` claim identifying the intended consuming application. | AuthX is the **sole JWT signing authority** for the DjangoPlay AuthX identity architecture. ```text AuthX │ │ signs JWT ▼ JWT │ │ verified by DjangoPlay ▼ DjangoPlay ``` DjangoPlay does not sign AuthX identity JWTs and does not require `JWT_PRIVATE_KEY` for normal verification. ### DjangoPlay → AuthX Authentication | Key | Value / Example | Requirement | Used by | Description / When needed | | --------------------- | ------------------------ | ---------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | `AUTHX_SERVICE_TOKEN` | `` | **Runtime — Required** | DjangoPlay ↔ AuthX | Backend service credential used to authenticate DjangoPlay-to-AuthX internal service requests. Never expose it to browsers or clients. | ### AuthX CORS | Key | Value / Example | Requirement | Used by | Description / When needed | | -------------- | ---------------------------------------------------- | ---------------------- | ------- | ------------------------------------------------------------------------------------------------------------------- | | `CORS_ORIGINS` | `https://app.lvh.me:9999,http://app.lvh.me:3333,...` | **Runtime — Optional** | AuthX | Comma-separated browser origins allowed to access AuthX. Needed when browser-based cross-origin access is required. | --- ## 4. AuthX URL and JWT Issuer `APP_BASE_URL` and `JWT_ISSUER` have different purposes. | Setting | Purpose | Example | | -------------- | -------------------------------------------------- | ----------------------------- | | `APP_BASE_URL` | Where the AuthX service is reachable | `http://127.0.0.1:8100` | | `JWT_ISSUER` | Identity authority asserted in the JWT `iss` claim | `https://auth.djangoplay.org` | They do not have to be the same URL. For example: ```text APP_BASE_URL=http://127.0.0.1:8100 JWT_ISSUER=https://auth.djangoplay.org ``` can be intentional. --- ## 5. `~/.dplay/config.yaml` `config.yaml` contains structured, non-secret DjangoPlay configuration. ### `site` | Key | Value / Example | Requirement | Used by | Description / When needed | | -------------------- | ------------------------- | ---------------------- | ---------- | ------------------------------------------------------------------ | | `site.name` | `DjangoPlay` | **Runtime — Required** | DjangoPlay | Application/display name. | | `site.host` | `lvh.me` | **Runtime — Required** | DjangoPlay | Base host used for URL construction. | | `site.ssl_protocol` | `https` | **Runtime — Required** | DjangoPlay | Protocol used for HTTPS URLs. | | `site.http_protocol` | `http` | **Runtime — Required** | DjangoPlay | Protocol used for HTTP URLs. | | `site.ssl_port` | `9999` | **Runtime — Optional** | DjangoPlay | HTTPS port when the environment uses an explicit/non-default port. | | `site.http_port` | `3333` | **Runtime — Optional** | DjangoPlay | HTTP port when the environment uses an explicit/non-default port. | | `site.ssl_url` | `https://app.lvh.me:9999` | **Runtime — Required** | DjangoPlay | HTTPS application URL. | | `site.http_url` | `http://app.lvh.me:3333` | **Runtime — Required** | DjangoPlay | HTTP application URL. | | `site.website` | `https://djangoplay.org` | **Runtime — Optional** | DjangoPlay | Public website URL. Needed only where the application uses it. | `site.ssl_port` and `site.http_port` are only needed when the corresponding serving mode requires an explicit port. ### `subdomains` | Key | Value / Example | Requirement | Used by | Description / When needed | | ------------ | ----------------------- | ---------------------- | ---------- | ------------------------------------------------- | | `subdomains` | `app`, `issues`, `docs` | **Runtime — Required** | DjangoPlay | Subdomains used by DjangoPlay URL-building logic. | ### `repository` | Key | Value / Example | Requirement | Used by | Description / When needed | | ---------------------- | ---------------------------- | ---------------------- | ----------------------- | ------------------------------------------------------------------------------------------- | | `repository.root` | `~/path/to/djangoplay-web/` | **Runtime — Required** | DjangoPlay tooling | Local DjangoPlay repository path. | | `repository.docs_root` | `~/path/to/documentation/` | **Runtime — Optional** | DjangoPlay/docs tooling | Documentation repository path. Needed only when the local documentation repository is used. | | `repository.site_root` | `~/path/to/djangoplay-site/` | **Runtime — Optional** | DjangoPlay/site tooling | Website repository path. Needed only when the local website repository is used. | ### `database` | Key | Value / Example | Requirement | Used by | Description / When needed | | --------------- | ----------------- | ---------------------- | ---------- | ------------------------------------------------------------------------ | | `database.host` | `127.0.0.1` | **Runtime — Required** | DjangoPlay | PostgreSQL server host. | | `database.port` | `5432` | **Runtime — Required** | DjangoPlay | PostgreSQL server port. | | `database.name` | `` | **Runtime — Required** | DjangoPlay | DjangoPlay PostgreSQL database name. | | `database.user` | `` | **Runtime — Required** | DjangoPlay | DjangoPlay PostgreSQL role. Its password is `DB_PASSWORD` in `.secrets`. | The DjangoPlay database values must remain consistent with the DjangoPlay `DATABASE_URL` and `DB_PASSWORD`. They are separate from AuthX's `POSTGRES_*` settings. ### `redis` | Key | Value / Example | Requirement | Used by | Description / When needed | | ------------ | --------------- | ---------------------- | ---------- | ------------------------------------------ | | `redis.host` | `127.0.0.1` | **Runtime — Required** | DjangoPlay | Redis server host. | | `redis.port` | `6379` | **Runtime — Required** | DjangoPlay | Redis server port. | | `redis.db` | `1` | **Runtime — Required** | DjangoPlay | Redis logical database used by DjangoPlay. | Redis authentication is controlled separately by the optional `REDIS_PASSWORD` in `.secrets`. ### `email` | Key | Value / Example | Requirement | Used by | Description / When needed | | ------------ | ------------------ | ---------------------- | ---------- | ----------------------------------------------------------------------- | | `email.mode` | `` | **Runtime — Optional** | DjangoPlay | Email delivery mode. Needed when the configured email workflow uses it. | | `email.host` | `` | **Runtime — Optional** | DjangoPlay | SMTP/email server hostname. | | `email.port` | `587` | **Runtime — Optional** | DjangoPlay | SMTP/email server port. | | `email.user` | `` | **Runtime — Optional** | DjangoPlay | SMTP/email account username. | | `email.from` | `` | **Runtime — Optional** | DjangoPlay | Default sender address. | The SMTP password belongs in `.secrets` as `EMAIL_HOST_PASSWORD`. ### `support` | Key | Value / Example | Requirement | Used by | Description / When needed | | ------------------ | --------------- | ---------------------- | ---------- | --------------------------------- | | `support.phone` | `` | **Runtime — Optional** | DjangoPlay | Public support telephone number. | | `support.email` | `` | **Runtime — Optional** | DjangoPlay | Public support email address. | | `support.location` | `` | **Runtime — Optional** | DjangoPlay | Public support/business location. | ### `social` | Key | Value / Example | Requirement | Used by | Description / When needed | | ----------------- | ---------------- | ---------------------- | ---------- | ------------------------- | | `social.linkedin` | `` | **Runtime — Optional** | DjangoPlay | Public LinkedIn URL. | | `social.github` | `` | **Runtime — Optional** | DjangoPlay | Public GitHub URL. | ### `django` | Key | Value / Example | Requirement | Used by | Description / When needed | | ------------------------ | ------------------------ | ---------------------- | ------- | -------------------------------------------------- | | `django.settings_module` | `paystream.settings.dev` | **Runtime — Required** | Django | Django settings module for the active environment. | Production example: ```yaml django: settings_module: paystream.settings.prod ``` ### `cdn` The `cdn` section is only relevant when the frontend/CDN workflow uses Cloudflare R2. | Key | Value / Example | Requirement | Used by | Description / When needed | | -------------------- | ----------------------------- | ---------------------- | ---------------------- | --------------------------------------------------------- | | `cdn.r2_bucket` | `djangoplay-frontend` | **Runtime — Optional** | DjangoPlay/CDN tooling | R2 bucket used for frontend assets. | | `cdn.r2_public_base` | `https://pub-xxxxxxxx.r2.dev` | **Runtime — Optional** | DjangoPlay/CDN tooling | Public base URL for R2-hosted assets. | | `cdn.asset_version` | `v1.2.1` | **Runtime — Optional** | DjangoPlay/CDN tooling | Version identifier used by the asset publishing workflow. | R2 credentials are stored separately in `.secrets`. --- ## 6. `~/.dplay/.appdata` `.appdata` is entirely optional. It is used by reference-data tooling for datasets such as: * locations * entities/businesses * industries/classifications It can be left unused for normal DjangoPlay application development. ### Reference Data | Key | Value / Example | Requirement | Used by | Description / When needed | | -------------------------- | ----------------------- | ---------------------- | ----------------------------- | ------------------------------------------------ | | `DATA_DIR` | `~/djangoplay/appdata/` | **Tooling — Optional** | Reference-data tooling | Directory containing local reference data. | | `GLOBAL_REGIONS_SYNC` | `` | **Tooling — Optional** | Locations tooling | Global region/continent reference-data location. | | `PHONE_POSTAL_LENGTH_JSON` | `` | **Tooling — Optional** | Locations tooling | Phone/postal-length reference-data location. | | `COUNTRY_INFO_JSON` | `` | **Tooling — Optional** | Locations tooling | Country information dataset location. | | `TIMEZONE_JSON` | `` | **Tooling — Optional** | Locations tooling | Timezone dataset location. | | `REGIONS_JSON` | `` | **Tooling — Optional** | Locations tooling | Regions dataset location. | | `SUBREGIONS_JSON` | `` | **Tooling — Optional** | Locations tooling | Subregions dataset location. | | `CITIES_JSON` | `` | **Tooling — Optional** | Locations tooling | Cities dataset location. | | `POSTAL_CODES_JSON` | `` | **Tooling — Optional** | Locations tooling | Postal-code dataset location. | | `ENTITIES_JSON` | `` | **Tooling — Optional** | Entity/reference-data tooling | Entity/business reference-data location. | ### Industry / Classification Sources | Key | Value / Example | Requirement | Used by | Description / When needed | | ------------- | --------------- | ---------------------- | ---------------------- | ---------------------------------------- | | `ISIC_SOURCE` | `` | **Tooling — Optional** | Classification tooling | ISIC industry classification source. | | `CPC_SOURCE` | `` | **Tooling — Optional** | Classification tooling | CPC classification source. | | `HS_SOURCE` | `` | **Tooling — Optional** | Classification tooling | Harmonized System classification source. | ### Compiled Data Source | Key | Value / Example | Requirement | Used by | Description / When needed | | ----------------- | -------------------------------------------- | ---------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------- | | `DATA_SOURCE_URL` | `https://install.djangoplay.org/data-source` | **Tooling — Optional** | Reference-data tooling | Source for pre-compiled reference data. Only needed when the reference-data workflow downloads data from a remote source. | The scaffold provides `DATA_SOURCE_URL` as a default source. --- ## 7. Credential Boundaries DjangoPlay and AuthX intentionally use separate credentials. | Purpose | DjangoPlay | AuthX | | ---------------------- | -------------------------------------------------------- | ------------------------------------------------------------ | | PostgreSQL password | `DB_PASSWORD` | `POSTGRES_PASSWORD` | | PostgreSQL user | `config.yaml` → `database.user` | `POSTGRES_USER` | | PostgreSQL database | `config.yaml` → `database.name` | `POSTGRES_DB` | | PostgreSQL connection | `.secrets` → `DATABASE_URL` | `.authx` → `DATABASE_URL` / `DATABASE_URL_SYNC` | | JWT signing | `JWT_SIGNING_KEY` for DjangoPlay's own JWT functionality | `JWT_PRIVATE_KEY` / `JWT_PUBLIC_KEY` for AuthX identity JWTs | | Service authentication | `AUTHX_SERVICE_TOKEN` | AuthX validates the backend credential | | JWT issuer | — | `JWT_ISSUER` | | JWT audience | — | `JWT_AUDIENCE` | Do not mix these credentials. ```text DB_PASSWORD != POSTGRES_PASSWORD JWT_SIGNING_KEY != JWT_PRIVATE_KEY AUTHX_SERVICE_TOKEN != database password APP_BASE_URL != JWT_ISSUER ``` In particular, there is no `AUTHX_DB_PASSWORD` configuration key. --- ## 8. Development vs Production Some configuration values vary by environment. | Setting | Development | Production | | -------------------- | ------------------------------- | ------------------------------------- | | AuthX `APP_ENV` | `development` | `production` | | AuthX `APP_BASE_URL` | Local AuthX service URL | Deployment-specific AuthX service URL | | `JWT_ISSUER` | Environment-specific | Production AuthX issuer | | `JWT_AUDIENCE` | `djangoplay` | Application/API audience | | Django settings | `paystream.settings.dev` | `paystream.settings.prod` | | CORS | Local `lvh.me` origins | Production browser origins | | JWT keys | Development key pair | Separate production key pair | | Service token | Development value | Separate production value | | Google OAuth | Only when SSO is enabled/tested | Only when SSO is enabled | | Turnstile | Only when enabled | Only when enabled | | R2 | Only when CDN workflow is used | When production CDN workflow is used | | AI credentials | Only for selected provider | Only for selected provider | Do not reuse development private keys or backend service credentials in production. --- ## 9. AuthX RSA Key Generation AuthX uses an RSA key pair for RS256 JWT signing. Generate a new pair when creating a new AuthX environment: ```bash openssl genrsa -out jwt_private.pem 2048 openssl rsa \ -in jwt_private.pem \ -pubout \ -out jwt_public.pem ``` Validate the private key: ```bash openssl rsa -in jwt_private.pem -check -noout ``` Expected output: ```text RSA key ok ``` Verify that the public key corresponds to the private key: ```bash openssl rsa \ -in jwt_private.pem \ -pubout \ -outform PEM | diff - jwt_public.pem ``` No output and exit status `0` means the public/private pair matches. ### PEM values in `.authx` The PEM values stored in environment configuration need to preserve their line breaks using literal `\n` sequences. Generate the private-key value with: ```bash awk 'NF {printf "%s\\n", $0}' jwt_private.pem ``` Generate the public-key value with: ```bash awk 'NF {printf "%s\\n", $0}' jwt_public.pem ``` The resulting value should contain literal: ```text \n ``` between PEM lines. Do not modify the Base64 key material or introduce arbitrary backslashes into the encoded key body. `JWT_PRIVATE_KEY` is an AuthX secret and must never be committed to Git or shared with consuming applications. --- ## 10. Configuration Creation The repository scaffold creates the four configuration files: ```bash bash scripts/installation/create_env.sh ``` The public installer provides the same configuration scaffolding remotely: ```bash curl -fsSL https://install.djangoplay.org/config | sudo bash ``` To intentionally overwrite existing configuration files: ```bash bash scripts/installation/create_env.sh --force ``` or: ```bash curl -fsSL https://install.djangoplay.org/config | sudo bash -s -- --force ``` Without `--force`, existing configuration files are not overwritten. --- ## 11. Configuration Maintenance This document shall ALWAYS remain synchronized with `create_env.sh` for below: Whenever a configuration key is: * added * removed * renamed * moved between files * changed from setup-only to runtime * changed from required to optional * associated with a new integration The generated configuration files are the operational configuration. This document is the human-readable reference explaining: * where each key belongs * when each key is required * which service or tooling consumes it * what each key does * which integrations are optional * which values are environment-specific * which credentials belong to DjangoPlay * which credentials belong to AuthX