Contributor License Agreement enforcement for all northpolesec open-source repos.
Rule: a PR is cleared only when every commit author is a current org member, a bot, or has signed the CLA. Signatures are shared across all repos via one file.
Two repos:
| repo | visibility | holds |
|---|---|---|
northpolesec/cla (this one) |
public | the CLA check action + CLA.md — public so the public project repos can use the action |
northpolesec/cla-signatures |
private | signatures/cla.json — the signer list, read/written via App token |
CLA.md # the CLA text (hardcoded URL in the action)
.github/actions/cla/action.yml # composite action: App token + github-script
.github/actions/cla/cla.js # the logic (pure decision fns + orchestration)
.github/actions/cla/cla.test.js # runnable check: node cla.test.js
examples/project-repo-cla.yml # per-repo caller workflow
- Create an org-owned GitHub App (Org → Settings → Developer settings → GitHub Apps).
- Permissions: Repository → Contents: Read & write, Organization → Members: Read.
- Generate a private key.
- Install it on the private
cla-signaturesrepo only (Members:Read applies org-wide).
- Add org-level Actions secrets (Org → Settings → Secrets → Actions):
CLA_APP_ID= the App's IDCLA_APP_KEY= the private key (full PEM)
- Keep
clapublic andcla-signaturesprivate.
Copy examples/project-repo-cla.yml to .github/workflows/cla.yml. That's the only
per-repo file, and it passes just the two secrets (secrets.CLA_APP_ID/KEY). The CLA URL,
signatures repo, and org are hardcoded in the action.
pull_request_targetis intentional (fork PRs need base-repo context + the App secret); safe here because the action never checks out PR code.