Skip to content

Configuration reference

Every RepoWrangler setting, what it does, whether it is secret, and where you set it per deployment target. The application reads a single flat set of values — on Cloudflare they come from wrangler.jsonc vars and wrangler secret put; on the Node host (Docker, Azure Container Apps, Kubernetes) they come from environment variables / .env / Key Vault / a Kubernetes Secret. The names are identical everywhere.

Secrets are never committed. Anything marked secret below must come from your platform's secret store (Cloudflare secrets, Key Vault, a K8s Secret, or an un-committed .env) — never from a file in the repository. See security.md.

Where each target reads configuration

TargetNon-secret configSecrets
Cloudflare Workerwrangler.jsonc varswrangler secret put NAME
Docker / compose.env (compose reads repo-root .env)same .env (keep it un-committed)
Azure Container AppsContainer App env varsKey Vault refs via managed identity
KubernetesConfigMapSecret (or external-secrets)
Decoupled SPAVITE_* at build timen/a (SPA holds no secrets)

Core

SettingSecretDefaultDescription
DEMO_MODEnotrue (public default)true = mock data, sign-in bypassed, no secrets. false = real mode (a data provider must be configured). Also auto-falls back to demo if no GitHub App is set.
AUTH_PROVIDERSnoOrdered CSV of enabled sign-in providers: github,gitlab,entra,google,local (ADR-019). Supersedes AUTH_MODE; a provider appears only if also configured. See Sign-in providers.
AUTH_MODEnogithub_appLegacy single-provider selector, used only when AUTH_PROVIDERS is empty: github_app or entra.
PUBLIC_BASE_URLnorequest originPublic URL of this instance; used to build OAuth callback URLs and links. Must match the redirect URI registered with your identity provider.
SESSION_SECRETyesLong random string that signs the session cookie (HMAC-SHA-256). Required in real mode. Generate with openssl rand -base64 48.
DEFAULT_RETENTION_DAYSnoprovider defaultDays of pipeline-run / webhook history to retain before compaction.

Storage (Node host only)

SettingSecretDefaultDescription
SQLITE_PATHno./data/repo-wrangler.db (/app/data/… in Docker)SQLite database file location. Used when DATABASE_URL is empty.
DATABASE_URLyesPostgreSQL connection string, e.g. postgres://user:pass@host:5432/db?sslmode=require. Set to use PostgreSQL instead of SQLite — required for multiple API replicas sharing one database. See ADR-015.
MIGRATIONS_DIRno./migrationsDirectory of ordered *.sql migrations applied at boot.
WEB_DISTnoapps/web/distDirectory of the built SPA the host serves.
PORTno8080TCP port the Node host listens on.
ENABLE_SCHEDULERnotrueRun the in-process sync scheduler. With multiple replicas on PostgreSQL, set false on all but one replica.

On Cloudflare, storage is the D1 binding DB in wrangler.jsonc (database_id) — not an environment variable.

Secrets source (PN-4, Node host)

Maturity: every backend below is implemented and unit-tested and is a supported deployment option. Validate your chosen backend against your real vault before production — pre-1.0.

Where the host reads its secrets from (ADR-017). Every non-env source falls through to environment variables for anything it does not supply.

No cloud is required — the external-vault options span self-hosted (HashiCorp Vault) and every major cloud. Env names map to vault keys by lower-kebab (GITHUB_CLIENT_SECRETgithub-client-secret). Every non-env source falls through to environment variables.

