Summary
CONTRIBUTING.md:42 requires every commit to carry a DCO sign-off: "Sign your commits with git commit -s (required by the DCO below)." Nothing checks it. No workflow under .github/workflows/ scans for the Signed-off-by: trailer, and it is not among the required status checks on the protect-main ruleset.
The result is a stated requirement that holds only when a contributor happens to read CONTRIBUTING.md and a reviewer happens to notice.
Current state, measured today
Four of six open pull requests are non-compliant. The two clean ones are from first-time contributors who read the guide and ticked the checklist item in the PR template, which is the honest signal here: the guide works when someone reads it, and nothing catches it when they do not. The single signed commit on #20 and the one on #21 are maintainer commits added this week, so the contributor-authored compliance rate is lower than the table suggests.
Why this is worth a check rather than a reminder
The DCO is the project's provenance record. It is the assertion that a contributor had the right to submit what they submitted, and that the record stays public indefinitely. It is also the reason this project does not need a CLA. A provenance record with 3 of 25 coverage on its largest pull request is not serving that purpose.
This was already raised on #20 on 2026-07-28: "it's probably worth a DCO check in CI rather than three separate rebases and a reminder." Six weeks on, the gap is wider rather than narrower, which is the argument for making it structural.
Sequencing
Deliberate: implement after the current open pull requests land, so enforcement starts against a clean baseline.
Turning this on today would immediately block #20, #21, #22, and #24 behind a rebase, on top of the review work those already carry. #22 in particular would need 22 commits re-signed while it is also conflicted and carrying 24 unresolved threads. That is a bad trade for a control whose value is prospective.
One design decision to settle first
Two behaviors are defensible and they are not the same:
- Per-commit. Every commit in the pull request carries the trailer. This is what the GitHub DCO app and most CI implementations do, and it is the strict reading of
CONTRIBUTING.md. It means contributors rebase when they forget.
- Merge-commit only. The squash message carries the sign-off.
protect-main already restricts merges to squash and rebase, so a squash lands one commit and one sign-off. Lighter on contributors, and it still produces a signed record on main, though it attests on behalf of work whose individual commits were never signed.
Option 1 is the stricter provenance record. Option 2 is the lower barrier for drive-by documentation contributions, which is most of the current inbound volume. Worth deciding before wiring anything, because the choice determines whether a contributor ever has to rebase.
Implementation options
- The first-party DCO GitHub App, which is what most OWASP projects use. No workflow to maintain.
- A workflow step scanning
pull_request commits for the trailer. More code, but it lives in the repo, gets pinned like every other action here, and can be tuned to whichever behavior is chosen above.
Either way it should become a third required status check alongside test and build on the protect-main ruleset, otherwise it advises rather than enforces.
Related
Consistent with the principle the harness already applies elsewhere: a rule that must hold every time belongs in a deterministic check rather than in a document that asks politely.
Summary
CONTRIBUTING.md:42requires every commit to carry a DCO sign-off: "Sign your commits withgit commit -s(required by the DCO below)." Nothing checks it. No workflow under.github/workflows/scans for theSigned-off-by:trailer, and it is not among the required status checks on theprotect-mainruleset.The result is a stated requirement that holds only when a contributor happens to read
CONTRIBUTING.mdand a reviewer happens to notice.Current state, measured today
Four of six open pull requests are non-compliant. The two clean ones are from first-time contributors who read the guide and ticked the checklist item in the PR template, which is the honest signal here: the guide works when someone reads it, and nothing catches it when they do not. The single signed commit on #20 and the one on #21 are maintainer commits added this week, so the contributor-authored compliance rate is lower than the table suggests.
Why this is worth a check rather than a reminder
The DCO is the project's provenance record. It is the assertion that a contributor had the right to submit what they submitted, and that the record stays public indefinitely. It is also the reason this project does not need a CLA. A provenance record with 3 of 25 coverage on its largest pull request is not serving that purpose.
This was already raised on #20 on 2026-07-28: "it's probably worth a DCO check in CI rather than three separate rebases and a reminder." Six weeks on, the gap is wider rather than narrower, which is the argument for making it structural.
Sequencing
Deliberate: implement after the current open pull requests land, so enforcement starts against a clean baseline.
Turning this on today would immediately block #20, #21, #22, and #24 behind a rebase, on top of the review work those already carry. #22 in particular would need 22 commits re-signed while it is also conflicted and carrying 24 unresolved threads. That is a bad trade for a control whose value is prospective.
One design decision to settle first
Two behaviors are defensible and they are not the same:
CONTRIBUTING.md. It means contributors rebase when they forget.protect-mainalready restricts merges to squash and rebase, so a squash lands one commit and one sign-off. Lighter on contributors, and it still produces a signed record onmain, though it attests on behalf of work whose individual commits were never signed.Option 1 is the stricter provenance record. Option 2 is the lower barrier for drive-by documentation contributions, which is most of the current inbound volume. Worth deciding before wiring anything, because the choice determines whether a contributor ever has to rebase.
Implementation options
pull_requestcommits for the trailer. More code, but it lives in the repo, gets pinned like every other action here, and can be tuned to whichever behavior is chosen above.Either way it should become a third required status check alongside
testandbuildon theprotect-mainruleset, otherwise it advises rather than enforces.Related
Consistent with the principle the harness already applies elsewhere: a rule that must hold every time belongs in a deterministic check rather than in a document that asks politely.