Skip to main content
Trinity
Guides/Credential Management

Credential Management

Add, edit, and hot-reload credentials on agents without restarting them. Includes direct file injection, encrypted storage, OAuth flows, and subscription token management.

Overview

Trinity uses a direct file injection system. Credentials are written as .env (KEY=VALUE) and .mcp.json (generated from template) directly to the agent container.

A template says which credentials its agent needs in template.yaml: credentials: lists the variable names, and the optional sibling credential_setup: describes each one. The Setup Checklist on the Credentials tab is the per-variable view: what this agent needs, which are already set, and where to get the missing ones.

Credentials can be exported to encrypted .credentials.enc files (AES-256-GCM) for backup and import.

The Setup Checklist

Open the agent detail page and click the Credentials tab. The checklist answers three questions per credential:

ColumnWhere it comes from
What does this agent need?The declaration in the agent's live workspace template.yaml — so a forked or hand-edited agent reports its actual requirements, not its original template's
Is it set?A bounded probe of the agent's own .env, reporting key names that have a non-empty value. Values are never read or transmitted.
Where do I get it?The template author's setup_url, rendered with a canonical host so the link's label can never disagree with its destination

Fill in the values you have and submit — the checklist writes through the same owner-gated injection path as everything else on this tab.

The checklist renders even when the agent is stopped: you can see what an agent will need before starting it, with the live-status column honestly reported as unavailable. If the status probe fails, you are told so — a failed probe is never shown as “nothing configured”.

Reading this checklist is owner-only and human-only: it is an operator surface, and agent-scoped API keys are rejected.

Credential files management showing configured and missing status

Declaring Credentials in a Template

credentials:
  env_file:
    - OPENAI_API_KEY
  mcp_servers:
    slack:
      env_vars:
        - SLACK_BOT_TOKEN

credential_setup:
  - name: OPENAI_API_KEY
    title: OpenAI API key
    description: Lets the agent call OpenAI models directly.
    required: true
    secret: true
    setup_url: https://platform.openai.com/api-keys

credentials: is names-only and will never accept per-variable objects — that is what keeps older Trinity versions able to read a newer template. All the human-facing detail lives in credential_setup:, where each entry may carry title, description, required, secret, format, setup_url, and a non-secret default.

Two rules make the pair safe:

Every credential_setup: entry must name a variable that credentials: declares. An entry naming anything else is dropped with a named error; its valid siblings survive.
Both keys are read tolerantly. A malformed block produces named errors in the template catalogue and the compatibility report rather than emptying the catalogue or failing the agent's creation.

secret defaults to true and setup_url must be https with no embedded userinfo, so a credential is masked until an author says otherwise and a setup link cannot impersonate a vendor domain.

The full contract is published at docs/schemas/trinity-agent-credentials.schema.json.

Adding Credentials

Add credentials using one of four methods:

Setup checklist — Per-variable inputs, with descriptions and setup links.

Manual entry — Name, value, and service fields.

Bulk import — Paste .env-style KEY=VALUE pairs.

From encrypted backup — Import a .credentials.enc file.

Hot-reload — Paste or edit credentials on a running agent. The .env file is updated and .mcp.json is regenerated immediately. No restart needed.

Credential Pattern

The credential file pattern inside each agent:

.env                    # Source of truth (KEY=VALUE)
.mcp.json.template      # Template with ${VAR} placeholders
.mcp.json               # Generated at runtime from template + .env

Which Files Can Be Injected

Injection accepts a curated set of credential file types, not just .env. Anything outside the allow-list — and anything on the deny-list — is rejected with a 400.

Allowed