SettingSecretDefaultDescription
SECRET_SOURCEnoenvenv · file · keyvault (Azure) · vault (HashiCorp) · aws · gcp · cloudflare-kv · cyberark · composite (file → configured vaults → env).
SECRETS_DIRno/run/secretsfile: directory of mounted secret files. Also covers any CSI driver (AWS/GCP/Vault) that mounts secrets as files.
KEY_VAULT_URI / AZURE_CLIENT_IDnokeyvault: Azure Key Vault URI (managed identity, no static credential); optional user-assigned identity client id.
VAULT_ADDR / VAULT_TOKENyesvault: HashiCorp Vault address + token (cloud-neutral, runs anywhere).
VAULT_KV_MOUNT / VAULT_KV_PREFIX / VAULT_NAMESPACEnosecretvault: KV v2 mount, optional key prefix, optional Enterprise/HCP namespace.
AWS_REGION + AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKENyesaws: AWS Secrets Manager (SigV4). Creds from the standard AWS env / instance role.
AWS_SECRET_PREFIXnoaws: optional secret-id prefix.
GCP_PROJECTnogcp: Google Secret Manager project; token from the metadata server / workload identity.
CF_ACCOUNT_ID / CF_KV_NAMESPACE_ID / CF_API_TOKEN / CF_KV_PREFIXyes (token)cloudflare-kv: Workers KV via REST. Note: Cloudflare Secrets/Secrets Store is preferred for sensitive values (encrypted); KV is offered as an option.
CYBERARK_BASE_URL / CYBERARK_APP_ID / CYBERARK_SAFE / CYBERARK_OBJECT_PREFIXnocyberark: CyberArk Central Credential Provider (CCP/AIM); application-authenticated, no token.

Scheduler driver (PN-3, Node host)

How periodic sync and daily maintenance are triggered (ADR-018). On Cloudflare, cron triggers always call the scheduled handler; this is a Node-host concern.

SettingSecretDefaultDescription
SCHEDULER_MODEnoin-processin-process (internal timer) · external (no timer; an outside ticker POSTs /internal/cron/run) · off (no scheduling).
CRON_TRIGGER_TOKENyesShared bearer token authorizing POST /internal/cron/run?job=periodic|daily when SCHEDULER_MODE=external. The endpoint is inert without both.

Example external ticker (Linux cron, K8s CronJob, GitHub Actions, Azure Functions timer):

sh
curl -fsS -X POST -H "authorization: Bearer $CRON_TRIGGER_TOKEN" \
  "$PUBLIC_BASE_URL/internal/cron/run?job=periodic"

GitHub App (data provider)

Required in real mode when monitoring GitHub. See Providers → GitHub App.

SettingSecretDescription
GITHUB_APP_IDno*Numeric App ID. (*Presence toggles real mode.)
GITHUB_APP_PRIVATE_KEYyesThe App's PEM private key (single line or \n-escaped).
GITHUB_CLIENT_IDnoOAuth client ID for user sign-in.
GITHUB_CLIENT_SECRETyesOAuth client secret for user sign-in.
GITHUB_WEBHOOK_SECRETyesVerifies inbound GitHub webhook signatures.
ALLOWED_GITHUB_USERSnoComma-separated GitHub logins allowed to sign in; first = owner, rest = admins.
ALLOWED_GITHUB_ORGSnoComma-separated orgs to scope discovery to (optional).

Sign-in providers (PN-5)

Maturity: every provider below is implemented and unit-tested and is a supported sign-in option. Validate the OAuth/OIDC flow against your identity provider before production — pre-1.0.

Authentication is a set of swappable providers behind one signed session cookie (ADR-019). Enable any combination with AUTH_PROVIDERS (ordered CSV); each appears on the sign-in screen only when it is also configured. For every provider, *_ALLOWED_USERS is a CSV where the first principal is the owner and the rest are admins. Each provider registers a redirect URI of {PUBLIC_BASE_URL}/auth/<id>/callback.

GitHub (github) — OAuth via the GitHub App user-authorization flow. Uses GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET (see GitHub App above) and ALLOWED_GITHUB_USERS.

GitLab (gitlab) — OAuth 2.0; works with gitlab.com or self-managed (GITLAB_BASE_URL), scope read_user.

