- On the orchestrator service itself
- As GitHub Actions secrets on each target repo (read by the synced workflow files).
- On the orchestrator:
GITHUB_APP_IDandGITHUB_APP_PRIVATE_KEY - On each target repo:
AI_IMPLEMENT_APP_IDandAI_IMPLEMENT_PRIVATE_KEY
Managed Codex accounts
Configure Codex credentials through OpenAI account profiles, then select them in stage settings. An all-Codex configured project does not require a legacy Anthropic credential. Do not putOPENAI_API_KEY, CHATGPT_PLAN_ACCESS_TOKEN, or copied session data in project Extra Env. Managed runs deliver the selected credential through their protected account path; credential-bearing overrides can be refused.
- Orchestrator runtime
- Target-repo workflow secrets
Variables the AI-Implement Node service reads at startup.
- For local development, set on the orchestrator’s
.envfile. - For Fly.io deployment, set on the Fly.io app via
fly secrets set(for sensitive values) or infly.toml’s[env]block (for non-sensitive defaults).
Required
The orchestrator needs the GitHub App credentials plus at least one ticketing provider’s credentials to start.string
required
Numeric ID of the GitHub App the orchestrator uses to authenticate with GitHub and dispatch workflows. Find this on the app’s settings page under General → App ID.
string
required
RSA private key (PEM format) for the GitHub App, used to generate installation tokens. When passing this as an environment variable, newlines in the PEM file must be replaced with literal
\n characters.The private key PEM file contains real newlines. When you set it as an environment variable (e.g. with
fly secrets set), those newlines must be expressed as the two-character sequence \n. Example: "-----BEGIN RSA PRIVATE KEY-----\nMIIE...\n-----END RSA PRIVATE KEY-----".Ticketing
The orchestrator can use Linear, Jira, or both. Expand the provider(s) you use:Linear
Linear
string
required
Required when any project mapping uses
ticketingProvider: linear.Client ID of the Linear application the orchestrator authenticates as. See Create a Linear app for how to create it.string
required
Required when any project mapping uses
ticketingProvider: linear.Client secret for the same application. Both values remain visible on the application’s settings page, so you can re-copy them whenever you need to.string
default:"https://linear.app"
User-facing Linear workspace URL, used to render issue links in dispatch logs and comments.
The orchestrator acts as the application itself, not as a person. Every status change, label, and comment it makes is attributed to the app in Linear’s activity feed.
Jira
Jira
Both authentication modes need
JIRA_TOKEN and JIRA_SITE_URL. Which of the remaining two you set decides the mode.string
required
Required when any project mapping uses
ticketingProvider: jira.Either an Atlassian API token or an OAuth access token, depending on the mode you pick below.string
required
Required when any mapping uses Jira.User-facing Atlassian site URL, e.g.
https://acme.atlassian.net. Renders issue links in dispatch logs and comments, and serves as the API host in Basic auth mode.string
Selects Basic auth — the recommended mode.The Atlassian account email paired with
JIRA_TOKEN. Create the token under Security → API tokens on your Atlassian account.Calls go to JIRA_SITE_URL directly, and the token is long-lived with nothing to refresh.Leave this blank to use OAuth instead.string
Required only for OAuth mode, meaning when
JIRA_EMAIL is blank.Jira Cloud tenant ID, found at https://<your-site>.atlassian.net/_edge/tenant_info under cloudId. Routes calls through api.atlassian.com using short-lived access tokens.Not needed for Basic auth.Service
string
deprecated
Shared password for the admin UI at
/admin. Using it logs a deprecation warning on each sign-in.Still works, and remains the simplest option for local development, but it identifies nobody and cannot be revoked for one person — prefer per-user sign-in on a deployed orchestrator.The admin UI is enabled when this or any sign-in provider is configured. With neither, all /admin and /api/ routes return 503, with a response body naming the missing variable.string
default:"8080"
HTTP port the orchestrator listens on. The Fly.io internal proxy routes traffic to this port automatically, so you typically do not need to change it.
string
default:"60000"
How often the orchestrator polls for new AI-Implement issues, in milliseconds. Lower values increase ticketing-API usage; values below
10000 are not recommended.string
default:"3"
How many consecutive failed dispatches for one issue and phase are tolerated before the orchestrator parks that issue and stops picking it up. This is the setting behind an issue that silently stops being dispatched, and a parked issue stays parked until a person clears it.Set to
0 to disable the breaker, so a repeatedly failing issue is retried on every poll instead.string
default:"/data/dedup.sqlite"
Absolute path to the SQLite file used for deduplication, dispatch logging, and project-mapping storage. Defaults to
/data/dedup.sqlite in production (the Fly.io volume mount point) and ./dedup.sqlite when running locally. Change this only if you are mounting the volume at a different path.string
HMAC-SHA256 secret used to validate incoming GitHub webhook payloads. Set the same value on the GitHub App’s webhook configuration, pointed at
https://<orchestrator-host>/api/github/webhook.Leaving it unset disables every webhook-driven behavior: automatic follow-up runs when a reviewer leaves blocking feedback, the faster merge-to-Done path, and — for target repos on the current workflow generation — handling of /ai-implement PR comments. Those repos have no fallback for the comment trigger once this secret is missing, since the orchestrator’s webhook is the only thing listening for it. A poll-based path still moves merged PRs to Done without the webhook, just on a slower cadence.The webhook also needs the right event subscriptions to deliver anything; see Create a GitHub App.
Admin sign-in
Per-user sign-in through Google or Microsoft. Configure a provider’s credentials to offer it, plus the shared base URL and allowlist below. See Set up admin sign-in for the provider walkthroughs.string
Required when any sign-in provider is configured.Public base URL of this orchestrator, used to build each provider’s callback address — for example
https://your-orchestrator.fly.dev, or http://localhost:8080 locally.string
Comma-separated domains whose addresses may sign in — for example
example.com,example.org.string
Comma-separated individual addresses that may sign in. An address matching either this or the domain list is admitted.
Google
Microsoft
Microsoft
string
Application (client) ID of a Microsoft Entra app registration. Set alongside the secret and tenant below to offer Microsoft sign-in.
string
Client secret Value for the same registration — not the Secret ID, which sits beside it in the Entra portal.
string
Directory (tenant) ID of the registration, as a GUID.
MCP server
The orchestrator exposes a bundled knowledge graph to MCP clients through an OAuth-authenticated proxy at/mcp. These variables configure how clients connect to it, alongside OAUTH_REDIRECT_BASE_URL and a sign-in provider from Admin sign-in above.string
Comma-separated allowlist of non-loopback callback origins accepted at dynamic client registration, for example
https://claude.ai,https://claude.com. Set it as a secret.Loopback callbacks are accepted by default, so a local client such as Claude Code needs nothing here. Any other HTTPS origin must be listed, and arbitrary origins stay denied.Leave it unset and connecting from a browser-based client fails at registration with invalid_redirect_uri, before any sign-in screen appears. See Add the orchestrator as a project connector.string
default:"3600"
Lifetime of an MCP access token, in seconds.The server also issues refresh tokens, so a connected client refreshes silently rather than re-authenticating when the access token expires.
Knowledge graph refresh
Both variables below seed a setting on the Knowledge Graph Pipelines page on first boot only, when no stored value exists. The page’s control wins afterward, so changing the variable later has no effect.string
Seeds the Backend setting — where a refresh runs. Accepted values:
github-actions (the knowledge-graph source repo’s GitHub Actions) or fly-machines (a kept Fly machine).Leave it unset and the backend defaults to fly-machines when Fly is configured, otherwise github-actions.string
default:"false"
Seeds the Materialize setting — how a refresh turns the pushed snapshot into the served graph.
true selects the direct path; false selects rdflib.The direct path requires the knowledge-graph source repo to be built on a base that supports it; against an image that predates it, the refresh reverts safely to the graph it was already serving.Self-deploy
string
Fly deploy token scoped to the orchestrator’s own app. Leaving it unset makes self-deployment unavailable; everything else runs normally.
FLY_SESSIONS_TOKEN is a different credential, scoped to the sessions app, and cannot deploy the orchestrator.Notifications
string
default:"slack"
Notification provider to use when a dispatch succeeds or fails. Accepted values:
slack (default) or teams. Has no effect if NOTIFY_WEBHOOK_URL is not also set.string
Incoming webhook URL for the notification provider. Notifications are skipped silently if this variable is unset. For Slack, this is the URL from your Incoming Webhooks app configuration. For Teams, use the connector webhook URL.
Runner mode
string
default:"default"
Global override for runner execution mode. Accepted values:
default(per-mapping setting wins)gha(force GitHub Actions for all mappings)fly(force Fly Machines)local(force local Docker — for local development)shadow(dispatch via GitHub Actions and additionally boot a Fly Machine for the same run)
string
Required when
RUNNER_MODE=fly or any mapping uses executionMode: fly-machines.Fly.io app name that hosts the session runners.string
default:"iad"
Default Fly.io region for new session machines.
string
Required when
RUNNER_MODE=fly or any mapping uses Fly Machines.Fly API token scoped to the sessions app. Used to create and destroy Fly Machines for runs.string
default:"ghcr.io/builddownai/ai-implement-runner:latest"
Default container image for runner sessions, in both execution modes. A per-repo
.ai-implement/image.yml takes precedence.string
deprecated
Superseded by
AI_IMPLEMENT_RUNNER_IMAGE, which covers both execution modes rather than Fly Machines alone.Still read when the newer variable is unset, and ignored when both are set.string
default:"ai-implement-runner:local"
Container image to use when
RUNNER_MODE=local. Built locally via npm run build:runner:local.string
default:"http://host.docker.internal:8080"
Base URL the local Docker runner uses to call back to the orchestrator.The default works on native macOS and Windows. Use the host’s own IP on Linux, and on WSL2 use the distro’s IP instead of
host.docker.internal (that points at the Windows host, not the distro running the orchestrator).Runner callbacks
Runner callbacks
Every execution mode reports back to the orchestrator through these — Fly Machines, local Docker, and GitHub Actions alike. The GitHub Actions path receives the values as workflow inputs rather than reading its own environment, so you set them on the orchestrator whichever mode your mappings use.Leaving either unset disables the callback path entirely. The most visible symptom is a planning run that never reports completion, leaving the issue stalled mid-planning.
string
Public base URL the runner uses to call back to the orchestrator, e.g.
https://your-orchestrator.fly.dev.string
Secret used to mint and validate short-lived runner-callback tokens. Required when
RUNNER_CALLBACK_BASE_URL is set.It also protects stored API keys and ChatGPT plan records.Gap-fill trigger
Gap-fill trigger
string
Shared bearer secret for the orchestrator’s
/trigger/gap-fill endpoint, which starts a gap-fill run against an existing pull request. Leaving it unset disables the endpoint.This is a separate secret from GITHUB_WEBHOOK_SECRET and is not needed for the /ai-implement comment trigger — that path is authenticated by GITHUB_WEBHOOK_SECRET instead (on target repos still running the older, pre-sync workflow generation, it runs inside that repo’s own comment-trigger.yml workflow and needs neither secret). Set GAP_FILL_TRIGGER_SECRET only if you drive gap-fill runs from your own automation.Reaper (operational)
Reaper (operational)
Controls the reconciliation sweep that cleans up stale Fly Machine sessions.
string
default:"false"
When
true, the reaper logs what it would destroy but takes no action. Useful for verifying rules before enabling live cleanup.string
default:"10"
Number of destructions in a single sweep above which the reaper emits an alert notification (via the configured
NOTIFY_TYPE).The count resets on the next pass rather than accumulating over time. Helps catch runaway destruction bugs.Multi-tenant deploys
Multi-tenant deploys
Identifiers used when deploying multiple AI-Implement instances as separate Fly apps from a single repo. Most single-client deployments leave these unset.
string
Identifier for this orchestrator instance, recorded with each reaper action and shown in the Reaper panel, so several deployments can be told apart. Defaults to the Fly.io app name.
string
Fly.io app name for this instance. Fly sets this automatically, so you rarely need to. It tags every session machine this instance creates, and the cleanup sweep uses that tag to avoid touching another tenant’s machines — in a shared sessions app, an incorrect value can cause one instance’s cleanup to destroy another tenant’s sessions.
Claude provider forwarding (Fly Machines / local Docker only)
Claude provider forwarding (Fly Machines / local Docker only)
Legacy Claude runs read these from the orchestrator and forward them when
RUNNER_MODE is fly or local. Configured runs use their selected account profiles.For GitHub Actions runner mode, the synced workflow uses its own repo secrets directly (see the Target-repo workflow secrets tab); these runtime values are unused.string
Anthropic API key, forwarded to the runner session as the Claude auth fallback. Required when
RUNNER_MODE=fly or local and no OAuth token is configured.string
Claude Code OAuth token, forwarded to the runner session. Preferred over
ANTHROPIC_API_KEY when both are set.