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
{{ message }}
Repository navigation
Reentrant non-sticky deployments can release their shared lock before all runs finish #504
A second non-sticky deployment claim from the same actor is admitted as owner of the first deployment's lock. Both runs share the same lock-ref SHA, so cleanup by the older run can remove the only environment lock while the newer run is still active.
This is a concurrency-correctness issue, not an authorization bypass: callers already need repository write permission. The impact is that the documented one-deployment-at-a-time guarantee can stop holding during overlapping same-owner deployments.
Affected revisions
Originally found in nansen-ai/branch-deploy@8dd55bfc87e62c54dcafdb1015380ff83d020a3e.
Reproduced on maintained github/branch-deploy@826fd07b4eae2e0a6b750c2a19d68b6c8d509cc0.
Relevant code: src/functions/lock.ts same-owner handling and src/functions/unlock-if-unchanged.ts conditional cleanup.
Evidence
A deterministic local fake-Octokit test started with an existing non-sticky lock for claim A, submitted claim B from the same actor, then ran A's cleanup. B was returned as owner, both runs carried the same lock SHA, and A's cleanup deleted that shared ref. No remote refs or workflows were touched.
The existing compare-and-delete mitigation prevents deletion of a replacement lock with a different SHA. It does not cover this case because both admitted runs share the original SHA.
Impact and prerequisites
Two overlapping deployment commands from one write-authorized actor for one environment.
Locking enabled and non-sticky deployment locks.
The older run finishes while the newer run remains active.
Result: the newer deployment continues without its environment lock, so conflicting work can be admitted.
A non-sticky lock should remain effective until every deployment claim admitted under it has completed, or distinct overlapping claims should not share cleanup ownership.
Recommended remediation
Represent each active non-sticky deployment as a distinct lease in compare-and-swap-protected lock state. Cleanup should remove only its own claim and delete the lock only when no active claims remain. A simpler alternative is to reject a distinct same-owner claim while another is active.
Regression test
Acquire a non-sticky lock for claim A, admit a different claim B from the same actor, complete A, then attempt a third deployment while B remains active. Assert the third deployment is rejected and the lock remains until B completes.
Duplicate/disclosure check
Open and closed issues/PRs were searched using same-owner, reentrant, non-sticky, shared-lock, lockRefSha, and cleanup anchors. No exact duplicate was found. The report is public-safe and contains no secret or unauthorized deployment path.
Activity