Forge

docs/ / auth.md · branch master

Forge authentication (v0.3)

North star: FORGE-ADR-0006 · FORGE-ADR-0010 · OAuth: FORGE-ADR-0011

Pilot behind VPN

FORGE_REQUIRE_AUTH=false — API и Lens без Bearer. Git — SSH keys only.

Configure GitHub OAuth on the server:

FORGE_GITHUB_CLIENT_ID=…
FORGE_GITHUB_CLIENT_SECRET=…

Then from workstation or CIDE:

forge auth login --host http://127.0.0.1:8770
# Opens browser → Sign in with GitHub → token in ~/.forge/credentials.json

Cascade IDE: forge_lens.connect tries OAuth first, falls back to device login if OAuth is not configured.

Device login (fallback / bootstrap)

forge auth login --device --host http://127.0.0.1:8770
# Terminal 2 — one-time bootstrap on server
FORGE_BOOTSTRAP_TOKEN=… forge auth approve ABCD-EFGH --host http://127.0.0.1:8770

Credentials land in ~/.forge/credentials.json. AgentForge.Mcp reads them automatically when FORGE_API_TOKEN is unset.

Commands

Command Purpose
forge auth login OAuth if configured, else device flow
forge auth login --oauth github Force OAuth
forge auth login --device Force device flow
forge auth approve <code> Approve pending CLI (bootstrap)
forge auth status Show saved login for host
forge auth logout Remove host entry
forge auth token Print token (scripts only)

Overrides

Variable When
FORGE_BASE_URL Default host for CLI / MCP
FORGE_API_TOKEN Wins over credential file (CI/debug)
FORGE_BOOTSTRAP_TOKEN Approve device / create first API token

Bootstrap (server setup)

curl -X POST http://127.0.0.1:8770/api/v1/admin/tokens \
  -H "Authorization: Bearer $FORGE_BOOTSTRAP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"ops","scopes":"read,write,accept_merge"}'

Prefer forge auth login for workstations instead of copying fg_… into MCP env.

Org catalog admin (no PAT): after login, users with org_members.role = admin (alias owner) and write scope can create repo groups, org-scoped repos, and add members via MCP/API. Bootstrap still required for org create, bulk import, and /admin/*. See FORGE-ADR-0034.

Public AMS (internet-facing showcase)

When the host is reachable by public IP (FORGE_REQUIRE_AUTH=true), treat it as partially open: public repos and /view are intentional; everything else must be locked down.

Required .env on VPS

Variable Value Why
FORGE_REQUIRE_AUTH true Bearer on MCP invoke and most write API
FORGE_OAUTH_SIGNIN_POLICY invite_only (showcase default) OAuth only for identities already in FORGE_DEFAULT_ORG_SLUG members (import or admin add)
FORGE_ORG_AUTO_MEMBER_ON_LOGIN false Do not auto-add every GitHub login to the org
FORGE_GIT_HOOK_SECRET random 32+ bytes (openssl rand -hex 32) Blocks anonymous POST /api/v1/git/push
FORGE_REQUIRE_GIT_HOOK_SECRET true Explicit; also implied when FORGE_REQUIRE_AUTH=true
FORGE_BOOTSTRAP_TOKEN strong secret, server-only Import, device approve, admin
FORGE_GITHUB_CLIENT_ID/SECRET OAuth app Human sign-in
FORGE_GITHUB_IMPORT_TOKEN PAT with org repo scope Private org import

scripts/deploy-vps-lean.ps1 -Showcase sets auth flags, FORGE_OAUTH_SIGNIN_POLICY=invite_only, FORGE_ORG_AUTO_MEMBER_ON_LOGIN=false, and generates FORGE_GIT_HOOK_SECRET if missing (does not overwrite an existing value).

OAuth sign-in policy (instance-user-management plugin)

FORGE_OAUTH_SIGNIN_POLICY Behavior
open Any GitHub user may sign in (local dev default when FORGE_REQUIRE_AUTH=false)
invite_only Identity must already be org member of FORGE_DEFAULT_ORG_SLUG (seed via org-import-github or org-user-management)
github_org Live GitHub org check — set FORGE_OAUTH_GITHUB_ORG=AI-Guiders (requests read:org scope)

Org member CRUD: org-user-management plugin (POST/GET/PATCH/DELETE /api/v1/orgs/{slug}/members).

Instance admin (instance-user-management plugin)

Role Scope Typical powers
Instance admin whole forge host create orgs, bulk import, /admin/*, manage instance admins; catalog ops in any org
Org admin one org repo groups, org members, org-scoped repos
Org member one org read/write repos per token scopes

Bootstrap (FORGE_BOOTSTRAP_TOKEN) — break-glass / deploy only. Day-to-day host ops → promote instance admins via POST /api/v1/instance/admins (bootstrap or existing instance admin). Instance admins bypass invite_only OAuth gate.

Post-deploy smoke (no token)

curl -sf http://HOST:8770/health          # 200
curl -sf http://HOST:8770/view/orgs/ai-guiders  # 200
curl -s -o /dev/null -w '%{http_code}\n' -X POST http://HOST:8770/api/v1/git/push \
  -H 'Content-Type: application/json' -d '{"repo":"x","commit":"0","branch":"main"}'  # 401 or 503, not 200
curl -s -o /dev/null -w '%{http_code}\n' http://HOST:8770/api/v1/admin/plugins/status  # 401 when auth on
curl -s -o /dev/null -w '%{http_code}\n' -X POST http://HOST:8770/api/v1/mcp/invoke  # 401

Still public by design

  • /view/orgs/{slug} — public repo catalog
  • /api/v1/orgs — org slugs and repo counts (private repo names hidden)
  • /api/v1/capabilities — MCP tool catalog (invoke still needs token)
  • TLS reverse proxy (Caddy/nginx) in front of :8770
  • Firewall: expose 2222 (git-ssh) only if needed; never without FORGE_GIT_AUTHORIZED_KEYS
  • Rotate FORGE_BOOTSTRAP_TOKEN after initial setup; keep off workstations

See also git-transport.md and FORGE-ADR-0024.

View only · write via MCP/CIDE