Secrets, Service Setup & Materializer

Trinity stores every API key, token, and config file your project needs in one encrypted store. The full management surface lives in Project Settings → Secrets, which splits into three sub-tabs:

  • Overview — a glance card with counts (configured / needs setup), a pending-setup list per service, and a "Re-sync files" button for materializable rows.
  • Shared — project-wide secrets visible to teammates (tier 3/4). Table view, filters, bulk .env import, per-target editing.
  • Yours — your personal overrides for this project (tier 1/2). Same editor, scoped to your account; teammates never see these rows.

End-to-end encryption

Every secret is encrypted and decrypted on your own devices — the server stores and serves only ciphertext. There is no server-side key: nobody without one of your enrolled devices can read your values, including Trinity.

Two key boundaries decide who can decrypt a row:

  • Your personal key encrypts everything scoped to you — Yours rows and your team-wide personal keys. Teammates can never decrypt these, even though the rows live in the shared team workspace.
  • The team key encrypts shared rows (project-shared and team defaults). Only devices belonging to current team members hold it, and removing a member rotates it — see Teams.

A device only holds keys once it's been approved. Rows your device can't decrypt show as locked rather than exposing anything. Manage devices, approvals, and your recovery code in App Settings → Profile → Devices.

Where secrets land on disk

Most secrets are environment variables — they get injected into the agent's process at execution time and never touch your filesystem. A handful (like dexie-cloud.json or .env.local) need to live as files inside your project — Trinity writes those into your repo under a managed .gitignore block so they never get committed. See The materializer below.

The Shared and Yours editors

Open Project Settings → Secrets and pick Shared or Yours. You'll see a table grouped by key name. A key with two target overrides shows up as one row that expands to reveal the per-target values.

What each row tells you

Column Meaning
Key name The env var name (e.g. STRIPE_SECRET_KEY)
Target Which target this row binds to. "Project-wide" if it applies to every target.
Service The service that owns this key (e.g. stripe, dexie-cloud)
Purpose runtime (env var), provider (AI provider key), file (materializes to disk)
Value Masked. Click the eye icon to reveal — your device decrypts it locally and shows briefly.
Updated Last write time

Filters

  • Search — substring match on key name
  • Targets — filter by one or more targets. "Project-wide" is its own toggle.
  • Purpose — narrow to runtime, provider, or file-purpose secrets

Adding a secret

Click Add secret. The dialog asks for:

  • Key name — the env var name (e.g. STRIPE_SECRET_KEY)
  • Value — what you're storing. Sensitive by default; the input masks the value as you type.
  • Targets — pick one or more targets, or leave as "Project-wide" for cascade fallback. One key can fan out to multiple targets in a single submit.
  • Purpose — defaults to runtime. Pick provider for AI provider keys, file for config files (file purpose adds a destinations field — see The materializer).
  • Sensitive — UI dimension only; controls whether the value is masked by default. Every row is encrypted at rest regardless.

Trinity infers sensitive from the key name (*_SECRET, *_KEY, *_TOKEN, *_PASSWORD default to true) when you don't override.

Editing a secret

Click any row to open the edit dialog. You can change the value, retarget the binding (move from project-wide to target-specific or vice versa), update the label, or delete the entry.

The cascade resolution rule means: if you have a project-wide value for DATABASE_URL and a target-specific value for the same key on the api target, the API target gets its own value and every other target gets the project-wide one. No manual fan-out needed.

Permissions

Who can edit, reveal, or delete a secret depends on the row's tier and the team's Manage Secrets permission setting.

Tier Edit / reveal / delete
Project-shared (Shared) Owner / manager always. Members pass when the team's Manage Secrets permission is set to "all", blocked when set to "owner".
Project per-user (Yours) Each user only. Pinned to your account — teammates never see, edit, or reveal your Yours rows.
Team default (team-wide) Owner / manager only. Members can read masked values and use them at runtime, but cannot write or reveal plaintext.
User team-wide (your /me row) Each user only. Same isolation as project per-user — teammates can't see your team-wide personal keys.

Configure the Manage Secrets permission in Team Settings → Access Control → Permissions, with optional per-project overrides in Project Settings → Permission Overrides. The default is "owner only". Personal scope has no permission gates — everything is yours.

Bulk .env import

Click Import .env to paste a .env file. Trinity:

  1. Parses the file (handles quoted values, escaped newlines, inline comments)
  2. Runs the sensitivity heuristic per key
  3. Lets you pick which targets each key binds to (or all → project-wide)
  4. Picks a conflict policy: keep existing, overwrite, or skip
  5. Submits everything in one transactional write — the whole batch rolls back on any failure

Per-row conflict overrides are available if you want different behavior for some keys. Result rows report created | updated | skipped | error so you can see exactly what happened.

Provider keys

The Project Settings → Provider Keys card is a focused view of purpose='provider' rows for AI providers (Anthropic, DeepSeek, Moonshot, Z.ai, Qwen, Ollama). Same encrypted store underneath; the card just narrows the table to provider rows.

You can also set provider keys globally (across all your projects) in App Settings → AI Models. Cascade rule: project-scoped wins over global.

The materializer

Some setup flows produce config files Trinity needs to write to disk — dexie-cloud.json, .env.local, certificates, or project-specific YAML. These get stored as purpose='file' secrets with destinations (where on disk to write them):

  • target — inside the consuming app's directory (e.g. apps/web/.env.local for a turborepo target)
  • repo — at the repo root (e.g. dexie-cloud.json next to package.json)
  • trunk — at your workspace root (project-wide config)

Trinity's materializer is what writes these files. It runs:

  • Right after a worktree is created (so every parallel story sees the right files)
  • After the setup runner finishes capturing values from a CLI
  • After successful story commits (so freshly-written secrets land before the next phase reads them)
  • On demand via Project Settings → Re-sync files

.gitignore management

Every materialized file gets added to a Trinity-managed block in your repo's .gitignore:

# === Trinity-managed (do not edit between markers) ===
.env.local
config/dexie-cloud.json
# === /Trinity-managed ===

Don't edit between the markers — Trinity will overwrite. Anywhere else in the file is yours to manage. If you delete a file-purpose secret, Trinity unlinks the file and prunes the line from the block on the next materializer pass.

How agents see your secrets

When a story executes, Trinity assembles the env var bag from:

  1. Target-specific rows for the story's target
  2. Project-wide rows (cascade fallback)
  3. Global rows (across all your projects)

The first hit wins per key name. Multi-target stories that don't have a clear target binding raise a gate so you can split the secret per-target or mark it project-wide.

For file-purpose secrets, agents just see the file on disk — the materializer wrote it before the agent ran.

Service setup gates

If you start a story that needs a service Trinity sees as unconfigured, the story pauses at a service setup required gate. The gate dialog has the setup runner pre-bound to the right target — finish the flow and the story resumes automatically. Agents can also raise this gate mid-execution via the signal_service_required tool when they hit a missing service that wasn't on Trinity's radar.

See Execution Gates for the full gate catalogue.