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.yamland any custom-CI deploy workflow.
Steps¶
- Review Security and Trust with the security owner.
- Review Administer Forge with the GitHub org admin.
- Install the Forge GitHub App through the CLI-provided setup link when one is shown, and use Connect GitHub for grant scope and evidence.
- Choose all-repos or selected-repos access in GitHub.
- Give developers the approved tenant, account, and project/app refs.
- Ask the first app team to configure, onboard, and deploy using Build with Forge.
- Require review of
mithran.yamlexposure and any custom-CI deploy workflow changes before merge. - 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 --jsonoutput.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_idand served app ref. - Intended
public_edge.exposure. - Confirmation that the repo has a Dockerfile and known serving probe behavior.
Steps¶
- Confirm the repo is granted to the Forge GitHub App. If it is not, update the GitHub App grant first.
- Confirm the app exposure choice using App access and sharing.
- Ask the developer to run
map onboard --installation-ref <installation-ref> <owner/repo> --repo-dir .. - 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. - If the repo uses custom CI, review
.github/workflows/map-deploy.yml. - Commit
mithran.yamlthrough the repo's normal review process. Commit the workflow only when the repo uses custom CI. - 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.yamldiff..github/workflows/map-deploy.ymldiff, when custom CI is involved.map doctor --app <owner/repo>output.- Any
map onboarderror 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¶
- Open the GitHub App installation page for the App shown by the customer setup link.
- Add or remove the selected repo, or switch between all-repos and selected-repos access.
- Save the GitHub App configuration.
- For added repos, ask the developer to run
map onboard. - For repos that lose GitHub App access and use custom CI, disable or remove
.github/workflows/map-deploy.ymlwhen CI must stop requesting deploys. - 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 --jsonoutput.- 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¶
- Identify the failed stage in the Forge deploy status or control-plane response.
- Use Deploy status and evidence to read the
status fields and collect
map --json evidence <deployment-ref>output when available. - Use Troubleshooting for common source fetch, webhook, custom-CI auth, route, and runtime-readiness errors.
- Review
map doctor --app <owner/repo>for blocking diagnostics. - Confirm the repo is granted to the Forge GitHub App.
- Confirm
mithran.yamlhas the expectedmetadata.app_id, app ref,public_edge.exposure, runtime command, and serving probe behavior. For self-service apps, confirm the app ref andmetadata.app_idare aligned. - Retry only after the failing input has changed or a transient GitHub/source fetch condition has cleared.
- 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.yamlat 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¶
- 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. - Confirm the deployment reached a publishable state:
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:
If the operator is working from a deployment ref instead of a version label, publish directly:
- Run
map versions <app>again and confirm thepublishedpointer now references the intended deployment ref. - Open or curl the clean public hostname returned by
map publishor shown in thepublishedline. - 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¶
- Run
map versions <app>and confirm the production alias points at the expected deployment. Copy that current deployment ref. - Confirm the current and canary deployments reached a canary-eligible state:
Both deploy phases must be Succeeded or Promoted.
3. Confirm the release review evidence for the canary deployment.
4. Start the canary:
- 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. Usemap --json canary start ...when the release record must retain the exact alias object. Treat the returned alias andmap versions <app>as the source of truth for the app and app environment. - Run
map versions <app>and confirm the production alias shows the canary deployment ref and weight. - 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. - To promote the canary, run:
- To roll back the canary, run:
- After promote or rollback, confirm the command reports the split cleared.
Use
map --json canary promote ...ormap --json canary rollback ...when the release record needs the exact control-plane response. - Run
map versions <app>again and confirm the production alias no longer shows an active canary split. - 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
--jsonis 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¶
- Capture the repo owner/name and app hostname.
- Capture tenant, account, project, and app refs.
- Capture the GitHub App grant state for the repo.
- Capture the relevant
mithran.yamland any custom-CI deploy workflow revision. - Capture the Forge deploy status and control-plane response.
- Capture
map --json evidence <deployment-ref>output when the endpoint has evidence. - Capture the observed user-facing error, such as
unknown_hostname, access denied, health failure, or source fetch failure. - 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.yamland 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.exposurevalue. - Which supported app-route exposure value should be deployed.
- Customer reviewer for the manifest change.
Steps¶
- Review App access and sharing with the admin and developer.
- Edit
public_edge.exposureinmithran.yamlwhen route exposure must change. - Review the manifest change and
access.yamlbefore applying them. - For protected apps, run
map access plan, then runmap access applybefore the route update that should carry the policy. - Deploy the reviewed commit when the manifest or app source changed.
- Publish the reviewed version if the app uses the clean public host.
- 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.
- 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.yamldiff 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, andmap access applyoutput when the protected sharing policy changed.- Observed HTTP response or access-denied result.
- Allowed and denied access verification result, when applicable.