Verify commit signatures using Auths identity keys. Ensures every commit in a PR or push is cryptographically signed by an authorized developer.
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: auths-dev/auths-verify-github-action@v1
with:
allowed-signers: '.auths/allowed_signers'That's it. The action auto-detects the commit range from the GitHub event (PR or push), downloads the auths CLI, and verifies each commit.
- Verifies SSH commit signatures against allowed signers or identity bundles
- Auto-detects commit range from pull request or push events
- Downloads and caches the
authsCLI automatically (with SHA256 checksum verification) - Skips merge commits by default
- Gracefully handles GPG-signed commits (skips rather than fails)
- Generates a GitHub Step Summary with per-commit results table and a "How to fix" section when verification fails
- Classifies failures (unsigned, unknown key, corrupted signature) with copy-pasteable fix commands
- Optionally posts results directly to the PR as a comment (
post-pr-comment: true) - Pre-flight checks: detects shallow clones and missing
ssh-keygen
| Input | Description | Required | Default |
|---|---|---|---|
allowed-signers |
Path to allowed_signers file | No | .auths/allowed_signers |
identity-bundle |
Path to identity bundle JSON file (alternative to allowed-signers) | No | '' |
identity-bundle-json |
Raw identity bundle JSON content (written to temp file automatically) | No | '' |
commit-range |
Git commit range to verify (e.g. HEAD~5..HEAD) |
No | Auto-detected from event |
auths-version |
Auths CLI version to use (e.g. 0.5.0) |
No | '' (latest) |
fail-on-unsigned |
Whether to fail the action if unsigned commits are found | No | true |
skip-merge-commits |
Whether to skip merge commits during verification | No | true |
post-pr-comment |
Post a PR comment with results and fix instructions (requires pull-requests: write) |
No | false |
github-token |
GitHub token for posting the PR comment (required when post-pr-comment: true) |
No | '' |
Note:
allowed-signersandidentity-bundle/identity-bundle-jsonare mutually exclusive. Use one verification mode or the other.
| Output | Description |
|---|---|
verified |
true if all commits passed verification |
results |
JSON array of per-commit verification results |
total |
Total number of commits checked |
passed |
Number of commits that passed verification |
failed |
Number of commits that failed verification |
Commit the team's public keys to your repo:
# .auths/allowed_signers
alice@example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...
bob@example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...
- uses: auths-dev/auths-verify-github-action@v1
with:
allowed-signers: '.auths/allowed_signers'Export your identity bundle locally and store it as a GitHub secret:
auths id export-bundle --alias mykey --output bundle.json
gh secret set AUTHS_IDENTITY_BUNDLE < bundle.jsonThen use the secret in your workflow:
- uses: auths-dev/auths-verify-github-action@v1
with:
identity-bundle-json: ${{ secrets.AUTHS_IDENTITY_BUNDLE }}Or commit the bundle (it contains only public data) and reference the file:
- uses: auths-dev/auths-verify-github-action@v1
with:
identity-bundle: '.auths/identity-bundle.json'name: Verify Commits
on:
pull_request:
push:
branches: [main]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: auths-dev/auths-verify-github-action@v1
with:
allowed-signers: '.auths/allowed_signers'name: Verify Commits
on: [pull_request]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: auths-dev/auths-verify-github-action@v1
with:
identity-bundle-json: ${{ secrets.AUTHS_IDENTITY_BUNDLE }}- uses: auths-dev/auths-verify-github-action@v1
with:
allowed-signers: '.auths/allowed_signers'
fail-on-unsigned: 'false'Post results (and a "How to fix" section) directly on the PR where contributors actually look:
jobs:
verify:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: auths-dev/auths-verify-github-action@v1
with:
allowed-signers: '.auths/allowed_signers'
post-pr-comment: 'true'
github-token: ${{ secrets.GITHUB_TOKEN }}- name: Verify commits
id: verify
uses: auths-dev/auths-verify-github-action@v1
with:
allowed-signers: '.auths/allowed_signers'
fail-on-unsigned: 'false'
- name: Gate a downstream step on verification
if: steps.verify.outputs.verified == 'true'
run: ./deploy.shStore in your org's .github repo at .github/workflows/auths-verify.yml:
name: Auths Verify
on:
workflow_call:
inputs:
mode:
description: 'warn or enforce'
type: string
default: 'enforce'
secrets:
AUTHS_IDENTITY_BUNDLE:
required: false
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: auths-dev/auths-verify-github-action@v1
with:
identity-bundle-json: ${{ secrets.AUTHS_IDENTITY_BUNDLE }}
fail-on-unsigned: ${{ inputs.mode == 'enforce' && 'true' || 'false' }}Then each repo opts in:
name: Verify
on: [pull_request]
jobs:
auths:
uses: your-org/.github/.github/workflows/auths-verify.yml@main
with:
mode: enforce
secrets: inheritfetch-depth: 0onactions/checkout(the action detects shallow clones and provides a fix message)- Commits must be SSH-signed (the action downloads
authsCLI automatically) - OpenSSH 8.0+ on the runner (pre-installed on GitHub-hosted runners)
- Runs pre-flight checks (shallow clone detection, ssh-keygen availability)
- Downloads and caches the
authsCLI binary (with SHA256 checksum verification) - Determines the commit range from the GitHub event context
- Runs
auths verify-commitwith--jsonoutput - Parses results, skipping merge commits and GPG-signed commits
- Writes a Markdown summary table to GitHub Step Summary
- Sets outputs and fails the workflow if unsigned commits are found (configurable)
Apache-2.0. See LICENSE.
- Auths - Decentralized identity for developers
- Auths CLI - Command-line tool
- Signing commits with Auths - Setup guide