You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I searched existing issues and did not find a duplicate request.
Affected area
Developer experience / tooling
Layer
Infrastructure / CI
Problem
After #2976, dev-deploy.yml auto-deploys pushes to both main and infra/* branches, with the dev3 IAM role's OIDC trust scoped to repo:Doenet/DoenetApps:ref:refs/heads/main + repo:Doenet/DoenetApps:ref:refs/heads/infra/*. That works for infra branches owned by maintainers, but two gaps remain:
No support for fork PRs. Most of our PRs come from contributor forks, and those branches are unreachable from dev-deploy.yml — the OIDC trust doesn't cover the fork's ref, and the reusable workflows' actions/checkout only checks out refs from the upstream repo (no repository: argument). So the common case — "try this PR on dev3 before merging" — is not actually supported.
No reviewer gate on the manual path. Any push to infra/* auto-deploys immediately. There's no built-in way to require human approval before a not-yet-reviewed branch executes code on dev3. For a maintainer-owned infra/* branch this is usually fine; for any path that eventually deploys fork-PR code, it isn't.
Proposed solution
Adopt the standard GitHub-recommended pattern for deploying fork-PR code from a privileged context:
Replace the infra/* push trigger with workflow_dispatch carrying a pr_number input. A resolve step runs gh pr view to surface the fork's repo, head ref, and head SHA at dispatch time (frozen — later pushes to the PR aren't deployed by the same run). Push-to-main auto-deploy stays as-is.
GitHub Environment dev3 with required reviewers (1–2 maintainers). Each deploy job declares environment: dev3 only on the workflow_dispatch path; the push-to-main auto-deploy stays unenvironment'd. The run pauses on "Waiting for review" before any AWS calls.
Tighten the dev3 OIDC trust in dev3-doenet-repositories.params to exactly two subjects:
repo:Doenet/DoenetApps:ref:refs/heads/main — push-to-main auto path
Thread a deploy_repo input through to each reusable-deploy-*.yml's actions/checkout so the fork's code can actually be checked out (repository: \${{ inputs.deploy_repo }}).
End state: any contributor (fork or maintainer) opens a PR; a maintainer dispatches with pr_number=N, approves the environment gate, and the PR's code deploys to dev3 with full OIDC + ECR + ECS plumbing. Prod is untouched. The infra/* shortcut from #2976 is no longer needed because env-gated manual dispatch covers it.
A full plan with file-by-file changes and verification steps was drafted (in offline notes); happy to attach when this is picked up.
Alternatives considered
`pull_request_target` + env gate. Equivalent security model. Slightly nicer UX (no PR-number paste) but easier to misconfigure into a known-insecure pattern; explicit `workflow_dispatch` is more deliberate.
Comment-driven (`/deploy-dev3` bot). Kubernetes-style. Needs a bot listener and more wiring; environment reviewer UI is built-in and audited.
`github.actor` allowlist in YAML. Simpler but bypasses GitHub's audit log for approvals; allowlist drift lives in code.
Two environments (`dev3-auto` + `dev3-manual`). Uniform but doubles env configuration for no real gain; one env on the manual path only is the lighter shape.
Keep feat(infra): allow dev deploys from infra/* branches #2976's `infra/*` push trigger alongside the env-gated dispatch. Possible but redundant — a maintainer with the env-gate available has no reason to also need an unapproved `infra/*` shortcut.
Additional context
Security notes that came out of the design review (capture them when this is picked up):
dev3 must remain a separate trust boundary from prod (separate AWS account already, IAM resource scoping by `${EnvironmentName}*`). Verify the ECS task role in `service-taskrole-includes.yml` is similarly scoped.
Disable "Allow administrators to bypass configured protection rules" on the `dev3` environment.
The `resolve` job must run before the env gate so the deployed SHA is frozen at dispatch — not pulled live after approval.
Reviewers must inspect `Dockerfile`, `package.json`, lockfile diffs, postinstall scripts before approving. Treat dev3 as "fork code may execute here."
Add a notification on `github-actions-dev3` AssumeRoleWithWebIdentity from a non-`main` subject, so any env-approved dispatch is visible.
Industry references for the pattern: Kubernetes `/ok-to-test`, CNCF projects (Istio, Envoy), GitHub's own "Using environments for deployment" + "Security hardening for GitHub Actions" docs.
Before submitting
Affected area
Developer experience / tooling
Layer
Infrastructure / CI
Problem
After #2976,
dev-deploy.ymlauto-deploys pushes to bothmainandinfra/*branches, with the dev3 IAM role's OIDC trust scoped torepo:Doenet/DoenetApps:ref:refs/heads/main+repo:Doenet/DoenetApps:ref:refs/heads/infra/*. That works for infra branches owned by maintainers, but two gaps remain:dev-deploy.yml— the OIDC trust doesn't cover the fork's ref, and the reusable workflows'actions/checkoutonly checks out refs from the upstream repo (norepository:argument). So the common case — "try this PR on dev3 before merging" — is not actually supported.infra/*auto-deploys immediately. There's no built-in way to require human approval before a not-yet-reviewed branch executes code on dev3. For a maintainer-ownedinfra/*branch this is usually fine; for any path that eventually deploys fork-PR code, it isn't.Proposed solution
Adopt the standard GitHub-recommended pattern for deploying fork-PR code from a privileged context:
Replace the
infra/*push trigger withworkflow_dispatchcarrying apr_numberinput. Aresolvestep runsgh pr viewto surface the fork's repo, head ref, and head SHA at dispatch time (frozen — later pushes to the PR aren't deployed by the same run). Push-to-mainauto-deploy stays as-is.GitHub Environment
dev3with required reviewers (1–2 maintainers). Each deploy job declaresenvironment: dev3only on theworkflow_dispatchpath; the push-to-mainauto-deploy stays unenvironment'd. The run pauses on "Waiting for review" before any AWS calls.Tighten the dev3 OIDC trust in
dev3-doenet-repositories.paramsto exactly two subjects:repo:Doenet/DoenetApps:ref:refs/heads/main— push-to-main auto pathrepo:Doenet/DoenetApps:environment:dev3— env-approved manual dispatchThis drops the
infra/*ref trust added in feat(infra): allow dev deploys from infra/* branches #2976 in favor of the more general env-scoped trust.Thread a
deploy_repoinput through to eachreusable-deploy-*.yml'sactions/checkoutso the fork's code can actually be checked out (repository: \${{ inputs.deploy_repo }}).End state: any contributor (fork or maintainer) opens a PR; a maintainer dispatches with
pr_number=N, approves the environment gate, and the PR's code deploys to dev3 with full OIDC + ECR + ECS plumbing. Prod is untouched. Theinfra/*shortcut from #2976 is no longer needed because env-gated manual dispatch covers it.A full plan with file-by-file changes and verification steps was drafted (in offline notes); happy to attach when this is picked up.
Alternatives considered
Additional context
Security notes that came out of the design review (capture them when this is picked up):
Industry references for the pattern: Kubernetes `/ok-to-test`, CNCF projects (Istio, Envoy), GitHub's own "Using environments for deployment" + "Security hardening for GitHub Actions" docs.