Skip to content

secrets

github-actions[bot] edited this page Aug 12, 2026 · 3 revisions

Advanced: secrets & keys

Agents often need secrets inside the environment — API keys, tokens, a project .env. Forge Fleet gives you three mechanisms, each suited to a different shape of secret. Pick by what the secret is and how the code expects to read it.

Mechanism Config key Secret arrives as Best for
Env file docker_env_file Environment variables in the container API keys/tokens the process reads from the environment (ANTHROPIC_API_KEY, LINEAR_API_KEY, DB URLs)
File snapshot copy_files A copy of a file placed in the worktree A project .env / local config file the app loads from disk
Bind mount extra_mounts A live-mounted host path in the container Directories or credentials you want shared as-is (e.g. ~/.ssh)

1. docker_env_file — inject environment variables

Point at an env file; its KEY=value lines are passed to the container via docker run --env-file, so they're present as environment variables for every process inside.

# A relative path resolves against this config file's own directory.
docker_env_file = "docker.env"
$ ffleet up SLUG --docker-env-file ./docker.env
# docker.env
ANTHROPIC_API_KEY=sk-ant-…
LINEAR_API_KEY=lin_api_…
DATABASE_URL=postgres://…

Use this for runtime secrets read from the environment. It's also the natural home for LINEAR_API_KEY when using Linear templates, and the companion to [claude].auth = "external", where you supply credentials yourself instead of letting ffleet's preflight find them.

The env file itself lives on the host and is never committed into the repo — keep it out of version control.

2. copy_files — snapshot a file into the worktree

Some apps don't read the environment; they load a file from disk (a .env, a config/local.json). copy_files snapshots gitignored files from your main checkout into each new worktree, at the same relative path.

copy_files = [".env", "config/local.json"]

Key properties:

  • One-time copy at creation, not a live link — later edits on either side don't sync.
  • The agent works on the copy, so it can't clobber your real file.
  • Entries are relative to the main checkout; globs are allowed.

Prefer this over a mount for env/local-config files. Inside the container the file appears at, e.g., /workspace/.env.

3. extra_mounts — bind-mount a host path

When you want the container to see a host directory or credential as-is, mount it. This is a live bind mount, not a copy.

extra_mounts = [
  "~/.ssh:/home/buddy/.ssh",
  "~/.agents:/home/buddy/.agents",
]

Format is source:target[:mode]: the target must be an absolute container path, a relative source resolves against the repo root, and ~ expands to the host home. Use this for things like SSH keys or shared caches — anything you want shared and kept in sync, accepting that the container has live access to the real path.

Choosing

  • The value is a credential the process reads from the environment → env file.
  • It's a file the app loads from disk, and the agent shouldn't touch your original → copy_files.
  • It's a directory/credential you want shared live, edits included → extra_mounts.

Related

Clone this wiki locally