GitHub

Secrets Management

Application secrets are stored as a single JSON object in GCP Secret Manager. Each environment (production, non-production) has its own GCP project containing a vault secret (e.g., hbcrm-vault).

At container startup, the entrypoint script calls fetch_secrets.sh, which authenticates through a two-step chain: first it gets a VM service account token from the GCE metadata server, then uses that to fetch a vault service account key from the vault-keys project, and finally exchanges that for a token to read the actual app secrets from the vault-secrets project. The fetched JSON is parsed and each key-value pair is written as an individual file to /app/secrets/. The envdir utility then exports each file as an environment variable, making secrets available to Django via os.environ.

If GCP is unavailable, the script falls back to a Redis cache of the last successful fetch.

Environment Console URL
Production prj-bu1-p-vault-secrets-8d4a
Non-production prj-bu1-n-vault-secrets-9d03

Tip: Always update non-production first, deploy and verify, then repeat for production.

Steps

  1. Open the vault for your target environment using the links above. The vault secret is named {app_name}-vault Click the secret, open the latest version, and click “View secret value”.

  2. Copy the entire JSON to a temporary local file:

    Warning: This file contains every secret for the environment. Do NOT save it inside the repo or leave it on disk.

  3. Edit the JSON – add a new key or update an existing value:

    {
      "EXISTING_SECRET": "existing-value",
      "NEW_OR_UPDATED_SECRET": "your-secret-value-here"
    }

    Key names are case-sensitive and must match what the application reads via os.environ.get().

  4. Validate the JSON by pretty-printing it to verify syntax and content:

    python -m json.tool $TEMP_FILE
    
    # OR
    jq . $TEMP_FILE
  5. Upload the new version – on the vault secret page, click “+ New Version”, paste the updated JSON, and click “Add new version”.

  6. Disable the previous version to prevent rollback to stale data. It can be re-enabled if needed.

  7. Delete the temporary file.

  8. Deploy. On next deploy, containers automatically pull the latest version. The secret is available in the application as os.environ.get("YOUR_SECRET_NAME") – no additional configuration needed.

Notes for HA Admin Portals

  • Add the secret key and placeholder value to .env (prod and staging)
    • .webapp for the Admin Portal Apps
    • .interfacetaskservice for Interface Tasks
    • .interfacetaskwebtest for Interface Task Swagger, e.g., https://massmu.myhaapp.com/test
Edit this page