Projects

Environment and variables

Define global and per-project variables, reference them from WORKFLOW.md, and control exactly what reaches an agent's sandbox.

SI Fabrik keeps two layers of environment variables: a global one for every project on the host, and a per-project one. $NAME references in WORKFLOW.md and hooks see both, with the project's value winning. Sandboxes see only the names you list.

Where to set them#

LayerMac appharnessd
GlobalSettings → Environment (Keychain)secrets_file (secrets.env, mode 0600), plus variables an admin sets from the app
Per projectEdit Project → Environment (Keychain, one item per project)projects[].secrets_file (mode 0600, checked by harnessd check), plus variables set from the app
Why not your shell?

GUI apps don't inherit your shell's environment, so a token you exported in ~/.zshrc isn't visible to SI Fabrik. Define tracker keys such as CLICKUP_API_TOKEN in Settings → Environment.

Add a variable#

  1. Global

    Open Settings → Environment, press +, and enter a Name and Value. Values are stored in your login Keychain.

  2. Per project

    Open the project's … menu → Edit Project…. Under Environment, press Add Variable. A name that also exists globally shows overrides global.

  3. Reference it
    WORKFLOW.md
    tracker:
      kind: clickup
      provider:
        api_token: $CLICKUP_API_TOKEN
    workspace:
      root: ${WORKSPACES}/storefront
    docker:
      env: [SENTRY_DSN, FEATURE_FLAGS_KEY]   # passed into the sandbox by name

Rules#

  • Precedence: a project's value wins over the global one with the same name.
  • Where they're used: $NAME and ${NAME} in WORKFLOW.md are resolved on the host. Hooks get the merged environment.
  • What reaches a sandbox: only the names in docker.env, passed by name (-e NAME) so values never appear on a command line. Push tokens and model credentials are never passed; the model credential is added by SI Fabrik's relay instead.
  • Tracker credentials are resolved on the host and stripped from agent processes.

Credential names#

Some names are credentials. In a project's environment they replace the global credential for that project only:

NameUsed as
ANTHROPIC_API_KEYAnthropic API key for Claude Code
CLAUDE_CODE_OAUTH_TOKENToken from claude setup-token
OPENAI_API_KEYOpenAI key for Codex
HARNESS_GATEWAY_API_KEY, LITELLM_API_KEYGateway key

These names never enter hook or agent environments, and never take part in $VAR expansion. The runners inject credentials explicitly, and Cloudflare sandboxes only ever see a placeholder. A project that sets one kind of Claude credential (ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN) uses only that kind.

Per-project budgets

Give each project its own LiteLLM virtual key in Edit Project → Environment as LITELLM_API_KEY. LiteLLM then enforces a budget per project.

Reserved host-only names, stripped from every agent and hook environment: HARNESS_GITHUB_TOKEN, HARNESS_GITLAB_TOKEN, HARNESS_CLOUDFLARE_TOKEN.

Check where values come from#

The Workflow tab's inspector has a Variables panel. It lists every variable the workflow references (including docker.env names) and its source: project, global, SI Fabrik process, or not set.

See also#