Secrets Protection

A coding agent needs to use secrets — API tokens, database URLs, push credentials — to do real work, but those secrets must never leak into the agent's context or the session transcript. act env sequesters secrets out of the working tree and injects them only into the processes that need them, with output redacted on the way back.

How it works

The model is mostly trigger, occasionally see. By default the agent names nothing and sees nothing — it runs a command and act injects the secrets behind it. On the rare occasion a value must be seen, that takes a deliberate, explicit flag.

1

Sequester

act env import (or act env mv per key) moves plaintext out of the working tree into a per-project store under ~/.config/act/secrets/, written 0600 in a 0700 directory.

→
2

Marked lines

What stays in the repo is the same .env with each sequestered line reading KEY=#act:sequestered — the key name with no value — and every other line untouched. Sequestered lines carry no secret, so they are safe to commit and safe for an agent to read; plaintext and sequestered lines may sit side by side.

→
3

Inject & redact

act env run -- <command> injects the values into the child process environment only, and redacts any secret value that appears in the child's output before it reaches the transcript.

The store is keyed to the project root — --workspace when given, otherwise the git root of the current directory. Linked worktrees share their main checkout's store, while each worktree's own .env is the one edited. Each root gets its own isolated store.

Threat boundary

This stops accidental leakage — the agent reflexively reading a .env, or a command echoing a token into a log. It is intentionally lean: no vault, no policy engine, no gateway, and no defense against an actively malicious or prompt-injected agent that is determined to exfiltrate a value it is allowed to use. For that, don't give the agent the secret.

Secrets Protection is available on every Edition, from Builder up.

Commands

Command What it does
act env import <path> [--force] Sequester every plaintext line of a .env into the out-of-repo store, replacing each of those lines' values with #act:sequestered in place. Comments, ordering and lines already sequestered are left as they are. --force overwrites a stored value that differs.
act env mv NAME [--restore] [--force] Sequester one existing .env key into the store, or — with --restore — write the stored value back into .env and drop it from the store. --force proceeds through a value collision.
act env add NAME [--stdin] Add or update one secret via a hidden prompt (or --stdin for pipes and scripts). The value never appears on the command line, so it can't land in shell history or the agent's context. Writes only the store; the repo .env is not touched.
act env rm NAME Remove one secret from the store. The repo .env is not touched; a #act:sequestered line for it, if any, stays where it is.
act env run -- <command> Run a command with the project's secrets injected into the child process environment. The values never enter the command string or the agent context, and the child's stdout/stderr is redacted on the way out.
act env list Print the stored key names — never the values.
act env get NAME [--reveal] Print one secret, redacted unless --reveal is given. --reveal is the explicit “I accept this value entering context” switch.