Skip to content

Forge architecture

Forge deploys a GitHub repo into an app route. The useful architecture model for customers is the set of controls and evidence points they can inspect: source access, onboarding, deploy trigger, deploy status, routing records, publish decision, and app access.

Use this page to answer architecture questions such as:

  • Can Forge read this repository?
  • Which event asked Forge to deploy?
  • Which reviewed source and manifest produced this running version?
  • Which version or alias is serving user traffic?
  • Which users can reach the route before traffic reaches the app process?

The controls to keep separate

Control What it decides Customer evidence
Source access Whether Forge can read a repo from GitHub. GitHub App grant for the App shown by the customer setup link and aegis github status --project-repo <owner/repo> --require --json.
Onboarding Whether the repo, installation ref, tenant/account refs, and project/app ref are recorded in Forge. map onboard output. Use map doctor --app <owner/repo> as an additional diagnostic.
Deploy trigger Which event asks Forge to deploy a ref or SHA. Built-in GitHub App webhook ref, explicit map deploy command, or optional custom-CI workflow run.
Deploy lifecycle Whether source snapshot, review, build, runtime, route, and smoke completed. map --json status <deployment-ref>, map watch <deployment-ref>, and map --json evidence <deployment-ref>.
Published route Which reviewed version the clean public URL serves. map versions <app> and map publish <app> --version <label> --expected-sha <sha>.
App access Which app-route exposure value is reviewed, and which signed-in users can reach a protected app. Reviewed mithran.yaml, reviewed access.yaml, map access plan, map access apply, and allowed/denied browser or API checks.

Do not use one control as proof of another. A repo can be granted but not onboarded. A deploy can succeed without moving the clean public URL. Removing source access does not retire an already served route.

Authority flow

Forge has two separate authority paths:

Path What authorizes it What it can do
Source fetch GitHub App installation grant plus Forge onboarding record. Read the granted repo to snapshot the requested ref or SHA.
Deploy request Built-in GitHub App webhook, direct map deploy, or optional custom-CI request. Ask Forge to run the deploy lifecycle for an onboarded repo.

The built-in webhook path does not require a repo workflow or a stored deploy secret. GitHub sends Forge a webhook for a pushed ref; Forge accepts it only when the repo is granted to the Forge GitHub App, the repo is onboarded, and the ref is one of the built-in deploy refs.

The optional custom-CI path is a dispatcher. The workflow requests GitHub Actions OIDC, exchanges it with Mithran auth, and posts a deploy request to the same control-plane lifecycle. Use that path only when the customer wants CI to decide when to request deploys.

Customer-facing components

flowchart LR
  Dev[Developer] --> Repo[GitHub repo]
  Admin[GitHub or account admin] --> AppGrant[Forge GitHub App grant]
  Dev --> CLI[aegis and map CLI]
  Repo --> Webhook[GitHub App webhook]
  AppGrant --> Source[Source fetch]
  CLI --> CP[Forge control plane]
  Webhook --> CP
  CP --> Source
  CP --> Review[Review]
  Review --> Build[Build]
  Build --> Runtime[Runtime]
  Runtime --> Routes[Routing records]
  Routes --> Edge[Forge edge]
  Auth[Forge auth] --> Edge
  User[Browser or API client] --> Edge
  Edge --> App[App process]

Customers own the repo contents, manifest, Git refs, GitHub App grant choice, onboarding inputs, access policy, and publish decision. Forge owns source fetch through the granted GitHub App, deploy intake, review, build execution, runtime placement, route programming, edge authentication, and deploy evidence.

Deploy flow

sequenceDiagram
  participant Trigger as Webhook, map deploy, or custom CI
  participant CP as Forge control plane
  participant GH as Forge GitHub App
  participant Review as Review
  participant Build as Build
  participant Runtime as Runtime
  participant Route as Route
  participant Smoke as Smoke

  Trigger->>CP: deploy request for repo plus ref or SHA
  CP->>CP: verify repo onboarding and source authority
  CP->>GH: fetch granted source
  GH-->>CP: source snapshot
  CP->>Review: review source snapshot and mithran.yaml
  Review-->>CP: passed, warned, blocked, or failed
  CP->>Build: build image
  Build-->>CP: build result and evidence refs
  CP->>Runtime: start runtime
  Runtime-->>CP: runtime status and serving target
  CP->>Route: program internal version and app-environment routing records
  CP->>Smoke: check route
  Smoke-->>CP: succeeded or failed

