← knowledge.oriz.in

Single env source: c:/D/oriz/.env ? auto-push to chirag127 GH Org Secrets ? apps consume at build

decision decisionenvsecretssingle-sourceautomationgh-org-secretsminimum-manual

Single env source: c:/D/oriz/.env ? GH Org Secrets

Decision

c:/D/oriz/.env (gitignored on master) is the single, authoritative source of every secret + config value used anywhere in the chirag127/oriz family.

A scheduled cron (.github/workflows/sync-env-to-org-secrets.yml on master) runs daily at 06:30 IST (or on-demand workflow_dispatch when c:/D/oriz/.env changes):

  1. Reads templates/.env.example to enumerate canonical key names
  2. For each key, reads the corresponding value from c:/D/oriz/.env (loaded via secure GH-Action secret OR encrypted file — see "Bootstrapping" below)
  3. Pushes each value to chirag127 GH Org Secrets: gh secret set <KEY> --org chirag127 --visibility all --body "<VALUE>"
  4. Every repo's workflows + builds inherit the org secret automatically (no per-repo setup)

User mandate verbatim (2026-06-22 evening): "I want to set the single token for all of the authentication and all of the monetization and all of the everything. I want minimum number of environment variable to be set. ... I will set them only one time. Throughout the organization of my GitHub. ... The builder will generate the website and deploy it on whatever server or this repository's .env file will also be served as a single source of truth for all of the environment variables. You will periodically push all of the environment variable from this repository to GitHub. ... I don't want to set environment variable manually for all of the apps and all of the websites."

Bootstrap (one-time, manual — minimum manual work)

You manually populate c:/D/oriz/.env ONCE with the canonical values (~50-80 env vars total). Then never touch them per-repo again.

To run the sync script the first time:

  1. Generate a chirag127 GH Personal Access Token with admin:org scope (one-time, 1-year expiry)
  2. Add it to c:/D/oriz/.env as GH_ADMIN_PAT=ghp_...
  3. Run node scripts/sync-env-to-org-secrets.mjs locally — this pushes all current keys to org-level secrets
  4. After local verification, the GH Action takes over on the daily cron

Sync script

c:/D/oriz/scripts/sync-env-to-org-secrets.mjs:

// 1. Parse templates/.env.example for canonical key names
// 2. Parse c:/D/oriz/.env for values
// 3. For each key, call: gh secret set <KEY> --org chirag127 --visibility all
// 4. Report diff (keys added, updated, deleted)

Bootstrapping the GH Action

The cron workflow needs access to c:/D/oriz/.env itself. Options:

A. encrypted-file approach (RECOMMENDED): encrypt .env with age or sops, commit the encrypted blob to master, decrypt in GH Action using a single bootstrap key stored as SOPS_AGE_KEY org secret. One bootstrap secret ? unlimited derived secrets.

B. manual-paste approach: GH Action accepts the .env content as an input on workflow_dispatch; you paste it once + it pushes all keys. Re-paste only when keys rotate.

Choosing (A): encrypted-file. Use sops + age. The unencrypted .env stays gitignored locally; the encrypted .env.enc is committed to master.

Consuming env vars in app builds

Every app's CF Pages build inherits chirag127 org secrets automatically. Apps reference process.env.RAZORPAY_KEY_ID etc. — no per-app setup needed.

For client-side env vars (PUBLIC_*), Astro embeds them at build time via import.meta.env.PUBLIC_*. Same single source.

Implications

Supersedes-in-part

security/env-and-secrets-single-source.md — that file describes the two-track delivery (.env.example synced + GH Actions secrets set once). This file extends it with the AUTOMATED periodic-sync mechanism (was implicit; now explicit).

Cross-refs

Status: deployed 2026-06-22

First-run results (local bootstrap, 2026-06-22):