Skip to content

ci: gate production deploys with a protected environment - #42

Open
willwashburn wants to merge 4 commits into
mainfrom
security/production-deploy-environment
Open

ci: gate production deploys with a protected environment#42
willwashburn wants to merge 4 commits into
mainfrom
security/production-deploy-environment

Conversation

@willwashburn

@willwashburn willwashburn commented Aug 2, 2026

Copy link
Copy Markdown
Member

Summary

  • attach the production deploy job to environment: production
  • add a human-only configuration and verification runbook
  • document why willwashburn cannot serve as the approver for agents authenticated as that identity

Required ordering

This PR must not merge until a human administrator configures the production environment with a chief-confirmed human required reviewer and the resident agentrelay-com agent independently verifies non-empty protection_rules.

CMO recommends khaliqgant (GitHub user ID 1724137) pending chief confirmation. The agent has not created or changed any repository environment setting.

Merging first would allow the first production run to auto-create an unprotected environment, manufacturing a phantom gate.

Validation

  • actionlint .github/workflows/deploy.yml — pass
  • git diff --check origin/main...HEAD — pass

No merge, production deploy, environment mutation, publishing, release, or DNS action performed.


Summary by cubic

Gate production deploys behind a protected GitHub production environment with a human-only runbook. Prevents agents from self-approving and restricts production deploys to main.

  • Migration
    • A human admin must create production with a chief-confirmed human required reviewer and enable Prevent self-review; if GitHub does not offer required reviewers on this org plan, stop and report—do not proceed.
    • Add a custom deployment branch policy limited to exactly main (do not use the branch-protection-based option).
    • The agentrelay-com agent must verify non-empty protection_rules, the required reviewer, and the single-branch policy for main before merge.
    • Do not use willwashburn as the reviewer; agents authenticate as that identity.
    • The deploy workflow now sets environment: production on deploy-production.

Written for commit 9611723. Summary will update on new commits.

Review in cubic

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@willwashburn, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 5 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8f042547-0e29-4e2c-aba2-a4228ee77aa0

📥 Commits

Reviewing files that changed from the base of the PR and between d02e9cd and 9611723.

📒 Files selected for processing (2)
  • .github/workflows/deploy.yml
  • security/production-environment-runbook.md

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Preview deployed!

Environment URL
Web https://4a80fc07-agentrelay-web.agent-workforce.workers.dev

This is a Cloudflare Workers preview version of this PR's build.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be2d161db5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +36 to +38
"wait_timer": 0,
"prevent_self_review": true,
"reviewers": [

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Disable administrator bypass for the production gate

Because the shared willwashburn identity has repository-administrator access, omitting can_admins_bypass leaves GitHub's administrator-bypass behavior enabled by default. That identity can therefore bypass a waiting deployment without the required human reviewer, and prevent_self_review does not prevent this separate admin-bypass path. Set can_admins_bypass to false, instruct UI users to disable administrator bypass, and include that value in the required read-back.

Useful? React with 👍 / 👎.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="security/production-environment-runbook.md">

<violation number="1" location="security/production-environment-runbook.md:37">
P1: The runbook's API example and UI steps don't disable administrator bypass. According to GitHub's deployment protection rules documentation, administrators can bypass protection rules and force deployments by default, and this is a separate setting from prevent_self_review. Since the shared willwashburn identity has repository-administrator access, it could still bypass the required human reviewer gate unless can_admins_bypass is explicitly set to false. Add that setting to the API payload, add a UI step to disable admin bypass, and include the value in the required read-back check.</violation>
</file>

<file name=".github/workflows/deploy.yml">

<violation number="1" location=".github/workflows/deploy.yml:21">
P2: Because GitHub auto-creates the `production` environment with no protection rules on the first deployment when it doesn't already exist, the protection provided by `environment: production` silently disappears if the environment is missing or its reviewers are later removed. The repository risk here is mitigated by the human-only runbook and merge ordering, but the workflow itself never verifies that `protection_rules` is non-empty before running `wrangler deploy`. Consider adding a defense-in-depth guard step near the start of the job that queries `repos/{owner}/{repo}/environments/production` and fails the build unless a `required_reviewers` protection rule is present, so a misconfigured or auto-created phantom gate can't slip through to production.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

--input - <<'JSON'
{
"wait_timer": 0,
"prevent_self_review": true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The runbook's API example and UI steps don't disable administrator bypass. According to GitHub's deployment protection rules documentation, administrators can bypass protection rules and force deployments by default, and this is a separate setting from prevent_self_review. Since the shared willwashburn identity has repository-administrator access, it could still bypass the required human reviewer gate unless can_admins_bypass is explicitly set to false. Add that setting to the API payload, add a UI step to disable admin bypass, and include the value in the required read-back check.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At security/production-environment-runbook.md, line 37:

<comment>The runbook's API example and UI steps don't disable administrator bypass. According to GitHub's deployment protection rules documentation, administrators can bypass protection rules and force deployments by default, and this is a separate setting from prevent_self_review. Since the shared willwashburn identity has repository-administrator access, it could still bypass the required human reviewer gate unless can_admins_bypass is explicitly set to false. Add that setting to the API payload, add a UI step to disable admin bypass, and include the value in the required read-back check.</comment>

<file context>
@@ -0,0 +1,68 @@
+  --input - <<'JSON'
+{
+  "wait_timer": 0,
+  "prevent_self_review": true,
+  "reviewers": [
+    {
</file context>

deploy-production:
name: Deploy production
runs-on: ubuntu-latest
environment: production

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Because GitHub auto-creates the production environment with no protection rules on the first deployment when it doesn't already exist, the protection provided by environment: production silently disappears if the environment is missing or its reviewers are later removed. The repository risk here is mitigated by the human-only runbook and merge ordering, but the workflow itself never verifies that protection_rules is non-empty before running wrangler deploy. Consider adding a defense-in-depth guard step near the start of the job that queries repos/{owner}/{repo}/environments/production and fails the build unless a required_reviewers protection rule is present, so a misconfigured or auto-created phantom gate can't slip through to production.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/deploy.yml, line 21:

<comment>Because GitHub auto-creates the `production` environment with no protection rules on the first deployment when it doesn't already exist, the protection provided by `environment: production` silently disappears if the environment is missing or its reviewers are later removed. The repository risk here is mitigated by the human-only runbook and merge ordering, but the workflow itself never verifies that `protection_rules` is non-empty before running `wrangler deploy`. Consider adding a defense-in-depth guard step near the start of the job that queries `repos/{owner}/{repo}/environments/production` and fails the build unless a `required_reviewers` protection rule is present, so a misconfigured or auto-created phantom gate can't slip through to production.</comment>

<file context>
@@ -18,6 +18,7 @@ jobs:
   deploy-production:
     name: Deploy production
     runs-on: ubuntu-latest
+    environment: production
     steps:
       - name: Checkout code
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant