0014. Releases register prod slash commands
- Status: accepted
- Date: 2026-10-14
Context
ADR 0012 kept registration a laptop command, and ADR 0013 kept it there: after a release that changes commands, a maintainer still ran just register prod with a .env.prod. Forgetting that step leaves Discord showing the old command list against the new code. The GitHub identity pixel-github-prod was Contributor on pixel-prod, which cannot read Key Vault secrets, so CD had no token to register with.
Decision
- A
register-prodjob in.github/workflows/release.ymlruns afterprod-cdrollspixel-prod, in GitHub Environmentprod. It readsDISCORD_APP_ID,DISCORD_GUILD_ID,PIXEL_ENVand thediscord-tokenKey Vault reference from the running Container App, so it can only register the bot that was just rolled, and refuses unlessPIXEL_ENV=prod. It fetches the token, masks it, and runsjust register-ci prod. just register-ciruns only in GitHub Actions. It builds the command list fromconfig/*.example.yamland a throwaway data dir: the commands don't depend on who is in the access lists, so CI never needs the real lists.- Least privilege:
pixel-github-prodgets Key Vault Secrets User on thediscord-tokensecret only (github_register_principal_idininfra/envs/prod, off when null). It still cannot readadmins-yaml, the Home Assistant token or any other secret, so the prod Terraform plan still runs with-refresh=false. just register prodwith.env.prodstays as the fallback and for rollbacks.
This supersedes the registration clauses of ADR 0012 and ADR 0013. Everything else in them stands.
Consequences
- A maintainer applies
infra/envs/prodonce withgithub_register_principal_idset (az identity show -g pixel-bootstrap -n pixel-github-prod --query principalId -o tsv). Until then the job fails closed with that instruction; prod is already rolled, and Re-run failed jobs works after the apply. - The job uses Environment
prod(its OIDC subject isenvironment:prod), so a reviewer approves it as a second step afterprod-cd. - The prod bot token is readable by a workflow job on
mainafter approval, not only by the app. A compromised workflow could act as the bot in the guild, but could not change access lists, Home Assistant or Azure beyond what Contributor already allowed.