Skip to content

Secrets migration mapping — GCP Secret Manager → Coolify per-app encrypted env

Secrets migration mapping — GCP Secret Manager → Coolify per-app encrypted env

Section titled “Secrets migration mapping — GCP Secret Manager → Coolify per-app encrypted env”

Task: ID-66.10 — Migrate secrets into Coolify per-app encrypted env (TECH change 3, migration step 5).

Purpose: Runbook for the operator performing the one-time manual copy of runtime secret values out of GCP Secret Manager into Coolify’s per-app encrypted env. This document contains env-var names, which service needs them, the GCP Secret Manager secret name, and the gcloud fetch command only. No secret values appear here.

Coolify dashboard: http://77.68.122.71:8000 (per {66.6} runbook).

Reference: docs/specs/ID-66-onprem-pivot/TECH.md §“3. Secrets migration” and .github/workflows/cloud-run-deploy.yml lines 347–409.


Base set — needed by the cocoindex service (and inherited by all pipeline jobs)

Section titled “Base set — needed by the cocoindex service (and inherited by all pipeline jobs)”
env varserviceGCP Secret Manager namefetch commandnotes
ANTHROPIC_API_KEYcocoindexANTHROPIC_API_KEYgcloud secrets versions access latest --secret=ANTHROPIC_API_KEYLLM provider key
OPENAI_API_KEYcocoindexOPENAI_API_KEYgcloud secrets versions access latest --secret=OPENAI_API_KEYEmbeddings
SUPABASE_URLcocoindexSUPABASE_URLgcloud secrets versions access latest --secret=SUPABASE_URLSupabase project URL
SUPABASE_PUBLISHABLE_KEYcocoindexSUPABASE_PUBLISHABLE_KEYgcloud secrets versions access latest --secret=SUPABASE_PUBLISHABLE_KEYAnon/publishable key
SUPABASE_SERVICE_ROLE_KEYcocoindexSUPABASE_SERVICE_ROLE_KEYgcloud secrets versions access latest --secret=SUPABASE_SERVICE_ROLE_KEYService-role key — high privilege
NEXT_PUBLIC_SUPABASE_URLcocoindexNEXT_PUBLIC_SUPABASE_URLgcloud secrets versions access latest --secret=NEXT_PUBLIC_SUPABASE_URLClient-facing Supabase URL
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYcocoindexNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYgcloud secrets versions access latest --secret=NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYClient-facing anon key
NEXT_PUBLIC_APP_URLcocoindexNEXT_PUBLIC_APP_URLgcloud secrets versions access latest --secret=NEXT_PUBLIC_APP_URLVercel app origin
CRON_SECRETcocoindexCRON_SECRETgcloud secrets versions access latest --secret=CRON_SECRETAuth token for inbound pipeline-runs/record webhook
SENTRY_AUTH_TOKENcocoindexSENTRY_AUTH_TOKENgcloud secrets versions access latest --secret=SENTRY_AUTH_TOKENError reporting
env varserviceGCP Secret Manager namefetch commandnotes
COCOINDEX_DB_DSNcocoindexCOCOINDEX_DB_DSNgcloud secrets versions access latest --secret=COCOINDEX_DB_DSNBoot-required. Supabase pooler connection string (region-qualified aws-<n>-<region> form). Must be present before /health serves. This is the engine’s asyncpg DSN — NOT the LMDB path (COCOINDEX_DB).
PIPELINE_RUN_WEBHOOK_URLcocoindexPIPELINE_RUN_WEBHOOK_URLgcloud secrets versions access latest --secret=PIPELINE_RUN_WEBHOOK_URLSet after {66.13} confirms the webhook repoint. The value is the Vercel app URL for app/api/internal/pipeline-runs/record. Read by flow.py:_emit_pipeline_run_webhook.
PULLMD_API_TOKENcocoindexPULLMD_API_TOKENgcloud secrets versions access latest --secret=PULLMD_API_TOKENBearer token sent by the cocoindex adapter to pullmd. Retained as defence-in-depth even over the host-local compose network (inv 11).
env varserviceGCP Secret Manager namefetch commandnotes
PULLMD_ADMIN_EMAILpullmdPULLMD_ADMIN_EMAILgcloud secrets versions access latest --secret=PULLMD_ADMIN_EMAILSingle-admin mode (PULLMD_AUTH_MODE=single-admin). Boot-required.
PULLMD_ADMIN_PASSWORDpullmdPULLMD_ADMIN_PASSWORDgcloud secrets versions access latest --secret=PULLMD_ADMIN_PASSWORDSingle-admin password. Boot-required.
PULLMD_API_TOKENpullmdPULLMD_API_TOKENgcloud secrets versions access latest --secret=PULLMD_API_TOKENSame secret as the cocoindex entry above — the shared Bearer token. Paste into the pullmd app env separately.

