Skip to content

fix(push-protection): use alerts API proxy when security_and_analysis is unreadable#224

Merged
don-petry merged 55 commits into
mainfrom
claude/issue-117-20260508-1733
Jun 8, 2026
Merged

fix(push-protection): use alerts API proxy when security_and_analysis is unreadable#224
don-petry merged 55 commits into
mainfrom
claude/issue-117-20260508-1733

Conversation

@don-petry

@don-petry don-petry commented May 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixes the recurring security_and_analysis_unavailable compliance finding (Compliance: security_and_analysis_unavailable #117) by introducing a proxy check via the secret-scanning alerts API when the primary security_and_analysis field is unreadable.
  • Makes pp_apply_security_and_analysis more robust when the current settings state cannot be read.
  • Documents the token scope requirement in standards/push-protection.md.

Root Cause

The audit token (ORG_SCORECARD_TOKEN) lacks admin or security_events OAuth scope, so GET /repos/{owner}/{repo} returns security_and_analysis: null. The check treated null the same as "unavailable," firing security_and_analysis_unavailable every week with no self-resolving path.

Changes

scripts/lib/push-protection.sh

  • pp_check_security_and_analysis: When security_and_analysis is unreadable, falls back to GET /repos/{owner}/{repo}/secret-scanning/alerts (accessible without admin scope on public repos):
    • Valid array response → secret scanning is active → emits security_and_analysis_unverifiable (accurate, actionable) instead of security_and_analysis_unavailable. This causes issue Compliance: security_and_analysis_unavailable #117 to auto-close on the next audit run.
    • Non-array response → emits security_and_analysis_unavailable with improved guidance mentioning security_events scope and the apply script.
  • pp_apply_security_and_analysis: Removes the premature return 1 when current state is unreadable. The loop already handles null/missing values correctly (all required values are "enabled", so applying unconditionally is idempotent and safe).

standards/push-protection.md

  • Added "Token scope requirement" subsection under "Compliance Audit Checks" documenting the security_events scope requirement and the proxy-check fallback behaviour.

Test plan

  • Next compliance audit run auto-closes issue Compliance: security_and_analysis_unavailable #117 (once security_and_analysis_unavailable is no longer in findings for .github)
  • New security_and_analysis_unverifiable finding is created with actionable remediation steps
  • apply-repo-settings.sh no longer exits early when security_and_analysis is unreadable — it attempts to apply all settings and reports success or a clear error

Closes #117

Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Push-protection script now handles missing token permissions gracefully instead of hard-failing; applies required security settings and provides clearer error messages about needed permission scopes.
  • Documentation

    • Added token scope requirements documentation, explaining how to enable full security verification and the fallback verification methods when permissions are limited.

Review Change Stack

@don-petry don-petry requested a review from a team as a code owner May 8, 2026 17:44
Copilot AI review requested due to automatic review settings May 8, 2026 17:44
@don-petry

Copy link
Copy Markdown
Contributor Author

PR is ready for review. All checks passing (SonarCloud quality gate passed, ShellCheck clean, AgentShield passed). CodeQL is still running but expected to pass since the changes are pure shell additions with no new code patterns.

Tagging @petry-projects/org-leads for review per CODEOWNERS.

@coderabbitai

coderabbitai Bot commented May 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@don-petry, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 21 minutes and 42 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 22d00ad3-327a-4073-90fa-5dc184c01a3a

📥 Commits

Reviewing files that changed from the base of the PR and between 5a7b46f and 842652e.

📒 Files selected for processing (2)
  • scripts/lib/push-protection.sh
  • standards/push-protection.md
📝 Walkthrough

Walkthrough

This PR updates push-protection audit and apply logic to gracefully degrade when the OAuth token cannot read repository-level security_and_analysis. The apply path now logs inaccessible state and proceeds unconditionally; the audit path uses secret-scanning alerts as a proxy to verify whether security scanning is enabled, emitting either unverifiable or unavailable findings with updated remediation guidance.

Changes

Graceful Degradation for Unreadable Repository Security Analysis

Layer / File(s) Summary
Token Scope Documentation
standards/push-protection.md
New "Token scope requirement" subsection documents audit behavior when token lacks admin or security_events scope, defining unverifiable vs unavailable outcomes tied to secret-scanning alert accessibility, and remediation steps.
Apply Path: Unreadable State Handling
scripts/lib/push-protection.sh
pp_apply_security_and_analysis no longer hard-fails on unreadable state; it logs unavailability and unconditionally applies all required settings. PATCH failure messages updated to explicitly mention required admin or security_events scope and org-plan support.
Audit Path: Proxy-Based Verification
scripts/lib/push-protection.sh
pp_check_security_and_analysis replaces the generic "unavailable" finding with proxy verification via secret-scanning alerts endpoint. Returns unverifiable warning if alerts are detected, or unavailable warning if proxy check fails, with respective remediation guidance.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • #117: This PR directly implements the remediation path for the security_and_analysis_unavailable compliance finding by introducing proxy-based verification and refined unverifiable vs unavailable outcomes with updated error messaging.

Possibly related PRs

  • petry-projects/.github#95: Both PRs modify push-protection standard documentation and audit behavior regarding security_and_analysis handling.
  • petry-projects/.github#134: Both PRs address push-protection enforcement and audit logic for repository security settings.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: implementing a proxy-based verification using the alerts API when security_and_analysis is unreadable.
Linked Issues check ✅ Passed The PR fully addresses issue #117 by implementing proxy verification, updating documentation with token scope requirements, and making the apply script more robust.
Out of Scope Changes check ✅ Passed All changes are directly aligned with fixing the security_and_analysis_unavailable finding through proxy verification, apply script robustness, and documentation updates.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/issue-117-20260508-1733

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses recurring push-protection compliance findings when the audit token cannot read security_and_analysis from GET /repos/{owner}/{repo} by adding a proxy verification path via the secret-scanning alerts API, and updating the standard to document the token-scope behavior.

Changes:

  • Add a fallback in pp_check_security_and_analysis that uses the secret-scanning alerts API to distinguish “unavailable” from “unverifiable.”
  • Make pp_apply_security_and_analysis continue applying required settings even when the current security_and_analysis state can’t be read.
  • Document the token-scope requirement and fallback behavior in the push-protection standard.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
standards/push-protection.md Documents why security_and_analysis may be unreadable and how the audit falls back to proxy verification.
scripts/lib/push-protection.sh Implements proxy-check fallback via secret-scanning alerts and makes apply logic proceed when state is unreadable.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/lib/push-protection.sh Outdated
Comment thread scripts/lib/push-protection.sh Outdated
Comment thread standards/push-protection.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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 `@scripts/lib/push-protection.sh`:
- Around line 137-145: The current comment above the alerts_response / gh_api
call incorrectly states the secret-scanning alerts endpoint is accessible
without admin scope on public repos; update that comment to clarify that the
endpoint requires the authenticated user to be an administrator of the
repository or owning organization regardless of public/private visibility, and
that scope substitution (e.g., using public_repo vs repo) does not remove the
admin role requirement; also note the intended use of this proxy is for cases
where the caller is an admin who has a token with the security_events scope but
not the full repo scope, so the proxy can succeed when security_and_analysis
checks would fail due to scope differences (referencing alerts_response, gh_api,
ORG and repo in the surrounding code).
- Around line 117-122: Update the error message and surrounding comment in
scripts/lib/push-protection.sh: change the err call that currently mentions
`security_events` so it only states that the PATCH to update
`security_and_analysis` failed because the authenticated token/user must have
admin permissions on the repository (remove any suggestion that adding
`security_events` OAuth scope will allow the PATCH). Also correct the comment
that describes the secret-scanning alerts proxy check (the block referencing
access for public repos) to remove the incorrect claim that public repositories
bypass the admin requirement—note that the secret-scanning alerts endpoint
requires repository admin privileges regardless of visibility; keep the proxy
check logic but update its comment to reflect the admin requirement.

In `@standards/push-protection.md`:
- Around line 441-444: Update the remediation paragraph under "To enable full
verification" to instruct owners to regenerate or rotate the classic personal
access token (PAT) in Developer Settings → Personal access tokens (classic) with
the security_events scope checked, then update the ORG_SCORECARD_TOKEN value in
org Settings → Secrets; also keep the alternative command reference to
scripts/apply-repo-settings.sh <repo> using an admin token to configure required
settings and grant the audit token visibility. Ensure the text explicitly names
the security_events scope and the ORG_SCORECARD_TOKEN secret so maintainers know
to change the PAT in Developer Settings before updating the secret.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0e90f2fe-942c-4bc3-b4dc-4f4711379bd8

📥 Commits

Reviewing files that changed from the base of the PR and between fc73ff1 and 5a7b46f.

📒 Files selected for processing (2)
  • scripts/lib/push-protection.sh
  • standards/push-protection.md

Comment thread scripts/lib/push-protection.sh
Comment thread scripts/lib/push-protection.sh
Comment thread standards/push-protection.md Outdated
@don-petry don-petry closed this May 11, 2026
@don-petry don-petry reopened this May 11, 2026
@don-petry don-petry closed this May 12, 2026
@don-petry don-petry reopened this May 12, 2026
@don-petry don-petry enabled auto-merge (squash) May 12, 2026 01:42
@github-actions

Copy link
Copy Markdown
Contributor

Auto-rebase failed — merge conflict — this branch has conflicts with main that must be resolved manually.

Please resolve the conflicts and push:

git fetch origin
git merge origin/main
# resolve conflicts, then:
git add .
git commit
git push

… is unreadable

The compliance audit token (ORG_SCORECARD_TOKEN) lacks the admin or
`security_events` OAuth scope needed to read the `security_and_analysis`
field from GET /repos/{owner}/{repo}. This caused the audit to emit
`security_and_analysis_unavailable` every week with no actionable path
to resolution, since the token also couldn't verify whether the settings
were actually configured.

Changes to scripts/lib/push-protection.sh:
- pp_check_security_and_analysis: when security_and_analysis is unreadable,
  fall back to a proxy check via the secret-scanning alerts endpoint
  (accessible without admin scope on public repos). If the alerts endpoint
  returns a valid array, secret scanning is confirmed active and the finding
  is emitted as `security_and_analysis_unverifiable` (more accurate) instead
  of `security_and_analysis_unavailable`. Both findings include actionable
  guidance: add `security_events` scope to ORG_SCORECARD_TOKEN, or run
  apply-repo-settings.sh with an admin token.
- pp_apply_security_and_analysis: remove the premature return 1 when the
  current state is unreadable. The loop already handles null/missing values
  correctly (treating them as needing update), so the apply now proceeds
  unconditionally when the state is unreadable — all required values are
  "enabled" so this is idempotent. Improves the error message to mention
  both admin scope and security_events scope.

Changes to standards/push-protection.md:
- Document the token scope requirement for full security_and_analysis
  verification and explain the proxy-check fallback behavior introduced
  by this fix.

Closes #117

Co-authored-by: Don Petry <don-petry@users.noreply.github.com>
@don-petry don-petry force-pushed the claude/issue-117-20260508-1733 branch from 0e723e2 to 4a39ef6 Compare May 13, 2026 16:53
@donpetry-bot

donpetry-bot commented May 13, 2026

Copy link
Copy Markdown
Contributor
Superseded by automated re-review at 756fb0fcd5384d4f9a14f7e924abc543948e8481 — click to expand prior review.

Review — fix requested (cycle 1/3)

The automated review identified the following issues. Please address each one:

Findings to fix

[Findings would be inserted here]

Additional tasks

  1. Resolve all unresolved review thread comments from other reviewers
  2. Ensure all CI checks pass after your changes
  3. Rebase on the target branch if behind
  4. Do NOT modify files unrelated to the findings above

The review cascade will automatically re-review after new commits are pushed.

@donpetry-bot

donpetry-bot commented May 14, 2026

Copy link
Copy Markdown
Contributor
Superseded by automated re-review at eca5458476ff4ff433d9256fe53fb9b2df8801f3 — click to expand prior review.

Review — fix requested (cycle 2/3)

The automated review identified the following issues. Please address each one:

Findings to fix

[Findings would be inserted here]

Additional tasks

  1. Resolve all unresolved review thread comments from other reviewers
  2. Ensure all CI checks pass after your changes
  3. Rebase on the target branch if behind
  4. Do NOT modify files unrelated to the findings above

The review cascade will automatically re-review after new commits are pushed.

@don-petry don-petry disabled auto-merge June 8, 2026 21:47
@don-petry

Copy link
Copy Markdown
Contributor Author

@coderabbitai resolve

@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — review-changes (applied)

Changes committed and pushed.

@don-petry don-petry enabled auto-merge (squash) June 8, 2026 21:52
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
✅ Action performed

Comments resolved and changes approved.

@don-petry don-petry disabled auto-merge June 8, 2026 21:58
@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — waiting on PR blockers (intent: fix-reviews)

PR: #224
No changes were committed, but the PR still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews). The retry cron will re-attempt automatically. Next attempt after: 2026-06-08T22:30:46Z

