Skip to content

Bitwarden naming convention — Last1 products

Date: 2026-08-10 (R940 authority update 2026-08-18)
Status: Approved standard. R940 is live; AWS ECS keys are historical only.


Purpose

One greppable pattern across Bitwarden Secrets Manager projects so operators can:

  • Distinguish staging vs prod vs shared values on R940
  • Separate product-owned secrets from cross-product platform secrets
  • Map BWS storage names to runtime env vars via deploy scripts (no application renames required for LastVet API)

Pattern

{PRODUCT}_{TARGET}_{ENV}_{PURPOSE}
Segment Allowed values Meaning
PRODUCT LASTVET, ANGEL, SOVEREIGN, MERIDIAN, LAST1, plus Railway→R940 product codes below Owning product. Use LAST1 / LAST1_PLATFORM only for the last1-platform project (cross-product). Do not use a universal LAST1_R940_* dump for every app.
TARGET R940, RAILWAY, CLOUDFLARE, EDGE, IOS, SHARED, TEST, AWS (retired) Where the value is consumed or which infra lane it belongs to. AWS is historical only (ECS retired August 2026).
ENV STAGING, PROD Logical environment. Omit for global/shared secrets (e.g. Cloudflare account ID).
PURPOSE SNAKE_CASE slug Role of the secret. For API runtime mirrors, suffix with the runtime var name when helpful.

grep cheatsheet

bws secret list | jq -r '.[].key' | grep '_R940_'      # all R940-scoped
bws secret list | jq -r '.[].key' | grep '^LASTVET_'   # all LastVet
bws secret list | jq -r '.[].key' | grep '^LAST1_'     # platform project
bws secret list | jq -r '.[].key' | grep '_RAILWAY_'  # rollback net only

Bitwarden projects

Project ID Holds
lastvet 93af53ce-9afe-45e9-948d-b47a014a75d9 LastVet API, edge, R940 DB/MinIO, iOS-shared API secrets
angel 57bde08e-39ff-4989-9b0e-b48800118fa6 Angel API/web Workers, Neon, R2, Ollama lane
sovereign 6f7c74e0-47c7-421a-8f64-b4a00120dc74 Sovereign client + Odysseus/MemPalace runtime (currently empty)
last1-platform (create) Cross-product: token encryption, Onset assertion, shared Cloudflare IDs
meridian (create) Eval harness Ollama, VA sandbox fixture tokens, telemetry
last1-test (create, optional) E2E harness, non-prod automation mailboxes
proxmox 73c620d6-e7fc-425d-9742-b49e00fcb553 Out of product scope; do not merge into product projects

Runtime mapping rule

Application code keeps canonical env var names. BWS keys are operator storage names only.

Deploy scripts (systemd, restore-api-env-from-bws.sh, secrets-pull.sh, Wrangler push) map:

LASTVET_R940_STAGING_DATABASE_APP_URL  →  export DATABASE_APP_URL=...
LAST1_PLATFORM_STAGING_TOKEN_ENCRYPTION_KEY  →  export LAST1_TOKEN_ENCRYPTION_KEY=...
ANGEL_R940_SHARED_OLLAMA_BASE_URL  →  wrangler secret put OLLAMA_BASE_URL
SOVEREIGN_R940_SHARED_ENGINE_URL  →  VITE_ENGINE_URL=... at build time

LastVet API never reads LASTVET_R940_* directly in TypeScript.


Cross-product policy (Ryan decisions 2026-08-10)

