# github-review attestor

Source: https://www.testifysec.com/docs/cilock/attestors/github-review/

The cilock github-review attestor snapshots the pull request review state of a commit from the GitHub REST API (every PR that contains the commit and every review on it) and signs it as in-toto evidence.

Reads the pull requests associated with a commit, or one named pull request, and every review on each, from the GitHub REST API, and records them as a point-in-time snapshot.

 

| Name | `github-review` |
| --- | --- |
| Predicate type | `https://aflock.ai/attestations/github-review/v0.1` |
| Lifecycle | `prematerial` |
| Default binary? | No |
| Category | code-review (primary) |
| Recommended trace | off — no syscall tracing needed |
| Auto-attaches when | - prefile\_exists: .git/HEAD<br>- preenv\_set: GITHUB\_TOKEN<br>- preenv\_set: GH\_TOKEN<br>- preenv\_set: GITHUB\_ACTIONS |

The facts in this box are generated from the CI/lock binary's own catalog (`cilock tools list`). Do not hand-edit — run `npm run gen:catalog`.

 

## What it captures

 

The attestor resolves the repository and commit, picks a token, then reads either `GET /repos/{repo}/commits/{sha}/pulls` (commit mode) or `GET /repos/{repo}/pulls/{pr}` (PR mode), and `GET /repos/{repo}/pulls/{n}/reviews` for each PR. Every list is followed through its `Link: rel="next"` pages at 100 per page.

 

Fields (the `json` tags on `Attestor`):

 

- `repo`: `owner/name`.
 - `commit_sha`: the commit reviews were looked up for. In PR mode it is the PR's head SHA unless `--attestor-github-review-sha` is set.
 - `fetched_at`: wall-clock time of the read, RFC 3339 UTC.
 - `api_base_url`: the REST base that was read.
 - `token_source`: which source supplied the token: `flag`, `gh-token-env`, `github-token-env`, `gh-auth-token` or `anonymous`. The token itself is never recorded.
 - `prs[]`: `number`, `state` (`open`, `closed`, or `merged` when GitHub reports it merged), `head_sha`, `base_sha`, `url`, and `reviews[]`.
 - `reviews[]`: `state` (GitHub's value, for example `APPROVED`, `CHANGES_REQUESTED`, `COMMENTED`, `DISMISSED`), `user_login`, `submitted_at`, `commit_id`.

 

The attestor records reviews as GitHub returns them. It does not decide whether a PR is approved; write that rule in policy.

 

## When to use

 

To make code review part of the evidence for a release: run it with `cilock attest` (no wrapped command) after the PR exists, then require `APPROVED` reviews from the reviewers you trust in a policy. It also works inside `cilock run`. Auto-detection attaches it when `.git/HEAD` exists and `GITHUB_TOKEN`, `GH_TOKEN` or `GITHUB_ACTIONS` is set.

 

## Flags

 

| Flag | Default | Purpose |
| --- | --- | --- |
| `--attestor-github-review-repo` | parsed from `git remote get-url origin` | `owner/name`. Required for a non-`github.com` remote. |
| `--attestor-github-review-sha` | `git rev-parse HEAD` | Commit to look up. |
| `--attestor-github-review-pr` | (none) | Attest this PR number directly, skipping the commit-to-PR lookup. |
| `--attestor-github-review-token` | (none) | Token with the highest precedence. |
| `--attestor-github-review-api-url` | `https://api.github.com` | REST base; for GitHub Enterprise Server use e.g. `https://ghe.example.com/api/v3`. |

 

Token precedence: the flag, then `GH_TOKEN`, then `GITHUB_TOKEN`, then `gh auth token` (3-second limit), then anonymous.

 

## Output shape

 

```json
{
  "repo": "acme/payments",
  "commit_sha": "3f2a9c1...",
  "fetched_at": "2026-10-16T14:02:11Z",
  "api_base_url": "https://api.github.com",
  "token_source": "github-token-env",
  "prs": [
    {
      "number": 42,
      "state": "merged",
      "head_sha": "3f2a9c1...",
      "base_sha": "a81d0e7...",
      "url": "https://github.com/acme/payments/pull/42",
      "reviews": [
        { "state": "APPROVED", "user_login": "alice", "submitted_at": "2026-10-16T13:40:02Z", "commit_id": "3f2a9c1..." }
      ]
    }
  ]
}
```

 

Subjects: `commitsha:<sha>`, `repo:<owner/name>`, `pr:<owner/name>#<number>` for each PR, and `reviewer:<login>` for each reviewer.

 

## Gotchas

 

- **No attestation before the commit reaches GitHub.** If GitHub answers 422 "No commit found", the attestor fails and records nothing. An empty `prs` list would make "every PR is approved" true, so it is never signed for a commit GitHub has not seen.
 - **A commit in no PR is recorded with `prs: []`.** Your policy must require at least one PR if that matters.
 - **The snapshot is what the token could see.** A private repository read anonymously, or with a token that lacks access, fails with 401, 403 or 404. In GitHub Actions grant `pull-requests: read`; with a fine-grained PAT grant "Pull requests: Read".
 - **Anonymous is public-only and limited to 60 requests an hour.** The attestor warns when it falls back to anonymous, and warns louder inside GitHub Actions.
 - **The data is not signed by GitHub.** The attestor trusts the API; only cilock's own envelope makes the snapshot tamper-evident, as of `fetched_at`.
 - **Each request has a 30-second timeout.**

 

## CLI example

 

```bash
# Review state for HEAD of the current checkout
cilock attest -a github-review -k key.pem -o review.bundle.json -s review-head

# One PR, from any directory
cilock attest -a github-review \
  --attestor-github-review-repo aflock-ai/rookery --attestor-github-review-pr 153 \
  -k key.pem -o review-pr153.bundle.json -s review-pr153
```

 

## See also

 

- [`github`](https://www.testifysec.com/docs/cilock/attestors/github)
 - [Catalog row](https://www.testifysec.com/docs/cilock/reference/attestor-catalog)

 

---

**This page is generated from the CI/lock tool catalog.** Don't edit it here — the source is [`attestation/detection/docs/github-review.doc.md`](https://github.com/aflock-ai/rookery/edit/main/attestation/detection/docs/github-review.doc.md) in [aflock-ai/rookery](https://github.com/aflock-ai/rookery). The same catalog powers `cilock tools show github-review` in the CLI, so a single edit keeps the terminal and the website in sync.

[Edit this page →](https://github.com/aflock-ai/rookery/edit/main/attestation/detection/docs/github-review.doc.md) ·  [Add a new tool →](https://github.com/aflock-ai/rookery/new/main/attestation/detection/docs)

When you open the pull request: if you are an **AI agent**, add the `ai-agent` label. If you are a **human**, add the `human` label.

Reference generated from the product documentation. Match commands and support details to your installed release.