PathTypical use
.env, .credentials.enc, .mcp.jsonCore credential files (workspace root only)
.config/gcloud/**Google Cloud SDK credentials / service-account JSON
.kube/configKubernetes kubeconfig
*.pem, *.key, *.crt, *.cert, *.p12, *.pfxTLS certificates and private keys
.ssh/id_*SSH key pairs (keys only — not authorized_keys or config)

Always blocked (deny takes precedence): anything executed or sourced at startup — shell startup files (.bashrc, .profile, .zshrc, …), agent instruction files (CLAUDE.md, AGENTS.md, .claude/**), .mcp.json.template, .ssh/authorized_keys / .ssh/config, .git/** and .gitconfig, anything under bin/, plus absolute paths and .. traversal. .mcp.json content is structurally validated before it is written.

Binary credentials (certificates, keystores, service-account bundles) round-trip as base64 via the files_b64 field on the inject endpoint.

Export and Import

Export creates an encrypted .credentials.enc file for backup. It captures the full injected credential set — every allow-listed credential file present in the agent (discovered live), text and binary alike — not just .env and .mcp.json. Import decrypts and injects credentials from an encrypted file; the archive is re-validated against the same path policy on the way in. Auto-import runs on agent startup via POST /api/internal/decrypt-and-inject.

Credential values are never logged. All operations use structured logging with values masked.

Rotating the Encryption Key

The platform encryption key (CREDENTIAL_ENCRYPTION_KEY) can be rotated online, with zero downtime and no data loss:

1

Back up the database (scripts/deploy/backup-database.sh).

2

Generate a new key: python3 -c "import secrets; print(secrets.token_hex(32))".

3

In .env, set the new key as CREDENTIAL_ENCRYPTION_KEY and move the previous key to CREDENTIAL_ENCRYPTION_KEY_SECONDARY (a decrypt-only fallback).

4

Restart the backend — existing secrets keep decrypting via the secondary key; all new writes use the new key.

5

Re-encrypt persisted secrets onto the new key: docker compose exec backend python scripts/deploy/rotate-credential-key.py (dry-run), then re-run with --apply.

6

Remove CREDENTIAL_ENCRYPTION_KEY_SECONDARY from .env and restart.

The sweep re-encrypts every database-persisted token (subscriptions, channel bot tokens, GitHub PATs, payment credentials). Per-agent .credentials.enc files re-encrypt onto the new key on their next credential operation; they keep opening via the secondary key until then.

Credential API

EndpointMethodDescription
/api/agents/{name}/credential-requirementsGETPer-variable checklist: declaration joined against live set/missing status. Owner-only and human-only; rate-limited. Returns a degraded body (not an error) for a stopped agent.
/api/agents/{name}/credentials/statusGETCheck credential files
/api/agents/{name}/credentials/injectPOSTInject files directly
/api/agents/{name}/credentials/exportPOSTExport to .credentials.enc
/api/agents/{name}/credentials/importPOSTImport from encrypted file

OAuth Credentials

OAuth2 authentication flows for connecting agents to external services like Google, Slack, GitHub, and Notion.

1

Open the agent's Credentials tab.

2

Click the OAuth provider button (Google, Slack, GitHub, or Notion).

3

Your browser redirects to the provider's authorization page.

4

After you approve access, credentials are normalized to MCP-compatible format and injected into the agent.

Supported Providers

Google — Gmail, Calendar, Drive, and other Google Workspace services

Slack — Workspace access for messaging and channel operations

GitHub — Repository access, issues, pull requests

Notion — Page and database access

OAuth tokens are stored in Redis with AOF persistence. When an OAuth flow completes, Trinity normalizes the token data, regenerates the agent's .mcp.json, and makes the credentials available to all configured MCP servers.

Subscription Credentials

Share Claude Max/Pro subscription tokens across multiple agents, with automatic assignment, health monitoring, and auto-switch on rate limits.

Key Concepts

Subscription — A Claude Max or Pro subscription token registered with Trinity. Stored encrypted (AES-256-GCM).
Round-Robin Assignment — New agents automatically get a subscription assigned. The subscription with the fewest agents is selected first.
Auto-Switch — When an agent hits repeated rate-limit (429) errors, Trinity automatically switches it to a different subscription.

How It Works

1

Go to the Settings page.

2

In the Subscriptions section, click Register Subscription.

3

Enter a subscription name and token. The subscription is encrypted and stored.

4

Expand a subscription row to see assigned agents with assign/unassign controls.

Encryption Requirement

CREDENTIAL_ENCRYPTION_KEY must be set in .env. This is auto-generated by start.sh on fresh deployments. If missing, a warning banner appears on the Settings page, the Register button is disabled, and the API returns 503.

Subscription API

EndpointMethodDescription
/api/subscriptionsGETList all subscriptions
/api/subscriptionsPOSTRegister a subscription
/api/subscriptions/{id}/assignPOSTAssign to an agent
/api/subscriptions/{id}/unassignPOSTUnassign from an agent

Security Best Practices

Credential values are never logged. All operations use structured logging with values masked.
Never commit .env or .mcp.jsonto git — only commit templates and encrypted files
Store the CREDENTIAL_ENCRYPTION_KEY separately from encrypted credential files
Use least-privilege API keys — grant only the scopes each agent needs
Rotate credentials regularly and revoke old keys immediately after rotation