How ForgeAI keeps your code, AI tokens, and conversations secure: local execution, encryption at rest, token storage, and organization isolation.
ForgeAI is split into two halves with a deliberate security boundary between them: the forge CLI runs on your machine and does the work, while the cockpit coordinates and visualizes it. This page explains what stays local, what reaches the cloud, and how both sides protect your data.
AI agents never run in the cloud. The CLI spawns your agent engine — Claude Code, Codex, OpenCode, or Kilo — inside local Docker containers on your machine. Your repository is cloned locally — into ~/.forgeai/repos/ for branch operations and into a per-session workspace mounted into each agent container. The cockpit has no execution environment and no copy of your repository.
Git credentials follow the same rule: for HTTPS clones inside containers, the CLI reads credentials from your machine's own git credential helper and injects them locally. SSH URLs pass through unchanged. Repository credentials are never sent to the cloud.
Agents run with your own AI subscription or API key. Each engine's credentials are captured once and stored the same way:
forge auth setup-claude captures a long-lived Claude Code OAuth token (macOS Keychain service ForgeAI-claude-oauth, or AES-256-GCM-encrypted at ~/.forgeai/auth/claude-oauth.json on other platforms)forge auth setup-codex stores an imported codex login credential or an OpenAI API key (Keychain service ForgeAI-codex-auth, or encrypted at ~/.forgeai/auth/codex-auth.json)forge auth setup-opencode stores an imported opencode auth login credential or a provider API key (Keychain service ForgeAI-opencode-auth, or encrypted at ~/.forgeai/auth/opencode-auth.json)forge auth setup-kilo stores an imported kilo auth login credential or a Kilo gateway API key (Keychain service ForgeAI-kilo-auth, or encrypted at ~/.forgeai/auth/kilo-auth.json)Credentials are configured inside agent containers locally, at spawn time: as name-only environment variables (their values never appear in the process table), or written into the container's own filesystem — never onto the host-mounted session volume. They are never transmitted to the cockpit, and session snapshots uploaded for resume explicitly exclude credential files. This is also why ForgeAI has zero variable AI cost: the platform never proxies your AI traffic. See Authenticating the CLI.
A note on agent sandboxes: the Docker container is the isolation boundary, so the engines' own interactive guardrails are disabled inside it (Claude Code runs with --dangerously-skip-permissions, Codex with its sandbox set to full access, OpenCode and Kilo with permissions set to allow). The container has no access to your machine beyond its session workspace.
The cockpit stores coordination data, not your codebase:
| Data | Stored in the cloud? |
|---|---|
| Repository contents | No — cloned and modified only on your machine |
| AI provider tokens | No — Keychain or encrypted local file |
| Git credentials | No — read from your local credential helper |
| Task and workflow events | Yes — status changes, board updates, heartbeats |
| Conversation messages | Yes — encrypted at rest (see below) |
| Agent output streams | Relayed live to the board; conversation history is encrypted at rest |
| Workflow deliverables | Yes — the file path in your branch, plus an optional content copy so artifacts can be viewed in the cockpit |
While the CLI is offline, events are journaled locally as NDJSON under ~/.forgeai/events/ and re-synced over REST when the connection returns — see the forge journal commands in the CLI reference.
Messages exchanged in workflow chats are encrypted before they are written to the database:
ENCRYPTION_KEY) via HKDF-SHA256, with the workflow ID as derivation context. Compromising one workflow's data does not expose another's.Encrypted step session snapshots follow the same model, allowing agents to resume a session with full context. Snapshots are one-time use: they are cleared from the database as soon as they are fetched for a resume. When a workflow completes, all of its conversations and messages are permanently deleted from the database in the same transaction; artifacts — and any encrypted step session snapshot not yet consumed by a resume — remain.
The CLI authenticates via an OAuth Device Flow: forge auth login prints a code, you approve it in the cockpit at /device, and you choose which organizations to link. The resulting access token is used as a Bearer token on every REST request (Authorization header) and on the Socket.io handshake.
The token is stored AES-256-GCM-encrypted at ~/.forgeai/auth/credentials.json (file mode 0600, directory 0700). The encryption key is derived with scrypt from your machine hostname and username, so the file is deliberately not portable — copying it to another machine or user account produces an unreadable file.
Cockpit sessions — and therefore CLI tokens obtained through the device flow — last 20 days and are refreshed every 7 days of activity. If the CLI fails Socket.io authentication 3 times in a row, it exits and asks you to run forge auth login again. Changing your password at /account/change-password offers a "Sign out from other devices" option, enabled by default.
You can revoke a CLI's access from either side:
| Action | Where | Effect |
|---|---|---|
forge auth logout | CLI | Stops the daemon, deletes the encrypted token file, clears session config |
forge cli unlink <cliId> | CLI | Unregisters a device from your default organization |
forge org unlink <slug> | CLI | Disconnects and deletes the device registration for one organization |
| Force disconnect | Settings → CLI Devices | Closes the device's Socket.io connection, clears its presence, and releases its incomplete tasks for re-dispatch |
| Unlink | Settings → CLI Devices | Everything force disconnect does, plus permanent deletion of the device record |
In the cockpit, only the device's owner or an organization admin can disconnect or unlink a device. Every member can view the device list at /orgs/<slug>/settings/cli-devices.
ForgeAI is multi-tenant, and every access path enforces membership in the target organization:
X-Org-Id header; the server verifies that the token's user is a member of that organization before running the handler./org:{orgId}); the namespace middleware validates membership before the connection is accepted, and handlers use the server-side identity — never client-supplied IDs.Within an organization, roles and permissions (member, admin, owner, plus custom roles) control who can manage projects, workflows, agents, and billing.
The browser and the CLI both talk to the cockpit over a single origin:
forge auth login --server https://forgeai-production-382c.up.railway.app. All traffic — REST and WebSocket — then runs over HTTPS/WSS.Production deployments run behind a WebSocket-capable HTTPS proxy; there is no unauthenticated data endpoint beyond the /api/health liveness probe, which returns only a status flag.
forge auth logout before decommissioning or handing over a machine; also unlink the device from Settings → CLI Devices.forge cli list or in the cockpit, and unlink devices you no longer recognize.repo scope (GitHub has no read-only scope for private repositories) along with user:email and read:org; the cockpit uses it to list repositories and branches when creating projects.If something looks wrong — an unknown device, a session that will not disconnect — see Troubleshooting & FAQ.