Skip to content

Admin operations runbooks

Use these runbooks when you operate Forge adoption for a customer account, GitHub organization, or tenant. They use only customer-visible GitHub settings, the aegis and map CLIs, Forge deploy status, GitHub Actions logs for custom-CI deploys, and the public docs.

Responsibility split

Role Owns
Customer admin GitHub App installation, repository grant decisions, tenant/account/project/app refs, change approval, and evidence packet collection.
Developer App manifest, Dockerfile, serving probe behavior, onboarding command, release trigger, and first-pass deploy troubleshooting.

For support-owned request formats, see Support and escalation.

Team rollout

Inputs

  • Target GitHub account or organization.
  • First repo or pilot repo list.
  • Tenant, account, and project/app refs for developers.
  • Admin decision on all-repos or selected-repos GitHub App access.
  • Review owner for mithran.yaml and any custom-CI deploy workflow.

Steps

  1. Review Security and Trust with the security owner.
  2. Review Administer Forge with the GitHub org admin.
  3. Install the Forge GitHub App through the CLI-provided setup link when one is shown, and use Connect GitHub for grant scope and evidence.
  4. Choose all-repos or selected-repos access in GitHub.
  5. Give developers the approved tenant, account, and project/app refs.
  6. Ask the first app team to configure, onboard, and deploy using Build with Forge.
  7. Require review of mithran.yaml exposure and any custom-CI deploy workflow changes before merge.
  8. Capture the first successful deploy status and app hostname as rollout evidence.

Expected result

The pilot repo is granted to the Forge GitHub App, onboarded in Forge, and able to deploy through the agreed webhook or custom-CI path.

Evidence to collect

  • GitHub account or organization name.
  • GitHub App installation status and grant choice.
  • Repo list selected for the pilot.
  • aegis doctor --json output.
  • map doctor --app <owner/repo> output for the pilot repo from the saved Forge endpoint.
  • First successful or failed deploy status. Include the GitHub Actions run URL when custom CI is involved.

Repo onboarding governance

Inputs

  • Repo owner/name.
  • GitHub App installation ref.
  • Tenant, account, and project/app refs.
  • Intended metadata.app_id and served app ref.
  • Intended public_edge.exposure.
  • Confirmation that the repo has a Dockerfile and known serving probe behavior.

Steps

  1. Confirm the repo is granted to the Forge GitHub App. If it is not, update the GitHub App grant first.
  2. Confirm the app exposure choice using App access and sharing.
  3. Ask the developer to run map onboard --installation-ref <installation-ref> <owner/repo> --repo-dir ..
  4. Review the committed mithran.yaml. If onboarding wrote the starter file, confirm the app ID, project/app ref, runtime, startup command, route, exposure, and app-environment policy before release deploys.
  5. If the repo uses custom CI, review .github/workflows/map-deploy.yml.
  6. Commit mithran.yaml through the repo's normal review process. Commit the workflow only when the repo uses custom CI.
  7. Run map doctor --app <owner/repo>.

Expected result

The repo has a reviewed app manifest and Forge onboarding evidence tied to the GitHub App grant. Custom-CI repos also have a reviewed deploy workflow.

Evidence to collect

  • Repo owner/name and GitHub App grant state.
  • Tenant, account, and project/app refs used for onboarding.
  • mithran.yaml diff.
  • .github/workflows/map-deploy.yml diff, when custom CI is involved.
  • map doctor --app <owner/repo> output.
  • Any map onboard error text.

Manifest review checklist

Use this checklist before approving the first deployable manifest for a repo:

Field or file What to check
metadata.app_id and served app ref For self-service apps, keep them aligned. The served app ref determines the hostname label.
identity.project_ref Matches the project/app ref agreed during onboarding.
capabilities[].kind Uses a supported capability kind. The self-service path documents HTTP apps.
capabilities[].startup.command Starts the long-running app process inside the built image.
App process contract The process listens on $PORT; Forge can receive HTTP 200 at the serving probe path Forge checks.
non_secret_env Contains only plain configuration; no tokens, private keys, or customer credentials.
public_edge.exposure Matches the reviewed access intent. public serves anonymously; all other values keep platform auth required.
app_env Defines the intended app environments with reviewed branch_pattern, auto_deploy_refs, image_tag, overrides, replicas, and review policy.

Custom-CI workflow review checklist

Use this only when the repo opted into --with-ci-workflow.

