Skip to content

Secrets Management

Use secrets for all sensitive values and keep them out of workflow YAML and Git.

Secret Types

  • Platform secrets — JWT keys, admin bootstrap credentials, encryption keys.
  • Connection secrets — API keys, OAuth client secrets, passwords (referenced by name in connections).
  • Runtime service tokens — reload/invocation/internal auth between microservices.

CI Path: Forgejo Environment Secrets

Deploy jobs in deploy.yml bind to Forgejo environments (lab, dev, tst, acc, prd). Environment-scoped secrets override repository defaults.

Before each engine rollout, the workflow step Ensure required Engine auth secrets reconciles Forgejo secrets into Kubernetes:

Forgejo secret K8s secret (key)
IDENTITY_JWT_SECRET meshflows-identity-auth (jwt_secret)
IDENTITY_ENCRYPTION_KEY meshflows-identity-auth (encryption_key)
ORCH_RELOAD_TOKEN meshflows-orchestrator-auth (reload_token)
RABBITMQ_USER / RABBITMQ_PASSWORD / RABBITMQ_INTERNAL_TOKEN meshflows-rabbitmq-auth
STORAGE_SERVICE_READ_TOKEN / WRITE / ADMIN meshflows-storage-auth
SES_SERVICE_TOKEN meshflows-ses-auth (service_token)
CAPABILITY_REGISTRY_TOKEN meshflows-capability-registry-auth (token)
SCHEDULER_RELOAD_TOKEN meshflows-scheduler-auth
ORCHESTRATOR_POSTGRES_PASSWORD meshflows-orchestrator-postgres

Reconcile rules:

  • Empty Forgejo value → keep existing Kubernetes secret value.
  • Neither Forgejo nor K8s value → CI generates a fallback (logged as hint — set explicitly for production).
  • After rotation: update Forgejo secret → redeploy with the same release_id → dependent pods restart when tokens change.

Full table and mandatory vs optional secrets: .github/workflows/README.md.

Setup checklist (Forgejo-only, no kubectl)

  1. Create environments: Settings → Environments → lab, dev, tst, acc, prd.
  2. Set repo-level shared secrets (REGISTRY_*, WORKFLOW_DISPATCH_TOKEN, WIKI_PUSH_TOKEN).
  3. Override per-env secrets on prd/acc (JWT, storage, Postgres passwords).
  4. Deploy via Actions or wait for auto-deploy after green build.
  5. Verify in deploy logs (secret reconcile + post-deploy verify steps).

Optional: kubeconfig helper scripts

For offline bootstrap or legacy tooling (not used by deploy.yml):

# Print base64 kubeconfig for manual paste into Forgejo Actions secrets
bash engine/scripts/generate-cluster-secret.sh --env DEV --kube ~/.kube/config

# Print curl/gh command for a specific forge host
bash engine/scripts/set-cluster-secret.sh \
  --host https://code.meshflows.org --repo meshflowsgpl/meshflows --env DEV \
  --file ~/.kube/config

Forgejo deploy runners use host kubectl; CLUSTER_<ENV> secrets are optional for normal CI.

Local Development

Copy engine/.env.example to engine/.env and replace all placeholder values. Never commit .env.

Manual Kubernetes Pattern

For bootstrap or offline clusters without CI:

kubectl create secret generic meshflows-identity-auth \
  --from-literal=jwt_secret=<value> \
  --from-literal=encryption_key=<value> \
  --namespace meshflows-dev

Offline seed files (/etc/meshflows/secrets.<env>.env + apply-cluster-secrets.sh) are optional bootstrap aids — not required when using Forgejo deploy.

  • Store secrets in Kubernetes Secrets or Forgejo environment secrets — not in Git.
  • Reference secret names in connections; do not inline values in workflow YAML.
  • Rotate secrets on schedule and after incidents.
  • Use unique credentials per production environment (prd, acc).

Validation

  • Ensure pods receive expected env vars after deploy.
  • Confirm traces/logs mask sensitive headers and values.
  • Test credential-dependent workflows after each rotation.
  • Call admin endpoints with X-Reload-Token after changing ORCH_RELOAD_TOKEN.