Secrets & configuration
This page is the single inventory of where every secret and environment
variable lives and how each app receives it. It’s cross-cutting by
nature — secrets span GitHub Actions, Infisical, and DigitalOcean, and no
single component owns them — which is why it sits in infra/.
Names only. This page never contains secret values — neither GitHub, DigitalOcean, nor Infisical will reveal a stored secret after creation, and we don’t reproduce them here. If you need a value, rotate it (see Rotation).
The three stores
| Store | Holds | Read by |
|---|---|---|
| Infisical | Source of truth for application secrets, per project, per environment (dev / staging / prod). | The apps (at runtime or via sync) + the migration runner. |
| DigitalOcean app env | Whatever an app needs at runtime — either just Infisical bootstrap creds, or the full synced set. | The running container (process.env). |
| GitHub Actions secrets | Credentials the CI/CD workflows need — DO API token, S3, Infisical bootstrap, Slack. | .github/workflows/* only. |
Two secret-loading models
Knowing which model an app uses explains its DO env footprint and its failure modes.
| Model | How it loads | DO env footprint | Failure mode |
|---|---|---|---|
| A — runtime pull | App logs into Infisical on boot with a universal-auth identity (INFISICAL_CLIENT_ID/SECRET) and fetches all secrets into process.env (api/src/shared/utils/set-env). | Only the 5 INFISICAL_* bootstrap vars. | Bad/expired creds → boot crash (Missing required environment variables / 401 Invalid credentials). |
| B — Infisical→DO sync | Infisical pushes secrets directly into the DO env panel via the DO App Platform connector; the app just reads process.env. | Full secret set as SECRET-typed vars. | No runtime Infisical dependency — nothing to expire at boot. |
When both apply, Model B wins:
setEnvFromInfisicalskips any key already present inprocess.env, so a synced var overrides the runtime pull.
Per-app model
All deployed apps are now Model B (synced) — the runtime Infisical pull is off everywhere. Migrated June 2026; see Migration.
| App | DO app id | Synced from new project b0466e3e… | App-level keys |
|---|---|---|---|
iba-api (prod) | 5c790555… | /api, prod | 69 (/api 57 + /shared 12) |
iba-www (prod) | 117b6530… | /www, prod | 18 (/www 6 + /shared 12) |
iba-admin (prod) | ad522377… | /admin, prod | 3 (NEXT_PUBLIC_*) |
iba-dev-api (playground) | 1620ef3e… | /api, staging | 69 |
tunnelflight-assistant | ed1d52aa… | its own Infisical project | 27 |
iba-api grew
65 → 69 since the June cutover: GA4_MEASUREMENT_ID, GA4_MP_API_SECRET,
SLACK_CRON_WEBHOOK_URL, SLACK_CRONS_WEBHOOK_URL. The last two are
near-duplicates — SLACK_CRONS_WEBHOOK_URL is the one the crons use (kept
distinct from the deploys webhook); the singular is a leftover.
Component-level on each app: SKIP_INFISICAL=1 + DO build flags
(USE_NPM_INSTALL, NODE_MODULES_CACHE; www also NPM_CONFIG_PRODUCTION=false
so sass survives the build). The old INFISICAL_* bootstrap creds were removed
after cutover. The prod API’s db-migrate Pre-Deploy job runs on the app-level
synced DB_MIGRATE_* (no bootstrap, no pull).
IS_PRODUCTIONis overloaded — worth knowing.if (!IS_PRODUCTION)gates the runtime pull and dev-only guards;if (IS_PRODUCTION === 'Yes')gates real production side-effects across ~20 crons/scripts. Syncing/shared(which containsIS_PRODUCTION) both disabled the pull and set the prod flag on apps that previously ran without it — a correction, but be aware it arms the=== 'Yes'paths (which live in crons/scripts run via the GH Actions scheduler, not the web apps). We rely on the explicitSKIP_INFISICAL=1to disable the pull, independent ofIS_PRODUCTION.
⚠️ The truthiness form is a trap.
IS_PRODUCTIONisYesinprodandNoinstaging/dev— and"No"is truthy in JS. So!process.env.IS_PRODUCTIONinapi/index.jsisfalsein staging and dev, meaning the runtime pull is disabled there by the string"No", not bySKIP_INFISICAL. Today that’s masked, because every app is Model B and carriesSKIP_INFISICAL=1anyway. The trap is the recovery path: dropSKIP_INFISICALexpecting the pull to resume — debugging a bad sync, or standing up a new app — and it silently won’t. The app boots on whatever the sync happened to deliver, and the loudMissing required environment variablesthrow thatset-envexists to produce never fires.Three conventions are live for the same variable name:
!IS_PRODUCTION(truthiness, 19 sites inapi/src),=== 'Yes'(13 sites inapi/src), and=== "true"(assistant/src/lib/infisical.ts, where the value istrue/falserather thanYes/No). The assistant’s strict comparison is the correct pattern; the API’s truthiness check is the one to fix.
GitHub Actions secrets
There is exactly one: GITHUB_TOKEN — the token GitHub injects itself. Every
other CI credential moved into Infisical /github-ci and is fetched at run time
over OIDC, so no long-lived secret is stored in GitHub at all.
Five workflows authenticate this way — crons.yml, db-backup.yml,
do-deployment.yml, pr-preview-create.yml, pr-preview-cleanup.yml — each
declaring permissions: id-token: write and calling infisical/secrets-action:
identity-id: a16d53a8-23a6-4994-b61e-7bc66da545ff
project-slug: tunnelflight-2g-un
env-slug: prod
secret-path: /github-ciThe 13 keys in /github-ci:
| Key | Purpose |
|---|---|
CRONS_API_KEY | authenticates the scheduled cron caller |
DO_API_TOKEN | doctl auth for deploy + preview workflows |
DO_ASSISTANT_APP_ID | assistant deploy target |
DO_DB_CLUSTER_ID | preview-DB provisioning |
INFISICAL_CLIENT_ID | handed to preview apps, which are still Model A |
INFISICAL_CLIENT_SECRET | ditto |
INFISICAL_PROJECT_ID | ditto |
S3_BUCKET_ACCESS_KEY_ID | preview-DB restore + prod DB backup |
S3_BUCKET_SECRET_ACCESS_KEY | ditto |
S3_BUCKET_NAME | ditto |
S3_REGION | ditto |
SLACK_WEBHOOK_URL | deploy-failure alerts |
SLACK_CRONS_WEBHOOK_URL | cron-failure alerts (distinct from deploys) |
The Infisical bootstrap credentials living inside Infisical isn’t circular — OIDC breaks the chicken-and-egg. The workflow proves its identity with GitHub’s own OIDC token, then reads the credentials it needs to hand to preview apps, which still use the Model A runtime pull (
INFISICAL_ENVIRONMENT: staging,INFISICAL_SECRET_PATH: /api). Long-lived apps never see them.
Infisical: the API / WWW / Admin keys
These app secrets live in the foldered project b0466e3e-98a7-4cb8-9db1-97dfa5d8da74
(folders /shared /api /www /admin — see Migration
for the structure). 88 keys, same key set across dev / staging / prod
(values differ). The matrix below is the usage analysis that drove the folder
allocation (● = the key is referenced in that app’s source — API 64, WWW 18,
Admin 5 of 88).
Legacy: the old flat project
c02f5163-16d8-4c5b-a1b2-879e12013cad(no folders, all 88 at root) is superseded and pending decommission — nothing deployed reads from it anymore. Keep it until the cutover’s bedded in, then delete.
●= a literalprocess.env.<KEY>reference in app source. A blank is not proof a key is unused — it may be consumed by the Docker build, CI workflows, scripts, or accessed via a dynamically-built name. It’s also why/shared= keys used by ≥2 apps,/api= api-only, and so on. Signal, not verdict.
Database & cache
| Key | API | WWW | Admin |
|---|---|---|---|
CACHE_ENABLED | ● | ||
DB_HOST | ● | ||
DB_MIGRATE_PASSWORD | ● | ||
DB_MIGRATE_USER | ● | ||
DB_NAME | ● | ||
DB_PASSWORD | ● | ||
DB_PORT | ● | ||
DB_USER | ● | ||
REDIS_HOST | ● | ● | |
REDIS_PASSWORD | ● | ● | |
REDIS_PORT | ● | ● | |
REDIS_USERNAME |
App config & URLs
| Key | API | WWW | Admin |
|---|---|---|---|
ADMIN_URL | ● | ● | |
API_PORT | ● | ||
API_URL | ● | ● | ● |
APP_PORT | ● | ||
APP_URL | ● | ||
COOKIE_DOMAIN_API | |||
COOKIE_DOMAIN_WWW | |||
DOCKER_API_URL | ● | ● | |
DOCS_FULL_URL | ● | ||
DOCS_FUSEMETRIX_URL | ● | ||
DOMAIN | ● | ||
IS_PRODUCTION | ● | ● | |
NODE_ENV | ● | ● | |
NODE_MODULES_CACHE | |||
RATE_LIMIT_MAX_REQUESTS | ● | ||
RATE_LIMIT_WINDOW_MINUTES | ● | ||
SITE_DOWN | ● | ||
USE_NPM_INSTALL | |||
USE_SPLIT_MIDDLEWARE |
Auth & crypto
| Key | API | WWW | Admin |
|---|---|---|---|
CRONS_API_KEY | ● | ||
CRYPTO_KEY | ● | ||
JWT_ALGO | |||
JWT_SECRET | ● | ● | |
NEXT_JWT_SECRET | |||
NEXT_PUBLIC_ENCRYPT_SECRET | ● | ||
RECAPTCHA_SECRETE_KEY | ● | ||
RECAPTCHA_SITE_KEY | ● | ||
TOTP_ENCRYPTION_KEY | ● |
OAuth / social
| Key | API | WWW | Admin |
|---|---|---|---|
FACEBOOK_CLIENT_ID | ● | ||
FACEBOOK_CLIENT_SECRET | ● | ● | |
GOOGLE_CLIENT_ID | ● | ||
GOOGLE_CLIENT_SECRET | ● |
Firebase (push notifications — API only)
| Key | API | WWW | Admin |
|---|---|---|---|
FIREBASE_AUTH_PROVIDER_X509_CERT_URL | ● | ||
FIREBASE_AUTH_URI | ● | ||
FIREBASE_CLIENT_EMAIL | ● | ||
FIREBASE_CLIENT_ID | ● | ||
FIREBASE_CLIENT_X509_CERT_URL | ● | ||
FIREBASE_PRIVATE_KEY | ● | ||
FIREBASE_PRIVATE_KEY_ID | ● | ||
FIREBASE_PROJECT_ID | ● | ||
FIREBASE_TOKEN_URI | ● | ||
FIREBASE_TYPE | ● |
Google services
| Key | API | WWW | Admin |
|---|---|---|---|
GA_PROPERTY_ID | ● | ||
GOOGLE_APPLICATION_CLIENT_EMAIL | ● | ||
GOOGLE_APPLICATION_PRIVATEKEY | ● | ||
GOOGLE_APPLICATION_WALLET_CLIENT_EMAIL | ● | ||
GOOGLE_APPLICATION_WALLET_PRIVATEKEY | ● | ||
GOOGLE_TRASLATE_CLIENT_EMAIL | ● | ||
GOOGLE_TRASLATE_PRIVATEKEY | ● | ||
GOOGLE_TRASLATE_TEXT_KEY |
Payments
| Key | API | WWW | Admin |
|---|---|---|---|
STRIPE_PK | ● | ● | |
STRIPE_SK | ● |
Email & SMS
| Key | API | WWW | Admin |
|---|---|---|---|
EMAIL_ALERT | ● | ||
FROM_EMAIL | ● | ||
MANDRILL_API_KEY | ● | ||
TWILIO_ACCOUNDSID | ● | ||
TWILIO_AUTHTOKEN | ● | ||
TWILIO_PHONE_UK | ● | ||
TWILIO_PHONE_US | ● |
Storage (S3)
| Key | API | WWW | Admin |
|---|---|---|---|
S3_BASE_URL | ● | ● | |
S3_BUCKET_ACCESS_KEY_ID | ● | ||
S3_BUCKET_NAME | ● | ||
S3_BUCKET_SECRET_ACCESS_KEY | ● | ||
S3_REGION | ● |
AI
| Key | API | WWW | Admin |
|---|---|---|---|
OPENAI_KEY | ● |
Admin app
| Key | API | WWW | Admin |
|---|---|---|---|
NEXT_PUBLIC_API_URL | ● | ||
NEXT_PUBLIC_APP_URL | ● |
Jira automation
| Key | API | WWW | Admin |
|---|---|---|---|
JIRA_ACCOUNT_EMAIL | ● | ||
JIRA_ACCOUNT_TOKEN | ● | ||
JIRA_ISSUE_TYPE_ID | |||
JIRA_MEMBER_ALEX | ● | ||
JIRA_MEMBER_VIVEK | ● | ||
JIRA_PROJECT_ID |
Postman docs
| Key | API | WWW | Admin |
|---|---|---|---|
POSTMAN_FUSE_MATRIX_DOC | |||
POSTMAN_MOBILE_DOC | |||
POSTMAN_TOKEN |
Referenced by none of the three apps (14):
REDIS_USERNAME,COOKIE_DOMAIN_API,COOKIE_DOMAIN_WWW,USE_SPLIT_MIDDLEWARE,JWT_ALGO,NEXT_JWT_SECRET,GOOGLE_TRASLATE_TEXT_KEY,JIRA_ISSUE_TYPE_ID,JIRA_PROJECT_ID,POSTMAN_TOKEN,POSTMAN_MOBILE_DOC,POSTMAN_FUSE_MATRIX_DOC, plus the DO buildpack flagsNODE_MODULES_CACHE/USE_NPM_INSTALL. The buildpack flags are expected (consumed by DO, not app code); the rest are drift candidates — likely used in scripts/CI, accessed dynamically, or stale. Verify before removing. NotablyNEXT_JWT_SECRETis set on theiba-adminDO app but unreferenced inadmin/source.
Some keys carry historical typos baked into the code (
RECAPTCHA_SECRETE_KEY,TWILIO_ACCOUNDSID,GOOGLE_TRASLATE_*). They’re listed as-is — renaming them is a coordinated code+Infisical change, not a doc fix.
Infisical: assistant project
Separate Infisical project, Model B — synced 1:1 into
tunnelflight-assistant’s DO env, so the DO app’s keys are the project’s
secret set.
| Group | Keys |
|---|---|
| Anthropic / model | ANTHROPIC_API_KEY, ASSISTANT_MODEL |
| Assistant config | ASSISTANT_USERS, ASSISTANT_STAFF_ROLE_IDS, ASSISTANT_ARTIFACTS_BUCKET, ASSISTANT_CRONS_API_KEY, ASSISTANT_JWT_SECRET |
| Database | ASSISTANT_DB_NAME, ASSISTANT_DB_USER, ASSISTANT_DB_PASSWORD, DB_HOST, DB_NAME, DB_PORT, DB_MIGRATE_USER, DB_MIGRATE_PASSWORD |
| AWS / storage | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION |
| Ops / observability | API_BASE_URL, SENTRY_DSN, OPS_ALERT_EMAILS, LOG_LEVEL, RELEASE_VERSION |
| Runtime flags | NODE_ENV, IS_PRODUCTION, SKIP_INFISICAL |
⚠️ Component-level drift (found 2026-08-03). The live app has 24 of these keys set a second time at component level with
type: GENERAL— i.e. plaintext, and returned in full bydoctl apps spec getto any token with app read access. Component-level wins over app-level in DO, so the plaintext copies are the ones actually in effect and the encrypted app-level values are inert.They can’t just be deleted: 20 of 24 match Infisical, but 4 diverge —
ANTHROPIC_API_KEY,ASSISTANT_JWT_SECRET,ASSISTANT_USERS(live is narrower than Infisical’s), andIS_PRODUCTION(livefalsevs Infisicaltrue). Dropping the block would swap the Anthropic key, invalidate every session via a new JWT secret, widen the user list, and flip the prod flag.The safe remediation is to convert them in place to
type: SECRET— same values, encrypted — then reconcile the 4 divergences deliberately. TheIS_PRODUCTION=falseis inert today only becauseassistant/src/lib/infisical.tschecksSKIP_INFISICAL === "1"first.
Infisical: mobile signing & store credentials
/mobile holds the 15 credentials used to sign and publish the React Native
apps. It exists in prod only — there is no staging/dev equivalent, because
signing identities aren’t environment-scoped.
These are the highest-blast-radius secrets in the project: they can publish builds to the App Store and Play Store under IBA’s identity. Nothing deployed reads them; they’re consumed by local Fastlane runs and mobile CI.
| Group | Keys |
|---|---|
| Android signing | ANDROID_APP_ALIAS, ANDROID_APP_PRIVATE_KEY, ANDROID_ALIAS_STORE_PW, ANDROID_KEY_STORE_PW, ANDROID_KEYSTORE_JKS_B64 |
| Google Play | GOOGLE_PLAY_JSON_KEY, PLAY_SERVICE_ACCOUNT_JSON_B64 |
| iOS signing | IOS_DIST_CERT_P12_B64, IOS_DIST_CERT_P12_PW, IOS_ASC_KEY_P8_B64, TEAM_ID |
| App Store Connect | APP_STORE_CONNECT_API_KEY_KEY_ID, APP_STORE_CONNECT_API_KEY_ISSUER_ID, APP_STORE_CONNECT_API_KEY_KEY_FILEPATH |
| Observability | SENTRY_AUTH_TOKEN (source-map upload) |
The
_B64suffixes are base64-wrapped binaries (keystore, P12, P8) — Infisical stores them as single-line strings. Decode to a temp file at use time; don’t commit the decoded artefact.
Infisical→DO sync
The connector lets Infisical be the single source of truth and push secrets into DigitalOcean — so secrets aren’t re-entered in DO by hand and the app doesn’t depend on a runtime Infisical login. All deployed apps now use this (api, www, admin, the dev playground, and the assistant).
| Step | Action | Where |
|---|---|---|
| 1 | Create/reuse a DO API token — scopes: App read + update, plus actions / regions / sizes read. DO tokens are account-wide and shown once. | DO console → API → Tokens |
| 2 | Add an org-level DigitalOcean App Connection (method: API Token) so every project’s syncs share one credential (one rotation point). | Infisical → Organization Settings → App Connections |
| 3 | Create a Secret Sync: source environment + path → destination DO app. | Infisical → project → Secret Syncs |
⚠️ DigitalOcean sync is overwrite-only — no import/merge mode. The first sync makes the DO app’s env a mirror of the Infisical source, deleting any DO-only var not in Infisical. For an app still on Model A (runtime pull, e.g. the preview apps), that prunes the
INFISICAL_*bootstrap vars it needs → boot crash. Mitigate: enable “Disable Secret Deletion” so the sync upserts without pruning. This is what protected the bootstrap during each cutover (validated oniba-dev-apifirst).
Migration: flat project → foldered project (complete)
We moved from the single flat project (c02f5163…) to a foldered project
(b0466e3e-98a7-4cb8-9db1-97dfa5d8da74) where each app has its own folder, shared
values are single-sourced, and every deployed app runs on Model B (sync).
Completed June 2026. The gotchas and runbook below are kept as the record of how.
Target structure (b0466e3e…, per env)
| Folder | Contents | Shared values via |
|---|---|---|
/shared | 12 keys used by ≥2 apps (canonical) | — |
/api | 57 API-only keys (canonical DB_HOST/DB_PORT/DB_NAME) | imports /shared |
/www | 6 WWW-only keys | imports /shared |
/admin | 3 NEXT_PUBLIC_* | — (admin doesn’t use /shared) |
/assistant | 26 keys — assistant’s own set | references /api for DB_HOST/DB_PORT/DB_NAME (${env.api.KEY}) |
/github-ci | 13 CI credentials, fetched over OIDC | — |
/mobile | 15 app-signing / store-publishing credentials — prod only | — |
Use “Add Secret Import” (root-level link) for /api//www → /shared —
not “Replicate”, which nests a /api/shared subfolder a sync won’t reach.
Hard-won gotchas (read before touching this)
- Deployed apps never sync from
dev. Thedevenvironment holds local-docker values (DB_HOST=mysql,REDIS_HOST=redis) for developers’ machines — unreachable from a deployed app. Deployed apps sync fromprod(the real apps) orstaging(the dev/preview playground —staginghas the real prod-cluster hosts but a separateDB_NAME, so it reaches real infra without touching prod data). - Create the Secret Sync inside the new project — syncs are project-scoped;
one created under the old flat project can’t find
/api. - Imports flow through DO syncs (verified on dev): syncing
/apipushes its own keys + the 12 imported from/shared(57 + 12 = 69 as of 2026-08-03; it was 53 + 12 = 65 at cutover). No references-fallback needed for api/www . - DO sync is overwrite-only → set Disable Secret Deletion = ON, or it prunes the component-level bootstrap vars and the app crash-loops.
- App-level vs component-level: the sync writes app-level env; the
bootstrap
INFISICAL_*and DO build flags (USE_NPM_INSTALL,NODE_MODULES_CACHE) live component-level. DO merges them (component wins on conflict) — keep them disjoint. SKIP_INFISICAL=1(component-level, not synced) turns off the runtime pull so the app runs purely on synced env — the Model-A→B switch. Don’t reuseIS_PRODUCTIONfor this (it also gates prod cron side-effects).- Multi-line values (PEM keys): the CLI’s bulk
secrets set --filerejects them — set each viaKEY=@file. (The DO sync handles multi-line fine; this is only a CLI-import concern.)
Per-app cutover runbook (dev-first, one app at a time)
- Create a Secret Sync in project
b0466e3e…: source env (prod for real apps; staging for the playground) + path (/api/www/admin) → destination DO app, connectiondigitalocean-iba, Overwrite + Disable Secret Deletion ON. (/admin’sNEXT_PUBLIC_*need BUILD_TIME scope.) - Trigger it — editing source config doesn’t auto-push; run the sync.
doctl-verify the app’s env: expected count landed (api 69, www 18, admin 3+), bootstrapINFISICAL_*survived, hosts reachable.- Set
SKIP_INFISICAL=1on the app (component-level) → redeploy. - Verify boot via
doctl apps logs --type run: no Infisical pull, server starts, DB/Redis connect. - Clean up: remove the 5 dead
INFISICAL_*bootstrap vars (keepSKIP_INFISICAL+ the build flags).
Status (updated 2026-08-03)
- ✅ New project populated + verified;
/sharedimports +/assistantreferences wired. - ✅
SKIP_INFISICALshipped inapi/www(PR #672). - ✅
iba-dev-api(playground) — synced from staging,SKIP_INFISICAL=1, bootstrap removed. - ✅
iba-www— synced from prod (NPM_CONFIG_PRODUCTION=falseto keepsassat build),SKIP_INFISICAL=1, bootstrap removed. - ✅
iba-admin— synced 3NEXT_PUBLIC_*from prod, component shadows removed (NEXT_JWT_SECRETconfirmed unused — login verified). - ✅
iba-api— synced from prod,SKIP_INFISICAL=1, bootstrap removed from both the web service and thedb-migratejob (Pre-Deploy migrations now run on app-level syncedDB_MIGRATE_*). - 🔸
tunnelflight-assistant— already Model B on its own project; the new/assistantfolder is prepared (DB coords reference/api), but cutting the assistant DO app to the new project is optional and not done. - ✅ GitHub Actions → Infisical (pull + OIDC) — shipped. Five workflows
authenticate via OIDC against
/github-ci;GITHUB_TOKENis the only secret left in GitHub. See GitHub Actions secrets. The path landed as/github-ci, not the originally-planned/ci. - ⏳ Rotate
INFISICAL_CLIENT_SECRET— still outstanding, and the oldest open item here. SeeSECURITY-credential-rotation-pending.mdin the repo root for the full runbook. The blast radius has shrunk since that runbook was written: it lists the DO app env var and the GitHub Actions secret as consumers, and both are now gone. What remains is the Infisical dashboard itself, the copy in/github-ci, and developers’ localinfisical.envfiles — no production redeploy required. - ⏳ Decommission the old flat project
c02f5163…once the cutover’s bedded in. - 🔸
tunnelflight-assistantcomponent-level env drift — 24 keys are set a second time at component level asGENERAL(plaintext, readable by any app-read token), shadowing correctSECRETapp-level entries. 20 of the 24 match the Infisical values; 4 diverge (ANTHROPIC_API_KEY,ASSISTANT_JWT_SECRET,ASSISTANT_USERS,IS_PRODUCTION), so they cannot simply be deleted without changing running behaviour. Found 2026-08-03.
Rotation & expiry
| Item | Rule / trigger | Action |
|---|---|---|
| DO API token | Expires 2027-05-28; every sync using it then fails silently. | Rotate before expiry; update the org App Connection. |
Infisical client secret (INFISICAL_CLIENT_SECRET) | Shown once; the in-use value can’t be revealed. Exposed in git history (9 commits, via the formerly-tracked infisical.env) and still live. Consumers are now: Infisical itself, the copy in /github-ci, preview apps (injected at creation), and local infisical.env files. | Add a new client secret to the identity (don’t revoke the in-use one), update /github-ci + local files, smoke-test one preview app, then revoke the old. Revoking neutralises the git-history exposure; the git filter-repo scrub is hygiene after that. |
| Any value | Not readable from any store. | Treat “I can’t find the value” as “create a new one,” not “look harder.” |
See also
- Database migrations — the migration runner uses
DB_MIGRATE_USER/DB_MIGRATE_PASSWORD. - GitHub workflows — the consumers of the GitHub Actions secrets.