Shipped Open source Creator and maintainer Open core 2026 - present

contribution-checker

Gates pull requests behind a contributor application, as a GitHub App or from inside GitHub Actions.

Self-hosted app that gates pull requests behind a contributor application form. A GitHub App, or a pair of Actions workflows where an App cannot be installed, closes pull requests from contributors who have not been approved, then reopens them once a maintainer approves. Built for Postiz work and open sourced under AGPL. It may move into GHub later, but it sits with the Postiz work for now.

Why it exists

Popular repositories attract pull requests nobody asked for. Triaging them by hand is slow, and the slow part is not the code review. It is deciding whether the contribution should have been opened at all.

contribution-checker moves that decision to the front. Contributors apply through a public form. Maintainers approve or deny from a dashboard. Everything else follows from that one decision.

How it works

A GitHub App watches pull_request.opened and pull_request.reopened on linked repositories. If the author has not been approved for that project, the app closes the pull request with a comment pointing to the project's application page. When a maintainer approves the applicant, their previously closed pull requests reopen automatically across every linked repo.

There is a second path for repositories where installing a GitHub App is not an option. Two GitHub Actions workflows do the same gating from inside Actions, authenticating with the run's OIDC token. Nothing is shared, so there is no secret to configure or rotate.

Approval is not the only way past the gate. A manual decision on a GitHub login wins first, then the bypass list, then the collaborator check, then the applicant's latest application. That order is why bots and existing collaborators never see the form.

What it covers

Each project builds its own application form with a schema builder, and forms can be saved as templates and reused. Access to a project comes in three roles: owner, admin and reviewer. Every decision lands in an append-only audit log.

Maintainers are notified in app, by SMTP email, and through HMAC-signed outbound webhooks with retries. Pull requests get per-project labels for pending, approved and denied. Any GitHub login can be approved or denied by hand without an application, bots can be added to a bypass list, repository collaborators can be bypassed automatically, denials can carry a cooldown before reapplying, and revoking someone can close their open pull requests.

The public apply endpoint is rate limited.

It self-hosts as a Docker Compose stack on SQLite, with secrets read from environment variables or HashiCorp Vault.

Where it sits

It came out of Postiz work, not out of GHub. It is public and licensed under AGPL, so it can be read, run and forked outside the context it was written for.

Moving it into GHub is on the table. It has not happened, and this record will say so when it does.

Scope

It gates pull requests and manages the applications behind that gate.

It does not judge the contribution. It records who is allowed to open one.

It is held to the same standard as everything else

Contribution Checker has its own published advisories, under the GSSA- prefix on gadvisory.org, written up the same way a third-party finding would be.

They cover the things a dashboard gets wrong when nobody is looking: shipping without a content security policy, frame options or HSTS, and reading a full request body on the webhook and CI endpoints before validating anything, which let a multi-gigabyte post exhaust process memory. Both are fixed, and both are on record.

Publishing your own findings against your own product is the cheap version of a promise. It costs a little pride and it means the security page is not the only place making claims.