Workflow area What to check
Trigger policy The generated workflow triggers on release/** branches, tags matching v[0-9]+.[0-9]+.[0-9]+, and manual dispatch. Push triggers target the production app environment; manual dispatch uses the env input.
Permissions The workflow has id-token: write for GitHub OIDC.
Secrets The workflow does not use a stored Forge deploy secret.
Required repo Variables MAP_INSTALLATION_REF, MAP_APP_REF, MAP_CONTROL_ENDPOINT, and MAP_AUTH_ENDPOINT are set. Onboarding can set the installation ref and resolved project/app ref when GitHub API access is available; set the endpoint values from the account setup values.
Optional repo Variables MAP_TENANT_REF and MAP_ACCOUNT_REF are set when the account uses those refs. Set MAP_OIDC_AUDIENCE only when the account setup requires a non-default audience; otherwise the workflow uses map-control.
Manual dispatch The workflow_dispatch env input is treated as the app environment. It does not change the customer account context.
Evidence Keep the workflow revision and Actions run URL for custom-CI deploy failures.

GitHub App grant change

Inputs

  • GitHub account or organization.
  • Current grant choice: all repositories or selected repositories.
  • Repo list to add or remove.
  • Reason for the grant change.

Steps

  1. Open the GitHub App installation page for the App shown by the customer setup link.
  2. Add or remove the selected repo, or switch between all-repos and selected-repos access.
  3. Save the GitHub App configuration.
  4. For added repos, ask the developer to run map onboard.
  5. For repos that lose GitHub App access and use custom CI, disable or remove .github/workflows/map-deploy.yml when CI must stop requesting deploys.
  6. If an existing app route must stop serving users, use App access and sharing to choose the customer-owned changes for source access, custom CI, manifest exposure, and protected sharing, then follow Support and escalation for route retirement.

Expected result

Forge source fetches succeed only for repos granted to the GitHub App, and repos without a GitHub App grant cannot fetch source for new deploy work.

Evidence to collect

  • GitHub App installation owner.
  • Before/after grant choice and repo list.
  • Affected repo owner/name.
  • aegis github status --project-repo <owner/repo> --require --json output.
  • Deploy status or evidence showing the source-fetch or deploy-auth failure if the grant change was part of an incident response.

Deploy failure investigation

Inputs

  • Repo owner/name.
  • Main ref, release branch, release tag, or explicit deploy request ref.
  • Forge deploy status. Include the GitHub Actions run URL when custom CI is involved.
  • App hostname.
  • App ref.
  • Expected exposure value.

Steps

  1. Identify the failed stage in the Forge deploy status or control-plane response.
  2. Use Deploy status and evidence to read the status fields and collect map --json evidence <deployment-ref> output when available.
  3. Use Troubleshooting for common source fetch, webhook, custom-CI auth, route, and runtime-readiness errors.
  4. Review map doctor --app <owner/repo> for blocking diagnostics.
  5. Confirm the repo is granted to the Forge GitHub App.
  6. Confirm mithran.yaml has the expected metadata.app_id, app ref, public_edge.exposure, runtime command, and serving probe behavior. For self-service apps, confirm the app ref and metadata.app_id are aligned.
  7. Retry only after the failing input has changed or a transient GitHub/source fetch condition has cleared.
  8. If the same stage still fails, assemble the evidence packet.

Triage by failed stage

Failed area First evidence Common owner of the fix
Webhook trigger Pushed ref, GitHub App grant state, and map doctor --app <owner/repo>. GitHub org admin or developer.
Source fetch Deploy status, installation ref, repo grant, onboarding command. GitHub org admin or account admin.
Review review_gate, review_ref, failure_reason, and map --json evidence <deployment-ref>. Developer or manifest reviewer.
Build build_status, build_failure_ref, build_logs_ref, Dockerfile, and lockfiles. Developer.
Runtime runtime_status, runtime_failure, startup command, $PORT, deploy evidence when available, and serving probe behavior. Developer.
Route or smoke route_status, route_target_ref, app ref, app hostname, map versions <app>, and map --json evidence <deployment-ref> when the endpoint has evidence. Developer or operator.
Published version map versions <app>, publish command output, and reviewed source SHA. Operator.

Expected result

The admin can classify the failure as source access, deploy auth, build, route, runtime readiness, or app access, then assemble the matching packet in Support and escalation.

Evidence to collect

  • Forge deploy status and control-plane response.
  • Deploy evidence from map --json evidence <deployment-ref> when the endpoint has evidence.
  • GitHub Actions run URL and raw log, when custom CI is involved.
  • Control-plane response from the failed run.
  • Commit SHA or deploy ref.
  • mithran.yaml at the failing commit.
  • map doctor --app <owner/repo> output.
  • App hostname, app ref, and observed HTTP response.
  • Recent GitHub App grant changes, if any.

Publish or restore clean public URL

Inputs

  • App name or app ref.
  • Deployment ref for the reviewed version.
  • Reviewed source commit SHA to pass as --expected-sha.
  • Current map versions <app> output.
  • Release or incident reviewer who approved moving the clean public URL.

Steps

  1. Run map versions <app> and find the internal version that points at the reviewed deployment ref. Do not use an app-environment alias as the publish target.
  2. Confirm the deployment reached a publishable state:
map --json status <deployment-ref>

The deploy phase must be Succeeded or Promoted. 3. Use the reviewed Git commit SHA as the --expected-sha guard. Do not use a branch name, tag name, or version label as the expected SHA. 4. Publish by internal version label:

map publish <app> --version <version> --expected-sha <sha>

If the operator is working from a deployment ref instead of a version label, publish directly:

map publish <app> --deployment-ref <deployment-ref> --expected-sha <sha>
  1. Run map versions <app> again and confirm the published pointer now references the intended deployment ref.
  2. Open or curl the clean public hostname returned by map publish or shown in the published line.
  3. For protected apps, verify one expected allowed result and one expected denied result.

Expected result

The app's clean public URL is pinned to the reviewed deployment ref. New deploys can still create internal versions and move app-environment aliases, but they do not move the clean public URL until another publish command changes the published clean URL.

Evidence to collect

  • map versions <app> before and after publish.
  • map --json status <deployment-ref> for the selected deployment.
  • Reviewed source SHA supplied as --expected-sha.
  • Publish command output.
  • Clean public hostname and observed HTTP result.
  • Allowed and denied verification for protected apps.

Stop and investigate

Symptom What it means Next step
version not publishable The selected deployment has not reached Succeeded or Promoted. Choose a reviewed completed deployment or investigate the deploy failure.
stale or conflict with --expected-sha Forge rejected the publish because the selected deployment did not match the supplied SHA. Re-check the version label, deployment ref, and reviewed release commit before publishing.
map versions has no matching internal version The deployment ref is not an internal version for that app. Re-check the app ref and deployment evidence, or publish by explicit deployment ref.
Clean public hostname is not the expected app hostname The app ref used for deploy or publish does not match the expected app label. Compare metadata.app_id, app ref, map versions <app>, and the publish response.
Protected access result is wrong The selected version or served route does not carry the expected exposure or sharing policy. Review mithran.yaml, access.yaml, map access apply, and the route users should reach.

For the detailed publish model, use Versions and publishing.

Canary app release

Use this runbook when an account release owner wants a production app-environment canary before promoting a deployment. Canary changes the production app-environment alias split. It does not move the clean public URL; that still requires map publish.

For the full operator workflow, use Canary releases. This runbook is the condensed production-change checklist.

map canary resolves the alias from the canary deployment's recorded app environment. For this production runbook, use a canary deployment ref whose deploy status shows app_env: production.

Inputs

  • App name or app ref.
  • Current production deployment ref.
  • Canary deployment ref.
  • Desired canary weight from 1 through 99.
  • Deploy status for both deployments.
  • Release review evidence for the canary deployment.
  • Release reviewer who approved starting, promoting, or rolling back the canary.

Steps

  1. Run map versions <app> and confirm the production alias points at the expected deployment. Copy that current deployment ref.
  2. Confirm the current and canary deployments reached a canary-eligible state:
map --json status <current-deployment-ref>
map --json status <canary-deployment-ref>

Both deploy phases must be Succeeded or Promoted. 3. Confirm the release review evidence for the canary deployment. 4. Start the canary:

map canary start <app> --deployment-ref <canary-deployment-ref> --weight 10
  1. Confirm the command reports action: canary-start, alias_app_mismatch: no, the canary deployment ref, the alias or hostname returned by Forge, and the expected split. Text mode exits non-zero if the returned alias app does not match the requested app. Use map --json canary start ... when the release record must retain the exact alias object. Treat the returned alias and map versions <app> as the source of truth for the app and app environment.
  2. Run map versions <app> and confirm the production alias shows the canary deployment ref and weight.
  3. Verify the production alias hostname returned by the command or shown by map versions <app>. Do not use the clean public URL as canary evidence unless publish has already pinned that URL to the intended version.
  4. To promote the canary, run:
map canary promote <app> --deployment-ref <canary-deployment-ref>
  1. To roll back the canary, run:
map canary rollback <app> --deployment-ref <canary-deployment-ref>
  1. After promote or rollback, confirm the command reports the split cleared. Use map --json canary promote ... or map --json canary rollback ... when the release record needs the exact control-plane response.
  2. Run map versions <app> again and confirm the production alias no longer shows an active canary split.
  3. If the clean public URL should move after a canary promote, use Publish or restore clean public URL.

Expected result

Start records a weighted production alias split. Promote makes the canary deployment the current production alias target and clears the split. Rollback clears the split and keeps the previous current production alias target at 100 percent.

Evidence to collect

  • map versions <app> before and after the canary action, including the active canary split when present.
  • Deploy status for the current and canary deployments.
  • Release review evidence for the canary deployment.
  • Canary command and output.
  • JSON canary response when --json is used.
  • Verification result for the production alias hostname.
  • Publish command output when the clean public URL is moved after promote.

Stop and investigate

Symptom What it means Next step
missing canary_deployment_ref The canary request did not name the candidate deployment. Rebuild the request from the reviewed deployment evidence.
missing weight_pct Start requires a canary weight. Add an integer weight from 1 through 99.
Weight is rejected The weight is outside the accepted 1 through 99 range. Choose a valid canary weight.
Deployment is not found The named deployment ref does not exist in the control-plane state. Re-check map versions <app> and deploy evidence.
Target is not canary-eligible The current or canary deployment has not reached Succeeded or Promoted. Wait for a completed deployment or deploy a fixed commit.
alias_app_mismatch is not no The returned alias belongs to a different app than the requested app. Stop. Keep the canary output, deployment ref, and map versions <app> output, then investigate the app ref and alias before moving traffic.
map versions does not show the canary split after start The canary action did not change the production alias, or the operator is inspecting the wrong app. Re-check the returned alias, app ref, canary command output, deployment ref, and weight.
Clean public URL did not change Canary does not move the published clean URL. Use the publish runbook after the canary promote if the clean public URL should move.

Evidence packet collection

Inputs

  • Investigation question or incident summary.
  • Affected repo, app hostname, and app ref.
  • Customer admin contact and developer contact.

Steps

  1. Capture the repo owner/name and app hostname.
  2. Capture tenant, account, project, and app refs.
  3. Capture the GitHub App grant state for the repo.
  4. Capture the relevant mithran.yaml and any custom-CI deploy workflow revision.
  5. Capture the Forge deploy status and control-plane response.
  6. Capture map --json evidence <deployment-ref> output when the endpoint has evidence.
  7. Capture the observed user-facing error, such as unknown_hostname, access denied, health failure, or source fetch failure.
  8. Include the troubleshooting steps already tried.

Expected result

The evidence packet identifies the app, route, source grant, deploy request, failing stage, and customer-observed behavior.

Evidence to collect

  • Incident summary.
  • Repo owner/name, commit SHA, and deploy ref.
  • Tenant, account, project, and app refs.
  • GitHub App grant state.
  • mithran.yaml and custom-CI workflow revision when applicable.
  • Forge deploy status and control-plane response.
  • Deploy evidence from map --json evidence <deployment-ref> when the endpoint has evidence.
  • GitHub Actions run URL, when custom CI is involved.
  • App hostname, timestamp, and HTTP response or screenshot.

App access change

Inputs

  • App hostname, app ref, and repo.
  • Current and requested public_edge.exposure value.
  • Which supported app-route exposure value should be deployed.
  • Customer reviewer for the manifest change.

Steps

  1. Review App access and sharing with the admin and developer.
  2. Edit public_edge.exposure in mithran.yaml when route exposure must change.
  3. Review the manifest change and access.yaml before applying them.
  4. For protected apps, run map access plan, then run map access apply before the route update that should carry the policy.
  5. Deploy the reviewed commit when the manifest or app source changed.
  6. Publish the reviewed version if the app uses the clean public host.
  7. Verify the app route and expected access behavior. If the served route does not reflect the reviewed protected sharing policy, update or publish the route users should reach and verify again.
  8. Keep the verification result with the access-change evidence.

Expected result

The app route reflects the reviewed exposure choice, and the admin has evidence showing which commit changed the access behavior.

Evidence to collect

  • App hostname and repo owner/name.
  • Current and requested exposure value.
  • mithran.yaml diff and commit SHA.
  • Deploy status, publish output when publishing is involved, and GitHub Actions run URL only when custom CI is involved.
  • access.yaml, map access plan, and map access apply output when the protected sharing policy changed.
  • Observed HTTP response or access-denied result.
  • Allowed and denied access verification result, when applicable.