Secret Home Per-env copies
LAST1_TOKEN_ENCRYPTION_KEY last1-platform Yes: LAST1_PLATFORM_STAGING_* and LAST1_PLATFORM_PROD_* (distinct per env; generate in BWS, never reuse across security domains)
ONSET_IDENTITY_ASSERTION_SECRET last1-platform Single LAST1_PLATFORM_SHARED_ONSET_IDENTITY_ASSERTION_SECRET unless Onset requires split
Ollama base URL Per product ANGEL_R940_SHARED_OLLAMA_BASE_URL, LASTVET_R940_SHARED_OLLAMA_BASE_URL, SOVEREIGN_R940_SHARED_OLLAMA_BASE_URLhttp://inference-01.tailc3bbdc.ts.net:11434
Cloudflare account ID last1-platform LAST1_PLATFORM_SHARED_CLOUDFLARE_ACCOUNT_ID
Cloudflare API token last1-platform (optional consolidate) Single operator token or per-repo deploy tokens (Ryan to confirm)

Examples by product

LastVet

BWS key Runtime / use
LASTVET_AWS_STAGING_DATABASE_APP_URL Retired. ECS staging (AWS decommissioned August 2026).
LASTVET_R940_STAGING_DATABASE_APP_URL DATABASE_APP_URL on lastvet-api VM (staging systemd)
LASTVET_R940_PROD_DATABASE_APP_URL DATABASE_APP_URL on lastvet-api VM (prod systemd)
LASTVET_R940_STAGING_MIGRATION_DATABASE_URL MIGRATION_DATABASE_URL (full URL, lastvet_master role, staging)
LASTVET_R940_PROD_MIGRATION_DATABASE_URL MIGRATION_DATABASE_URL (prod)
LASTVET_R940_STAGING_VETERAN_JWT_SECRET VETERAN_JWT_SECRET (staging). Distinct from OAUTH_JWT_SECRET, SECURE_LINK_HMAC_SECRET, LAST1_TOKEN_ENCRYPTION_KEY, and prod counterpart. Generate in BWS; do not copy from retired AWS keys.
LASTVET_R940_PROD_VETERAN_JWT_SECRET VETERAN_JWT_SECRET (prod). Same distinct-secret rule as staging.
LASTVET_R940_STAGING_SECURE_LINK_HMAC_SECRET SECURE_LINK_HMAC_SECRET (staging). Distinct from token encryption and JWT secrets.
LASTVET_R940_PROD_SECURE_LINK_HMAC_SECRET SECURE_LINK_HMAC_SECRET (prod).
LASTVET_R940_STAGING_VETERAN_SESSION_EXCHANGE_SECRET iOS Debug + lastvet-api-staging (retired name: LASTVET_AWS_STAGING_VETERAN_SESSION_EXCHANGE_SECRET)
LASTVET_R940_PROD_VETERAN_SESSION_EXCHANGE_SECRET iOS Release + lastvet-api-prod (retired name: LASTVET_AWS_PROD_VETERAN_SESSION_EXCHANGE_SECRET)
LASTVET_EDGE_CLOUDFLARED_TUNNEL_TOKEN cloudflared on lastvet-edge
LASTVET_RAILWAY_STAGING_DATABASE_APP_URL Retired. Rollback net torn down before VA production PHI.

Angel

BWS key Runtime / use
ANGEL_CLOUDFLARE_PROD_DATABASE_URL Worker DATABASE_URL (Neon today)
ANGEL_CLOUDFLARE_PROD_SESSION_SECRET Worker SESSION_SECRET
ANGEL_R940_SHARED_OLLAMA_BASE_URL Worker OLLAMA_BASE_URL
ANGEL_R940_SHARED_OLLAMA_MODEL Worker OLLAMA_MODEL
ANGEL_CLOUDFLARE_PROD_R2_ACCESS_KEY_ID Worker R2_ACCESS_KEY_ID

Local docker-compose keys (POSTGRES_*, MINIO_*, REDIS_URL) stay out of production BWS or under ANGEL_LOCAL_DEV_* if stored at all.

Sovereign

BWS key Build-time mapping
SOVEREIGN_R940_SHARED_ENGINE_URL VITE_ENGINE_URL (Odysseus engine on R940; replaces unicorn.*:7000)
SOVEREIGN_R940_SHARED_ENGINE_URL_LOCAL VITE_ENGINE_URL_LOCAL