@don-petry don-petry enabled auto-merge (squash) June 8, 2026 22:00
@don-petry don-petry disabled auto-merge June 8, 2026 22:11
@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@don-petry don-petry enabled auto-merge (squash) June 8, 2026 22:12
@don-petry don-petry disabled auto-merge June 8, 2026 22:22
@sonarqubecloud

sonarqubecloud Bot commented Jun 8, 2026

Copy link
Copy Markdown

@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@don-petry don-petry enabled auto-merge (squash) June 8, 2026 22:25

@donpetry-bot donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review — APPROVED ✓

Risk: LOW
Reviewed commit: 842652e5d56a44ca92bfe4774bf5ffa52338a156
Review mode: triage-approved (single reviewer)

Summary

Targeted compliance-audit fix: makes pp_check_security_and_analysis fall back to the secret-scanning alerts endpoint as a proxy when security_and_analysis is unreadable, downgrading the recurring security_and_analysis_unavailable finding (#117) to a more accurate security_and_analysis_unverifiable when scanning is in fact active. Also makes pp_apply_security_and_analysis proceed when current state is unreadable (safe — required values are all "enabled", so PATCH is idempotent), and updates standards/push-protection.md to document the token-scope requirement and remediation steps. Scope is tight: 2 files, +58/-6. The earlier CodeRabbit changes-requested round was resolved (alerts-endpoint admin-requirement comment corrected, security_events removed from the PATCH error message, classic-PAT/secret-rotation language added to the standard), and CodeRabbit subsequently re-approved.

Linked issue analysis

Linked issue #117 (recurring security_and_analysis_unavailable finding) is substantively addressed: the proxy check via the secret-scanning alerts API gives the audit a self-resolving path when the token can prove scanning is active, and the new security_and_analysis_unverifiable finding name causes the existing issue to auto-close on the next audit run as described in the PR body.

Findings

No blocking findings.

  • Correctness: the fallback logic correctly distinguishes "scanning confirmed active" (alerts API returns a JSON array → unverifiable) from "cannot confirm" (non-array → unavailable). jq -e 'type == "array"' is the right type-check.
  • Idempotency: removing the early return 1 in pp_apply_security_and_analysis is safe — the loop that follows applies required values unconditionally, and all required values are "enabled", so re-applying is a no-op on already-correct repos.
  • Error messaging: the PATCH-failure message no longer overstates what security_events can do (it now correctly cites the repo-admin requirement for PATCH), matching the CodeRabbit feedback.
  • Standards doc: the new "Token scope requirement" subsection is consistent with the script behaviour and names the right secret (ORG_SCORECARD_TOKEN), the right scope (security_events), and the right rotation path (Developer Settings → PAT classic → org Settings → Secrets → Actions). No HIGH-risk surface (no auth/secret/crypto/migration changes, no GitHub Actions security smell, no CODEOWNERS/AGENTS.md violation).

CI status

All required checks green: ShellCheck, Lint, Agent Security Scan, Secret scan (gitleaks), CodeQL (actions), SonarCloud (quality gate passed, 0 new issues), AgentShield, dev-lead/dispatch, pr-auto-review/check-and-dispatch. Dependency-audit ecosystem jobs correctly skipped (no matching ecosystems in changed files). mergeStateStatus is BLOCKED only because REVIEW_REQUIRED — this approval will unblock it.


Reviewed automatically by the PR-review agent (single-reviewer mode: opus 4.7). Reply if you need a human review.

@don-petry don-petry merged commit 89ccedd into main Jun 8, 2026
21 checks passed
@don-petry don-petry deleted the claude/issue-117-20260508-1733 branch June 8, 2026 22:35
don-petry added a commit that referenced this pull request Jun 11, 2026
… is unreadable (#224)

* fix(push-protection): use alerts API proxy when security_and_analysis is unreadable

The compliance audit token (ORG_SCORECARD_TOKEN) lacks the admin or
`security_events` OAuth scope needed to read the `security_and_analysis`
field from GET /repos/{owner}/{repo}. This caused the audit to emit
`security_and_analysis_unavailable` every week with no actionable path
to resolution, since the token also couldn't verify whether the settings
were actually configured.

Changes to scripts/lib/push-protection.sh:
- pp_check_security_and_analysis: when security_and_analysis is unreadable,
  fall back to a proxy check via the secret-scanning alerts endpoint
  (accessible without admin scope on public repos). If the alerts endpoint
  returns a valid array, secret scanning is confirmed active and the finding
  is emitted as `security_and_analysis_unverifiable` (more accurate) instead
  of `security_and_analysis_unavailable`. Both findings include actionable
  guidance: add `security_events` scope to ORG_SCORECARD_TOKEN, or run
  apply-repo-settings.sh with an admin token.
- pp_apply_security_and_analysis: remove the premature return 1 when the
  current state is unreadable. The loop already handles null/missing values
  correctly (treating them as needing update), so the apply now proceeds
  unconditionally when the state is unreadable — all required values are
  "enabled" so this is idempotent. Improves the error message to mention
  both admin scope and security_events scope.

Changes to standards/push-protection.md:
- Document the token scope requirement for full security_and_analysis
  verification and explain the proxy-check fallback behavior introduced
  by this fix.

Closes #117

Co-authored-by: Don Petry <don-petry@users.noreply.github.com>

* chore: apply manual instructions [skip ci-relay]

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Don Petry <don-petry@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compliance: security_and_analysis_unavailable

3 participants