feat(ci): Rekor v2 identity monitoring for the release signer#1727
feat(ci): Rekor v2 identity monitoring for the release signer#1727lockwobr wants to merge 1 commit into
Conversation
|
🌿 Preview your docs: https://nvidia-preview-feat-rekor-v2-identity-monitor.docs.buildwithfern.com/aicr |
📝 WalkthroughWalkthroughThe Rekor monitoring workflow now resolves the newest currently valid Rekor v2 shard from the generated signing configuration and passes that URL to the reusable monitor workflow. Its documentation explains consistency and identity checks, v2 requirements, automatic shard discovery, resolution failures, and checkpoint reset steps when switching from v1 to v2. Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/contributor/maintaining.md`:
- Around line 87-94: Update the illustrative command in the documentation to
match the CI step by using “go run ./cmd/aicr trust update --emit-signing-config
signing-config.json” instead of the installed “aicr” binary, and keep the
accompanying jq expression synchronized with the validity-window logic used by
the resolve-v2-shard job in rekor-monitor.yaml.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 308ecdd3-f04f-4c4f-b064-e1ea9c5585d2
📒 Files selected for processing (2)
.github/workflows/rekor-monitor.yamldocs/contributor/maintaining.md
Re-enable transparency-log identity monitoring for AICR's release signer on Rekor v2, replacing the v1 identity scan that timed out on every run and never completed a single scan. The v1 firehose scan ran ~50x slower than the log grew, so it could never keep up in a bounded CI job. Rekor v2 is tile-based (bulk 256-entry reads), so a single-worker scan outpaces the log and both the consistency proof and the identity scan complete in one cheap hourly job. This rides on release signing having moved to v2 (#1650 / #1679). - Add a resolve-v2-shard job that reads the current v2 shard from the same TUF signing config release signing uses (aicr trust update --emit-signing-config), so the shard URL is never hardcoded and yearly shard rotation needs no workflow change. - Keep the certIdentities identity config; the reusable MonitorLoop runs the consistency proof then the identity scan in one job. - Document the v2 rationale, automatic shard selection, and the one-time v1->v2 checkpoint reset in docs/contributor/maintaining.md. Signed-off-by: Brian Lockwood <lockwobr@gmail.com>
3d1c64e to
150badf
Compare
Coverage Report ✅
Coverage BadgeNo Go source files changed in this PR. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/contributor/maintaining.md`:
- Around line 111-115: Update the checkpoint cleanup command in the maintenance
documentation to paginate the artifact listing, using gh api’s --paginate option
or an equivalent explicit page loop, while preserving extraction of each
artifact ID and deletion of all checkpoint artifacts.
- Around line 117-119: Add a one-time Rekor historical audit step before
removing the v1 checkpoint, covering entries predating the v2 baseline and
detecting unseen identity entries. Alternatively, explicitly document that this
historical gap is accepted; update the v2 monitor, `aicr verify`, and checkpoint
guidance accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Enterprise
Run ID: 6a74ebc4-6472-44ce-95d4-1bf4b3a42cfc
📒 Files selected for processing (2)
.github/workflows/rekor-monitor.yamldocs/contributor/maintaining.md
| ```bash | ||
| gh api "repos/NVIDIA/aicr/actions/artifacts?name=checkpoint" \ | ||
| --jq '.artifacts[].id' \ | ||
| | xargs -I{} gh api -X DELETE "repos/NVIDIA/aicr/actions/artifacts/{}" | ||
| ``` |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n## docs/contributor/maintaining.md (around lines 111-115)\n'
nl -ba docs/contributor/maintaining.md | sed -n '100,125p'
printf '\n## Search for related artifact cleanup guidance\n'
rg -n "actions/artifacts|checkpoint cleanup|checkpoint" docs .github -g '!**/node_modules/**' || trueRepository: NVIDIA/aicr
Length of output: 248
🌐 Web query:
GitHub REST API actions artifacts list pagination per_page page documentation
💡 Result:
The GitHub REST API endpoints for listing artifacts support pagination via the per_page and page query parameters [1][2]. Key details for these parameters: - per_page: Defines the number of results to return per page. The maximum value allowed is 100, and the default value is 30 [1][2]. - page: Specifies the page number of the results to retrieve, with a default value of 1 [1][2]. These parameters are applicable to endpoints such as List artifacts for a repository and List workflow run artifacts [1][2]. For more advanced pagination needs, the GitHub REST API uses Link headers to provide URLs for accessing subsequent pages of data [3][4]. Users can also leverage client libraries like Octokit.js, which provides helper methods like octokit.paginate to automatically handle fetching all pages of results [3].
Citations:
- 1: https://docs.github.com/en/rest/actions/artifacts
- 2: https://docs.github.com/en/enterprise-cloud@latest/rest/actions/artifacts
- 3: https://docs.github.com/en/rest/using-the-rest-api/using-pagination-in-the-rest-api?apiVersion=2026-03-10
- 4: https://docs.github.com/en/rest/using-the-rest-api/using-pagination-in-the-rest-api
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
p = Path("docs/contributor/maintaining.md")
for i, line in enumerate(p.read_text().splitlines(), 1):
if 100 <= i <= 125:
print(f"{i:4d}: {line}")
PY
printf '\n## Related mentions\n'
python3 - <<'PY'
from pathlib import Path
import re
for path in [Path("docs/contributor/maintaining.md")]:
text = path.read_text()
for m in re.finditer(r'checkpoint|artifact|gh api', text, re.I):
line = text.count("\n", 0, m.start()) + 1
print(f"{path}:{line}")
PYRepository: NVIDIA/aicr
Length of output: 1897
🌐 Web query:
GitHub artifacts list endpoint name filter pagination behavior gh api actions/artifacts?name=checkpoint
💡 Result:
The GitHub Actions artifacts API endpoints (e.g., GET /repos/{owner}/{repo}/actions/artifacts) support both a name filter and standard pagination parameters (per_page and page) [1][2][3]. When you include the name query parameter (e.g., ?name=checkpoint), the API filters the returned list to only include artifacts matching that specific name [1][4]. Because the API continues to support pagination, the name filter applies to the entire set of artifacts, and the paginated results will contain only the artifacts that match the provided name [1][5]. Key behaviors to note: 1. Pagination Parameters: The endpoint uses standard page and per_page parameters [1][3]. You should follow the link header in the API response to reliably navigate through paginated results, rather than manually constructing page numbers, as the latter can be error-prone [6][7]. 2. Combining Filters: The name filter can be used in conjunction with pagination [1][5]. If you request actions/artifacts?name=checkpoint&per_page=100, the API will return a paginated list of artifacts where every item matches the name "checkpoint" [1]. 3. Tool Usage: When using the GitHub CLI (gh api), ensure you are targeting the correct endpoint. If you encounter issues with manual pagination, rely on the link header provided in the API response or use higher-level CLI commands where available to handle the iteration for you [8][7]. In summary, the name filter is a server-side parameter that restricts the dataset before pagination occurs, ensuring that all subsequent pages of the result set adhere to your specified filter [1].
Citations:
- 1: https://docs.github.com/en/rest/actions/artifacts
- 2: https://docs.github.com/en/enterprise-cloud@latest/rest/actions/artifacts
- 3: https://docs.github.com/en/enterprise-server@3.21/rest/actions/artifacts?apiVersion=2026-03-10
- 4: https://github.com/google/go-github/blob/master/github/actions_artifacts.go
- 5: Unable to filter artifacts by name in golang google/go-github#3328
- 6: https://docs.github.com/en/rest/using-the-rest-api/using-pagination-in-the-rest-api
- 7: https://docs.github.com/en/rest/using-the-rest-api/using-pagination-in-the-rest-api?apiVersion=2026-03-10
- 8: https://github.com/cli/cli/blob/trunk/pkg/cmd/run/shared/artifacts.go
Paginate the checkpoint cleanup. gh api only returns the first page here, so once checkpoint artifacts exceed the default page size, older stale entries can be left behind. Add --paginate or an explicit page loop so every checkpoint artifact is deleted.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/contributor/maintaining.md` around lines 111 - 115, Update the
checkpoint cleanup command in the maintenance documentation to paginate the
artifact listing, using gh api’s --paginate option or an equivalent explicit
page loop, while preserving extraction of each artifact ID and deletion of all
checkpoint artifacts.
| The first v2 run then watches forward from the current head; historical entries | ||
| predating the baseline are covered by release-time verification (the `aicr | ||
| verify` path), not by this monitor. |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the referenced doc section with line numbers
sed -n '100,140p' docs/contributor/maintaining.md | cat -n
# Find references to the v2 run / checkpoint / verify wording
rg -n "v2 run|checkpoint|aicr verify|Rekor|identity scan|historical" docs pkg cmd .github -S
# Map likely verification-related files before reading
fd -a "verify" docs pkg cmd tools | sed -n '1,200p'Repository: NVIDIA/aicr
Length of output: 50369
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the user-facing verification docs around the relevant claims
sed -n '160,190p' docs/user/artifact-verification.md | cat -n
sed -n '2550,2635p' docs/user/cli-reference.md | cat -n
sed -n '1,90p' docs/integrator/supply-chain-verification.md | cat -n
# Inspect the verifier implementation for any Rekor history scanning
ast-grep outline pkg/bundler/attestation/verifying.go --view expanded
ast-grep outline pkg/evidence/verifier/verify.go --view expanded
# Search for code paths that query Rekor entries by identity, history, or monitor-style scanning
rg -n "history|historical|identity scan|certificate SAN|Rekor.*search|rekor.*search|entries.*identity|query.*Rekor|scan forward|baseline" pkg docs -SRepository: NVIDIA/aicr
Length of output: 29801
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the surrounding maintenance guidance, including the historical audit section
sed -n '288,325p' docs/contributor/maintaining.md | cat -n
# Inspect the verifier implementation paths for any identity-history scan behavior
sed -n '1,220p' pkg/bundler/attestation/verifying.go | cat -n
sed -n '1,280p' pkg/evidence/verifier/verify.go | cat -n
# Look for any Rekor search-by-identity or history scan code
rg -n "search.*identity|identity.*search|SAN|history scan|historical scan|Rekor.*UUID|rekor-cli search|search --sha|search --email|certificate identity" pkg docs -SRepository: NVIDIA/aicr
Length of output: 29915
Add a one-time Rekor history audit before dropping the v1 checkpoint. The v2 monitor only advances from the new head, and aicr verify checks individual release artifacts; neither covers an unseen pre-baseline identity entry on its own. If that gap is acceptable, document it explicitly; otherwise keep the v1 checkpoint until a historical audit runs.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/contributor/maintaining.md` around lines 117 - 119, Add a one-time Rekor
historical audit step before removing the v1 checkpoint, covering entries
predating the v2 baseline and detecting unseen identity entries. Alternatively,
explicitly document that this historical gap is accepted; update the v2 monitor,
`aicr verify`, and checkpoint guidance accordingly.
Summary
Re-enable transparency-log identity monitoring for AICR's release signer on Rekor v2, replacing the v1 identity scan that timed out on every run and never completed a single scan.
Motivation / Context
The v1 firehose identity scan ran ~50x slower than the log grew, so it could never keep up in a bounded CI job (see #1623 for the full analysis). Rekor v2 is tile-based (bulk 256-entry reads), so a single-worker scan outpaces the log and both the consistency proof and the identity scan complete in one cheap hourly job. This rides on release signing having moved to v2 (#1650 / #1679) — only entries actually in v2 can be watched there.
Fixes: #1623
Related: #1650, #1679, #1149
Type of Change
Component(s) Affected
docs/,examples/).github/workflows/rekor-monitor.yaml(CI supply-chain monitoring)Implementation Notes
MonitorLoopruns the consistency proof, then (becausecertIdentitiesis set) the identity scan, then writes the checkpoint — all in one job. On v2 both finish quickly, so no vendoring/paging/fleet is needed.resolve-v2-shardjob buildsaicr, runsaicr trust update --emit-signing-config, andjqs the current v2 shard out of the TUF signing config, feeding it to the monitor vianeeds. This is the same signing config release signing resolves, so the monitor provably watches where releases write, and yearly shard rotation (log2025-1→log2026-1→ …) needs no workflow change. If the resolve job fails (e.g. TUF CDN down), the monitor is skipped that hour and retries next tick.certSubject/issuersregex for theon-tag.yamlrelease signer.sigstore/rekor-monitorpin (170374c6, 2026-06-22) already has full v2 support; no bump.Testing
No Go source changed (workflow + docs only), so the Go unit/lint/coverage gates do not apply.
Risk Assessment
Rollout notes: One-time post-merge step — the
checkpointartifact holds a v1 checkpoint that a v2 run cannot parse, so delete it once so the first v2 run takes a fresh baseline (documented indocs/contributor/maintaining.md):The first v2 run is baseline-only (saves head, no scan); steady-state runs scan each new window. Historical entries predating the baseline are covered by release-time verification, not this monitor.
Checklist
make testwith-race) — N/A, no Go changes; workflow linted with actionlint + yamllintmake lint)git commit -S)