last1-platform

BWS key Consumers
LAST1_PLATFORM_STAGING_TOKEN_ENCRYPTION_KEY LastVet API staging (+ any product using Last1 OAuth token storage)
LAST1_PLATFORM_PROD_TOKEN_ENCRYPTION_KEY LastVet API prod
LAST1_PLATFORM_SHARED_ONSET_IDENTITY_ASSERTION_SECRET LastVet API, Onset Supabase
LAST1_PLATFORM_SHARED_CLOUDFLARE_ACCOUNT_ID wrangler, GitHub Actions

Meridian

BWS key Runtime mapping
MERIDIAN_R940_SHARED_OLLAMA_BASE_URL OLLAMA_BASE_URL
MERIDIAN_R940_SHARED_OLLAMA_MODEL OLLAMA_MODEL
MERIDIAN_TEST_VA_SANDBOX_ACCESS_TOKEN VA_SANDBOX_ACCESS_TOKEN

Extension — Railway / Supabase → R940 product prefixes (2026-08-20)

Decision (proposed; Ryan to approve): Per-product prefixes, not a universal LAST1_R940_* namespace.

Why not universal: LAST1 already means cross-product platform (last1-platform). A catch-all LAST1_R940_* would collide with that meaning, weaken blast-radius grep, and fight the existing LASTVET_ / ANGEL_ / SOVEREIGN_ / MERIDIAN_ pattern.

Product codes for consolidating apps:

Product BWS PRODUCT segment Example key Suggested BWS project
last1.id LAST1ID LAST1ID_R940_PROD_DATABASE_URL last1id (create)
Onset / clinic.theonset.app ONSET ONSET_R940_PROD_DATABASE_URL onset (create)
last1.app LAST1APP LAST1APP_R940_PROD_DATABASE_URL last1app (create) or shared with RadioCheck until DB split
RadioCheck RADIOCHECK RADIOCHECK_R940_PROD_SERVICE_ROLE_KEY shared with last1.app while Supabase project tcthzakppndkykatoefx remains one DB
RealOutcomes REALOUTCOMES REALOUTCOMES_R940_PROD_DATABASE_URL realoutcomes (create)
last1-admin LAST1ADMIN LAST1ADMIN_R940_PROD_SESSION_SECRET stays in last1-admin project
n8n N8N N8N_R940_PROD_ENCRYPTION_KEY last1-admin or last1-platform ops

Shared-DB exception: last1.app + RadioCheck (+ last1-admin auth) currently share one Supabase project. Until that DB is split, store one Postgres URL under a single agreed owner key (prefer LAST1APP_R940_* as the DB owner; RadioCheck maps the same runtime DATABASE_URL). Do not duplicate divergent copies.

Still cross-product (last1-platform only): token encryption, Onset identity assertion, shared Cloudflare account ID, and any secret consumed by ≥2 product security domains.

Runtime mapping rule unchanged: apps keep canonical env names (DATABASE_URL, SUPABASE_SERVICE_ROLE_KEY, …). systemd / restore scripts map PRODUCT_R940_ENV_PURPOSE → runtime.

Planning context: LAST1_INFRASTRUCTURE_CONSOLIDATION_PLAN.md.


Anti-patterns (do not use)

Bad Why
DATABASE_APP_URL_STAGING No product or target; caused Railway/AWS/R940 confusion
LASTVET_APP_PASSWORD_PRODUCTION Implies prod generically; was Railway-only
OLLAMA_BASE_URL in angel without prefix Not greppable; hid product scope
Storing runtime names without target/env Ambiguous grep; use LASTVET_R940_{STAGING,PROD}_*
Duplicating cross-product keys in every product project Rotation drift; use last1-platform
Copying retired AWS secret values into R940 keys Preserves key reuse; generate distinct values per env
LAST1_R940_* for every consolidating app Collides with platform namespace; prefer LAST1ID_ / ONSET_ / LAST1APP_ / …