PLT-1259: 1Password + Railway environment consolidation — brief

Linear: PLT-1259
Date: 2026-04-06
Status: Draft for review — aligns secrets naming with Codex/Cursor/OpenCode/Railway consumers without pasting secret values here.

Linear workflow (as of 2026-04-06): Issue remains Triage; assignee Sam. No further status comments after the initial thread below.

Linear thread (accounted for)

SourceIntentReflected here
Issue comment (2026-04-03)Next steps: inventory → target model → migration plan; align with PLT-1260 on secret sourcingCurrent state, Target state, Ordered actions; explicit coordination with PLT-1260 in action 4 and Related

Ticket open questions (authoritative vaults for Codex vs Cursor vs OpenCode; client-data boundaries) are not closed in this draft — they feed actions 1–2 and the verification matrix.

Summary

Brainforge already uses multiple 1Password vaults (team + per-client vaults). The Brainforge AI Team vault holds shared Platform and automation credentials, including items that directly feed cloud agents (Cursor, Codex-related Azure keys) and Railway automation tokens. Railway projects under the Brainforge org span Platform, OpenWork, Labs, and other services.

Target: Fewer ambiguous patterns: every deploy/agent path should have a named place in 1Password (vault + item purpose) and a documented consumer (Railway service, Codex Cloud, Cursor Cloud, OpenCode worker). The recommended runtime pattern is op-based injection first (op run, op read, service accounts), with 1Password Environments treated as an optional grouping/onboarding layer rather than the sole source of truth.

State-of-the-art guidance to fold into the plan

Recent team practices around local development, agents, and production suggest a cleaner split:

  1. 1Password vault items remain the durable source of truth for actual secrets. Re-usable credentials should live as normal 1Password items/fields, not be duplicated into multiple plaintext .env files.
  2. op is the runtime contract. Local dev, CI, and cloud agents should resolve secrets at execution time with op run / op read, rather than depending on long-lived checked-out env files.
  3. 1Password Environments are optional structure, not a replacement for vault items. They are useful for shared stage-level config and onboarding, but this plan should not assume every secret is authored or managed there.
  4. Agent and CI access should use separate service accounts per trust boundary. Desktop-authenticated local dev is acceptable for non-prod human workflows; Codex/Cursor/OpenCode/Railway automation should use scoped machine credentials.
  5. Client boundaries are vault boundaries first. Shared Brainforge platform credentials can stay in the team vault, but client-specific secrets and any client-auditable credentials should live in client vaults and never be injected into unrelated agent sessions.

Tooling context

  • Doppler represents the “centralized environment injection” model many teams use once they want a strong shared developer experience across local, CI, and production.
  • Varlock represents a complementary “typed env + sensitivity metadata + plugin backend” model; it can sit on top of providers like 1Password rather than replace them.
  • For Brainforge, the main implication is: we do not need a second secrets control plane to get most of the value. The recommended path here is to keep 1Password as the system of record, use op for runtime resolution, and only evaluate a Varlock-style schema layer later if we want stronger app-level env typing/redaction ergonomics.

Current state (inventory)

1Password vaults (account-level)

Vault nameRole
Brainforge AI TeamShared engineering/automation; primary Platform vault
EmployeePersonal API keys
Brainforge <> ABC Home and CommercialClient ABC-scoped material
Brainforge <> EdenClient Eden-scoped material
Brainforge <> Default, Ellie, Insomnia, Magicspoon, ReadMe, Urban StemsOther client vaults
Brainforge Design, Finance, Marketing, Operations, PM, Sales, Shared VaultFunctional vaults

Source: op vault list (2026-04-06).

Brainforge AI Team — items relevant to Platform, agents, Azure, Railway (sample)

Titles only (no values):

Item titleLikely consumers
platform envRailway / local Platform; bundled env reference
brainforge-openai-eastus2Codex, Cursor, Platform — East US 2 canonical
Azure OpenAI (brainforge-openai) + KimiAzure OpenAI usage
Brainforge Github OpenAIGitHub–OpenAI integrations
Cursor Cloud Agent TokenCursor Cloud agents
AI Team Cursor API KeyCursor API usage
Railway Github Marketing Production TokenRailway automation (production)
Railway Github Marketing QA TokenRailway automation (QA)
OpenWork Labs Hosted Runtime TokensHosted OpenWork / Labs

Full listing available via op item list --vault "Brainforge AI Team".

Additional grep for agent/Azure/Railway/OpenAI/Cursor-related titles should be run before any rename/move.

Railway (CLI snapshot)

Account: Logged-in user (Sam Roberts) — Brainforge team.