The default trigger is a GitHub App webhook for built-in deploy refs. By default, refs/heads/main targets the preview app environment, and refs/heads/release/* or refs/tags/release/* targets the production app environment. Manifest app_env entries can declare reviewed auto_deploy_refs for app-env resolution on those webhook auto-deploy candidates.

map deploy posts directly to /v1/map-control/deploy/request. It does not dispatch GitHub Actions. The optional map-deploy.yml workflow is only for teams that want GitHub Actions or another custom CI system to request deploys; it enters the same control-plane lifecycle after the workflow posts the deploy request.

Deploy status and evidence

Start every deploy investigation with the deployment ref:

map --json status <deployment-ref>
map --json evidence <deployment-ref>

map --json status reads the saved deploy record. The status view is under deployment.status, and the deploy phase is deployment.status.status.

Area Fields or evidence to inspect What it proves
Identity deployment_ref, tenant_ref, account_ref, app_ref, platform_env, app_env The deploy belongs to the expected account, app, account context, and app environment.
Source snapshot source_snapshot_ref and deploy evidence Forge resolved source for the requested repo and ref or SHA.
Review review_status, review_gate, review_ref, manifest_digest, failure_reason The committed app contract was accepted, warned, blocked, or failed before build.
Build build_status, build_logs_ref, build_failure_ref, build_provenance_ref, build_sbom_ref, artifact_digest The source produced an artifact, or build evidence explains why it did not.
Runtime runtime_status, runtime_failure The artifact started and became healthy, or runtime evidence explains why it did not.
Route route_status, route_target_ref, github_check_ref, github_deployment_id Forge programmed the route target and recorded GitHub-facing status refs when available.
Completion status, completed_at The deploy is still running, succeeded, or ended at a terminal failure state.

Use map watch <deployment-ref> when you need to poll until a terminal state. Use map --json evidence <deployment-ref> when the status fields name an evidence ref or do not explain the failure clearly enough.

Deployment phase values include:

Phase family Status values
Intake and source IntentReceived, SourceResolving, SourceSnapshotted
Review ReviewPending, ReviewWarned, ReviewBlocked
Build BuildPending, BuildSucceeded, BuildFailed
Runtime RuntimePending, RuntimeReady, RuntimeFailed
Route and release actions RoutePending, RouteReady, RouteFailed, Promoted, RolledBack, Superseded
Terminal success or generic failure Succeeded, Failed

Phase-specific failure values such as ReviewBlocked, BuildFailed, RuntimeFailed, and RouteFailed are terminal for that deploy attempt.

Routing records

Deploy and publish are separate operations.

Record Moved by What it means
Internal version Successful deploy. A versioned route for inspecting a specific deploy.
App-environment alias Deploy lifecycle or route action. The current target for an app environment such as preview or production.
Canary split map canary start, map canary promote, and map canary rollback. A weighted split on the target app-environment alias. Start records a canary deployment and weight; promote or rollback clears the split.
Published clean URL map publish. The clean public URL users open. It stays pinned until another publish.

map versions <app> reads /v1/map-control/routes/status and separates those records into internal versions, aliases, and the published clean URL.

Publishing does not build or redeploy source. map publish pins the clean public URL to a reviewed deployment that reached Succeeded or Promoted. Use --expected-sha when a human reviewed a specific commit; the control plane rejects the publish if the selected deployment records a different source SHA.

Canary does not move the published clean URL. map canary start changes the target app-environment alias by sending a 1 through 99 percent slice to a canary deployment that reached Succeeded or Promoted. The control plane resolves the alias from the canary deployment's app environment. Use map versions <app> to inspect the active split; when a canary is active, the alias shows the canary deployment ref and weight. Keep the map --json canary ... response with the release evidence as the action receipt. After promote or rollback, map versions <app> should no longer show an active canary split. Use Canary releases for the operator workflow.

Request and access path

sequenceDiagram
  participant Client as Browser or API client
  participant Edge as Forge edge
  participant Auth as Forge auth
  participant App as App process

  Client->>Edge: HTTPS request for app hostname
  Edge->>Edge: resolve published, alias, or version routing record
  Edge->>Auth: require session when route is auth-required
  Auth-->>Edge: allowed or denied
  Edge->>Edge: apply protected sharing policy when present
  Edge->>App: forward allowed request
  App-->>Client: app response

protected, none, public-redirect, and an omitted exposure keep Forge auth required before the request reaches the app runtime. public serves the app route without platform auth.

For auth-required routes, the edge applies the route's protected sharing policy. When no protected sharing policy is attached, the route admits signed-in users. When allowed_domains or share is set, the route admits only matching verified email domains, email addresses, or account: principals.

map access plan resolves access.yaml locally. map access apply sends the reviewed policy to Forge. The next route update or route reconcile carries the current protected sharing policy to the served route.

Responsibility boundaries

Area Customer owns Forge owns
Source Repo contents, Dockerfile, mithran.yaml, branch and tag policy. Source fetch through the granted GitHub App installation.
Deploy authority GitHub App grant, onboarding inputs, explicit deploy requests, and optional custom-CI workflow configuration. Webhook validation, deploy-request authorization, and deploy-intake checks.
App contract HTTP route, startup command, serving probe behavior, non-secret config, and exposure intent. Manifest review and secret-shaped-value rejection before build.
Runtime behavior App process, $PORT binding, serving probe response, and app-level authorization. Runtime placement, readiness observation, and runtime status.
Traffic Publish decision and protected sharing policy. Routing record updates, clean public URL pinning, Forge auth gate, and protected sharing enforcement.

Operator checklist

When a developer or admin asks "what is running?", collect these facts in order:

  1. Repo and commit SHA.
  2. Account context and app environment.
  3. deployment_ref from deploy output, map versions <app>, or deploy status.
  4. map --json status <deployment-ref> for phase and identity fields.
  5. map --json evidence <deployment-ref> when the status names evidence refs or the phase does not explain the result.
  6. map versions <app> to identify internal versions, app-environment aliases, the published clean URL, and any active canary split.
  7. map --json canary ... output as the action receipt when a canary start, promote, or rollback is part of the release or incident.
  8. mithran.yaml and access.yaml at the reviewed commit when exposure or sharing is part of the question.

Where to go next