Skip to content

fix(security): scorecard job permissions, dispatch secret-gate, .envrc placeholder#30

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/wokelangiser-security-hardening
Jun 20, 2026
Merged

fix(security): scorecard job permissions, dispatch secret-gate, .envrc placeholder#30
hyperpolymath merged 1 commit into
mainfrom
claude/wokelangiser-security-hardening

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Why

Pre-existing Hypatia workflow_audit findings (unrelated to #28's timeout fix). The 🔴 critical .envrc "Generic API key" is a verified false positive — a commented-out # export API_KEY="..." on line 24 (gitleaks + trufflehog both pass) — and is excluded.

Fixes (3)

  1. scorecard.yml — explicit least-privilege job permissions: on the OpenSSF Scorecard reusable-workflow caller (was inheriting top-level read-all, which can't grant the security-events/id-token writes publishing needs). Clears scorecard_wrapper_missing_job_permissions.
  2. instant-sync.yml — secret-presence gate on the repository-dispatch step (FARM_DISPATCH_TOKEN mapped to a job-level env var, since secrets can't be referenced directly in if:), so forks skip it instead of firing with an empty token. Clears secret_action_without_presence_gate.
  3. .envrc — substitute the unsubstituted {{PROJECT_NAME}} scaffold placeholder with the real project name.

3 files changed, 17 insertions(+), 1 deletion(-).

Pending (authorised, follow-up commit)

  • governance.yml SHA-pingovernance-reusable.yml@main → a commit SHA (DependencyPinning). Needs the standards@main SHA; standards is out of this session's read scope. Will be added to this branch once the SHA is confirmed.

Not in this PR (riskier / unapproved)

scorecard-enforcer.yml publish-job split (scorecard_publish_with_run_step, non-trivial refactor); setup.sh curl|sh CWE-494 (install-script redesign); codeql.yml "nominal SAST" (its matrix already has language: actions — finding looks stale); GS007 branch cleanup.

Caveats

  • instant-sync.yml and scorecard.yml trigger only on push: main / schedule (not on PRs), so their first real execution is post-merge — PR CI validates YAML + the Hypatia scan, not a functional run. Watch the first post-merge Scorecard run for the new job permissions.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Y2MWTAqX2x7goVJzjFB4j5


Generated by Claude Code

…c placeholder

Addresses pre-existing Hypatia workflow_audit findings (unrelated to the timeout PR):

- scorecard.yml: add explicit least-privilege job permissions to the OpenSSF
  Scorecard reusable-workflow caller (was inheriting top-level read-all, which
  can't grant the security-events/id-token writes publishing needs). Clears
  scorecard_wrapper_missing_job_permissions.
- instant-sync.yml: presence-gate the repository-dispatch step on
  FARM_DISPATCH_TOKEN (mapped to a job env var, since secrets can't be used in
  if:) so forks skip it instead of firing with an empty token. Clears
  secret_action_without_presence_gate.
- .envrc: substitute the unsubstituted {{PROJECT_NAME}} scaffold placeholder
  with the real project name.

Deferred: SHA-pinning governance.yml's governance-reusable.yml@main needs the
standards@main commit SHA, and the standards repo is out of this session's
scope. The critical .envrc 'Generic API key' finding is a false positive (a
commented-out '# export API_KEY="..."' placeholder on line 24; gitleaks and
trufflehog both pass).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2MWTAqX2x7goVJzjFB4j5
@hyperpolymath
hyperpolymath marked this pull request as ready for review June 20, 2026 07:24
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 14 issues detected

Severity Count
🔴 Critical 1
🟠 High 9
🟡 Medium 4

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Issue in scorecard-enforcer.yml",
    "type": "scorecard_publish_with_run_step",
    "file": "scorecard-enforcer.yml",
    "action": "split_scorecard_publish_job",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in instant-sync.yml",
    "type": "secret_action_without_presence_gate",
    "file": "instant-sync.yml",
    "action": "peter-evans/repository-dispatch",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Download-and-execute pattern (curl|wget pipe to shell) -- verify integrity before execution (3 occurrences, CWE-494)",
    "type": "shell_download_then_run",
    "file": "/home/runner/work/wokelangiser/wokelangiser/setup.sh",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "line": 24,
    "reason": "Secret found: Generic API key",
    "type": "secret_detected",
    "file": "/home/runner/work/wokelangiser/wokelangiser/.envrc",
    "action": "revoke_rotate_and_purge",
    "rule_module": "security_errors",
    "severity": "critical"
  },
  {
    "reason": "Nominal-only SAST in wokelangiser: codeql.yml language matrix contains no language present in the repo and lacks `actions`, so CodeQL records zero results on every commit. Remediation: set the CodeQL matrix to `language: actions`.",
    "type": "StaticAnalysis",
    "file": "/home/runner/work/wokelangiser/wokelangiser",
    "action": "auto_fix",
    "rule_module": "scorecard",
    "severity": "medium",
    "remediation": "Add CodeQL or equivalent SAST workflow.",
    "scorecard_check": "SAST"
  },
  {
    "reason": "1 workflow(s) with tag-pinned (not SHA-pinned) actions in wokelangiser",
    "type": "DependencyPinning",
    "file": "/home/runner/work/wokelangiser/wokelangiser",
    "action": "auto_fix",
    "rule_module": "scorecard",
    "severity": "medium",
    "remediation": "Pin GitHub Actions and Docker base images by SHA hash.",
    "scorecard_check": "Pinned-Dependencies"
  },
  {
    "reason": "Repository has 9 non-main remote branch(es). Policy: single main branch only.",
    "type": "GS007",
    "file": ".",
    "action": "delete_remote_branches",
    "rule_module": "git_state",
    "severity": "medium"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/workflow_audit/scorecard_wrapper_missing_job_permissions -- Hypatia workflow_audit: scorecard_wrapper_missing_job_permissions -- 20 day(s) old [STALE]",
    "type": "CSA001",
    "file": "scorecard.yml",
    "action": "escalate",
    "rule_module": "code_scanning_alerts",
    "severity": "high"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/workflow_audit/secret_action_without_presence_gate -- Hypatia workflow_audit: secret_action_without_presence_gate -- 20 day(s) old [STALE]",
    "type": "CSA001",
    "file": "instant-sync.yml",
    "action": "escalate",
    "rule_module": "code_scanning_alerts",
    "severity": "high"
  },
  {
    "reason": "Code scanning (Hypatia): hypatia/workflow_audit/scorecard_publish_with_run_step -- Hypatia workflow_audit: scorecard_publish_with_run_step -- 20 day(s) old [STALE]",
    "type": "CSA001",
    "file": "scorecard-enforcer.yml",
    "action": "escalate",
    "rule_module": "code_scanning_alerts",
    "severity": "high"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath
hyperpolymath merged commit 0a66402 into main Jun 20, 2026
20 checks passed
hyperpolymath added a commit that referenced this pull request Jun 20, 2026
… headers, tighten dispatch gate (#31)

* fix(security): pin governance reusable to SHA, migrate stale PMPL-1.0 headers, tighten dispatch gate

Follow-ups to #30 (which merged before these could be appended):

- governance.yml: pin governance-reusable.yml@main -> @e0caf11508a3989574713c78f5f444f2ce5e33ef (the standards commit scorecard.yml already trusts). Clears the DependencyPinning finding.
- License: migrate the remaining stale PMPL-1.0 SPDX headers to MPL-2.0 on codeql.yml, scorecard.yml and secret-scanner.yml (leftovers from the repo's PMPL-1.0 -> MPL-2.0 migration). No docs carried stale SPDX headers, so CC-BY-SA-4.0 had no targets this pass.
- instant-sync.yml: the repository-dispatch action now consumes the gated env var (token: env.FARM_DISPATCH_TOKEN) instead of secrets directly, so the presence gate and the secret consumption reference the same identifier - helping workflow_audit recognise the gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2MWTAqX2x7goVJzjFB4j5

* revert(ci): un-pin governance reusable back to @main

The e0caf115 pin (the SHA scorecard.yml uses) broke 'governance / Language / package anti-pattern policy': that older governance-reusable.yml version checks out hyperpolymath/standards at the CALLER's commit (github.sha = the wokelangiser PR merge commit), which doesn't exist in standards -> 'fatal: remote error: upload-pack: not our ref'. The @main version doesn't have this bug, so revert restores green CI. DependencyPinning stays open until a current standards@main SHA (with the fix) is available; standards is out of this session's scope.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2MWTAqX2x7goVJzjFB4j5

---------

Co-authored-by: Claude <noreply@anthropic.com>
@github-actions
github-actions Bot deleted the claude/wokelangiser-security-hardening branch June 21, 2026 02:15
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.

2 participants