Projects listed: openwork, brainforge-platform, openwork-labs, google-workspace-mcp, applets, compassionate-comfort.

Source: railway list (2026-04-06).

Align variable sets per service with platform env / service-specific items in 1Password; use railway-cli-setup.md and github-railway-repo-and-services-without-ui.md for CLI operations.

OpenCode worker

See PLT-1160apps/opencode-worker uses Railway production / staging in railway.toml. Secrets for that path must remain in the consolidation map and verification matrix.

Target state (proposal)

  1. Naming: One clear convention for items that are the same secret in multiple places (e.g. East US 2 Azure key) vs purpose-specific tokens (Railway GitHub deploy tokens). Prefer one canonical item for brainforge-openai-eastus2 and document duplicates for retirement.
  2. Runtime pattern: Standardize on 1Password vault items + op injection as the default path for local dev, Codex/Cursor/OpenCode agents, and CI. Treat plaintext .env files as generated/transient only, not authoritative.
  3. 1Password Environments: If used, limit them to shared stage-level config or curated project groupings. Do not require Environments to mirror every underlying secret item one-for-one.
  4. Client boundaries: Use existing Brainforge <> {Client} vaults for client-scoped credentials; Platform-wide keys stay in Brainforge AI Team unless compliance requires client-only storage.
  5. Railway: Each production service has a single documented mapping: Railway project → env var names → 1Password item(s) (reference pull-railway-env.js where applicable).
  6. Automation identities: Separate human local auth from automation service accounts. Production and agent automation should not rely on a developer desktop session.

Railway implementation note

If Brainforge standardizes on op run inside Railway for any service, we may need to move some surfaces to an explicit Dockerfile-based deployment path so the 1Password CLI is guaranteed to exist in the runtime image. That is most likely to matter for Platform or future client deployments where we want Railway to resolve 1Password references at process start instead of relying only on synced platform variables.

Ordered actions (with owners)

#ActionOwnerNotes
1Confirm whether 1Password Environments are in use and list namesPlatform / whoever has adminUI; complement CLI vault list. Record whether they are being used for grouping only or as active runtime inputs.
2Export or script full op item list for Brainforge AI Team; tag each row with consumer (Railway, Codex, Cursor, OpenCode, other)PlatformInternal doc only; no values in Linear. Add a column for source of truth vs generated/runtime-only copies.
3For each Railway project, snapshot variables (railway variables or MCP) and map to 1Password itemsPlatformStaging vs production. Note whether deployment pulls from a synced env set or direct op-managed automation.
4Identify duplicate Azure/OpenAI-related items; propose canonical item and deprecation datePlatformCoordinate with PLT-1260
5Define automation service account boundaries for Codex/Cursor/OpenCode/RailwayPlatformSeparate dev, staging, prod, and client-pilot access; avoid one broad token shared across all agent surfaces.
6Update or add a playbook pointer — draft under knowledge/engineering/environments/ first; merge to knowledge/standards/ when approvedPlatformTicket AC. Capture op-first usage examples and when Environments are optional rather than required.

Standards pointer (drafted)

Future environment work should follow:

That draft standard captures the recommended 1Password + op pattern, optional use of 1Password Environments, trust-boundary rules for service accounts, and minimum post-cutover verification expectations.

Verification matrix (after cutover)

SurfaceCheck
Railway — brainforge-platformDeploy or health URL; critical env vars present
Railway — opencode-workerStaging/prod start; secrets injected
Codex / CursorSmall task using East US 2 key per codex-setup.md
OpenCode workerSmoke per opencode-worker README / deploy

Add one non-functional check during cutover: verify each automation path uses the intended identity (desktop auth for local human dev, service account for CI/agents) and that no client pilot can read unrelated client or production secrets.

Inventory appendix (follow-through)

Machine-assisted inventory (titles and Railway variable names only — no secret values):

Acceptance-criteria status

  • Current vs target layout with rationale: covered in Current state, Target state, and the inventory appendix.
  • Concrete actions with owners and order: covered in Ordered actions.
  • Playbook or standards pointer drafted: covered by env-and-credential-pattern.md.
  • Verification steps for Railway, Codex Cloud, and OpenCode paths: covered in Verification matrix.

Paste for Linear (comment)

PLT-1259 draft brief (vault + Railway inventory, target state, ordered actions, verification):
knowledge/engineering/environments/plt-1259-op-vault-railway-env-consolidation-brief-2026-04-06.md
Next: admin pass on 1Password Environments (if used), full item-to-consumer mapping, explicit op + service-account runtime plan, then playbook PR when ready.