The following GCP credentials are eliminated by B1 and must NOT be pasted into Coolify:

  • GCP deploy-SA JSON (kh-cocoindex-pipeline-deploy@… service-account key) — B1 eliminates gcloud run deploys entirely ({66.17}, TECH change 4). No deploy-SA JSON ever lands on the host (PRODUCT invariant 12).
  • WIF credentials (GCP_WIF_PROVIDER / GCP_DEPLOY_SA_EMAIL GitHub vars) — retired with cloud-run-deploy.yml. These stay in the GitHub repo variables for reversibility (invariant 24) but are not needed on the Coolify host.

PULLMD_SERVICE_URL is not migrated as a secret. In the B1 co-location compose, cocoindex and pullmd share the same Docker network. The value becomes the non-sensitive plain string http://pullmd:3000 (the Docker compose service alias). This is an ordinary, non-sensitive env var set directly in deploy/coolify/docker-compose.production.yaml or in Coolify’s non-secret env section (TECH change 1 / PRODUCT invariant 11).

The existing GCP Secret Manager secret named PULLMD_SERVICE_URL can be left in place for reversibility (the Cloud Run manifests still reference it) — it does not need to be deleted.


  • Coolify dashboard reachable at http://77.68.122.71:8000 (verified in {66.6}).
  • gcloud CLI authenticated with access to the kh-prod-494815 project.
  • The Coolify application(s) for cocoindex and pullmd must already be created via the Docker Compose build pack ({66.8}).
  1. Open Coolify → navigate to the relevant application (cocoindex or pullmd).
  2. Go to Environment Variables for that application.
  3. For each row in the secret table above: a. Run the fetch command in a terminal: gcloud secrets versions access latest --secret=<NAME> b. Copy the returned value. c. In Coolify, add a new env var: set the key to the env var name from the table; paste the value. d. Mark the var as secret/encrypted (Coolify hides the value after save — OQ-66-3).
  4. Save and redeploy.

Important: paste the value directly and immediately. Do not write it to a file, pipe it to a variable in a persistent shell, or commit it anywhere. The intent of this runbook is names + commands only — values flow operator-to-Coolify UI and nowhere else.

Coolify exposes a REST API (http://77.68.122.71:8000/api/v1) that accepts env-var create calls. This is useful for scripted bulk-import. It requires a Coolify API token (generate one in Coolify → Profile → API Tokens). The API approach is not implemented here — it is noted as an option for B2 when Infisical or a more automated secret-sync workflow is adopted (OQ-66-3, Infisical deferred to B2).


gcloud secrets list --project=kh-prod-494815 (names only, no values) confirms the following secret names exist as of 2026-05-31:

ANTHROPIC_API_KEY
COCOINDEX_DB_DSN
CRON_SECRET
FIRECRAWL_API_KEY
NEXT_PUBLIC_APP_URL
NEXT_PUBLIC_CLIENT_ID
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
NEXT_PUBLIC_SUPABASE_URL
OPENAI_API_KEY
PIPELINE_RUN_WEBHOOK_URL
PULLMD_ADMIN_EMAIL
PULLMD_ADMIN_PASSWORD
PULLMD_API_TOKEN
PULLMD_SERVICE_URL
SENTRY_AUTH_TOKEN
SUPABASE_PUBLISHABLE_KEY
SUPABASE_SERVICE_ROLE_KEY
SUPABASE_URL

All 17 secret names required by this runbook are present in the list above. (FIRECRAWL_API_KEY and NEXT_PUBLIC_CLIENT_ID are present in GCP SM but are not part of the B1 migration set — they are not referenced by the cocoindex or pullmd services in cloud-run-deploy.yml:347–409.)