SettingSecretDescription
GITLAB_CLIENT_IDnoGitLab OAuth application id.
GITLAB_CLIENT_SECRETyesGitLab OAuth application secret.
GITLAB_ALLOWED_USERSnoComma-separated GitLab usernames; first = owner.

Microsoft Entra ID (entra) — OpenID Connect. Also selectable via the legacy AUTH_MODE=entra. See Providers → Entra ID.

SettingSecretDescription
ENTRA_TENANT_IDnoDirectory (tenant) ID, or organizations / common.
ENTRA_CLIENT_IDnoApplication (client) ID.
ENTRA_CLIENT_SECRETyesThe Entra app's client secret.
ENTRA_ALLOWED_USERSnoSign-in names (UPN/email); first = owner.

Google (google) — OpenID Connect; the verified email is the identity.

SettingSecretDescription
GOOGLE_CLIENT_IDnoGoogle OAuth 2.0 client id.
GOOGLE_CLIENT_SECRETyesGoogle OAuth 2.0 client secret.
GOOGLE_ALLOWED_USERSnoGoogle account emails; first = owner.

Local-dev (local) — development only, password-less. Active only when local is in AUTH_PROVIDERS and LOCAL_DEV_USERS is set. Never enable in production.

SettingSecretDescription
LOCAL_DEV_USERSnoUsernames offered on the local sign-in form; first = owner.

GitLab (data provider, optional)

See Providers → GitLab.

SettingSecretDefaultDescription
GITLAB_TOKENyesRead-only GitLab access token. Presence + GITLAB_GROUPS enables GitLab.
GITLAB_BASE_URLnohttps://gitlab.comBase URL for self-managed GitLab.
GITLAB_GROUPSnoComma-separated top-level group paths to monitor.
GITLAB_WEBHOOK_SECRETyesVerifies inbound GitLab webhook signatures (optional).

Frontend / networking

SettingSecretDefaultDescription
CORS_ALLOWED_ORIGINSnoempty (same-origin)Comma-separated exact SPA origins allowed to call the API cross-origin. Set only for the decoupled frontend topology (ADR-011, Mode B). Empty = integrated same-origin.
VITE_API_BASE_URLno (build-time)emptySPA build var: absolute API base for a decoupled SPA. Empty = same-origin.
VITE_BASE_PATHno (build-time)/SPA base path when hosted under a sub-path (e.g. GitHub Pages project site).
VITE_DEFAULT_THEMEno (build-time)lightDefault UI theme id. See theming guide.

Notifications (optional)

SettingSecretDescription
NOTIFY_WEBHOOK_URLyesOutbound webhook for critical/high attention escalations. Empty = disabled.

Minimal configurations

Demo (any target): nothing required — DEMO_MODE=true is the default.

Real GitHub, self-hosted (SQLite):

ini
DEMO_MODE=false
PUBLIC_BASE_URL=https://repowrangler.example.com
SESSION_SECRET=<openssl rand -base64 48>
GITHUB_APP_ID=123456
GITHUB_APP_PRIVATE_KEY=<pem>
GITHUB_CLIENT_ID=Iv1.abc123
GITHUB_CLIENT_SECRET=<secret>
GITHUB_WEBHOOK_SECRET=<secret>
ALLOWED_GITHUB_USERS=your-login

Real GitHub + Postgres + Entra sign-in (Azure Container Apps / Kubernetes): add to the above:

ini
DATABASE_URL=postgres://user:pass@db:5432/repowrangler?sslmode=require
AUTH_MODE=entra
ENTRA_TENANT_ID=<guid>
ENTRA_CLIENT_ID=<guid>
ENTRA_CLIENT_SECRET=<secret>
ENTRA_ALLOWED_USERS=you@example.com
# with >1 replica, ENABLE_SCHEDULER=false on all but one

The full example file is apps/server/.env.example; the Cloudflare dev equivalent is .dev.vars.example.

Apache-2.0 licensed. Read-only by design.