Skip to content

Add zizmor security scanner and harden CI workflows#7

Merged
penso merged 8 commits intomainfrom
claude/add-zizmor-security-scanner
Jan 30, 2026
Merged

Add zizmor security scanner and harden CI workflows#7
penso merged 8 commits intomainfrom
claude/add-zizmor-security-scanner

Conversation

@penso
Copy link
Copy Markdown
Collaborator

@penso penso commented Jan 30, 2026

Summary

  • Add zizmor GitHub Actions security scanner workflow with SARIF upload to Security tab
  • Pin all action uses: to full SHA hashes to prevent tag-hijacking attacks
  • Add persist-credentials: false to all actions/checkout steps
  • Add top-level permissions: {} with explicit least-privilege per-job permissions
  • Move all ${{ }} expressions out of run: blocks into step-level env: blocks to prevent template injection

Test plan

  • Zizmor CI job appears and passes
  • SARIF results visible in GitHub Security tab
  • All existing CI jobs still pass after hardening

Closes #5

🤖 Generated with Claude Code

penso and others added 8 commits January 29, 2026 18:47
- Add zizmor workflow to scan GitHub Actions for supply-chain risks
- Pin all actions to full SHA hashes to prevent tag-hijacking
- Add persist-credentials: false to all checkout steps
- Add top-level permissions: {} with explicit per-job permissions
- Move ${{ }} expressions from run: blocks into env: blocks

Closes #5

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The zizmor release assets are .tar.gz archives, not bare binaries.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All CI checks (fmt, clippy, build, zizmor) now run as jobs in a single
workflow, so zizmor gates every PR alongside the other checks.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…izmor

The codeql-action/upload-sarif needs actions:read in addition to
security-events:write. Also make fmt/clippy/build depend on zizmor
so they are skipped if workflow security fails.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code scanning must be enabled in repo settings for SARIF upload to
work. Instead, rely on zizmor's non-zero exit code on findings to
fail the job directly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use zizmorcore/zizmor-action (pinned to v0.4.1 SHA) instead of manually
downloading and extracting the zizmor binary.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…avior

The manual zizmor invocation didn't use --online, but the action enables
online-audits by default, causing impostor-commit failures on third-party
action SHAs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@penso penso merged commit bca88e2 into main Jan 30, 2026
4 checks passed
@penso penso deleted the claude/add-zizmor-security-scanner branch January 30, 2026 03:00
jroth1111 pushed a commit to jroth1111/moltis that referenced this pull request Mar 3, 2026
- Add ConfidenceMetrics struct with score, logprobs, and uncertainty_reason fields
- Add confidence field to CompletionResponse (currently None for all providers)
- Add RETRY_THRESHOLD (0.4) and ESCALATE_THRESHOLD (0.6) constants
- Add should_retry() and should_escalate() helper methods

Part of AI agent effectiveness improvements (Issue moltis-org#7)

Co-Authored-By: AI <noreply@anthropic.com>
jroth1111 pushed a commit to jroth1111/moltis that referenced this pull request Mar 3, 2026
- Add ConfidenceMetrics struct with score, logprobs, and uncertainty_reason fields
- Add confidence field to CompletionResponse (currently None for all providers)
- Add RETRY_THRESHOLD (0.4) and ESCALATE_THRESHOLD (0.6) constants
- Add should_retry() and should_escalate() helper methods

Part of AI agent effectiveness improvements (Issue moltis-org#7)
penso added a commit that referenced this pull request Mar 23, 2026
* feat(ci): add zizmor security scanner and harden workflows

- Add zizmor workflow to scan GitHub Actions for supply-chain risks
- Pin all actions to full SHA hashes to prevent tag-hijacking
- Add persist-credentials: false to all checkout steps
- Add top-level permissions: {} with explicit per-job permissions
- Move ${{ }} expressions from run: blocks into env: blocks

Closes #5

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ci): download zizmor tarball instead of bare binary

The zizmor release assets are .tar.gz archives, not bare binaries.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(ci): move zizmor into CI workflow instead of separate workflow

All CI checks (fmt, clippy, build, zizmor) now run as jobs in a single
workflow, so zizmor gates every PR alongside the other checks.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ci): add concurrency groups to cancel superseded runs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ci): add actions:read permission for SARIF upload, gate jobs on zizmor

The codeql-action/upload-sarif needs actions:read in addition to
security-events:write. Also make fmt/clippy/build depend on zizmor
so they are skipped if workflow security fails.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ci): drop SARIF upload, use zizmor exit code to gate CI

Code scanning must be enabled in repo settings for SARIF upload to
work. Instead, rely on zizmor's non-zero exit code on findings to
fail the job directly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(ci): replace manual zizmor install with official GitHub Action

Use zizmorcore/zizmor-action (pinned to v0.4.1 SHA) instead of manually
downloading and extracting the zizmor binary.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(ci): disable online audits in zizmor-action to match previous behavior

The manual zizmor invocation didn't use --online, but the action enables
online-audits by default, causing impostor-commit failures on third-party
action SHAs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Cstewart-HC added a commit to Cstewart-HC/moltis-mini that referenced this pull request Apr 16, 2026
Review fixes applied:
- #1: Extract require_str/opt_usize_or to moltis_tools::params — replaced
  local helpers with params::require_str() and params::u64_param() from
  the shared workspace crate
- #2: Unified error model — CodebaseSearchTool now returns
  Ok(json!({error:..., search_available: false})) for
  BackendUnavailable, matching Peek/Status pattern
- #3: u64→usize truncating cast replaced with usize::try_from().unwrap_or()
- #4: ensure_collections() error remapped from BackendUnavailable to
  IndexFailed { project_id, message }
- moltis-org#6: result.line as usize now clamped with .max(1) minimum
- moltis-org#7: compute_delta carries forward previous hash on hash errors so
  files aren't spuriously marked as removed
- moltis-org#8: Added doc comment noting that watcher batches may contain
  duplicate paths
- moltis-org#9: Extracted effective_extension() from filter.rs, removed
  duplication between filter.rs and watcher.rs
- moltis-org#11: Added tracing::debug! for skipped files in build_initial_snapshot
- moltis-org#12: Added 'drop to stop' documentation on CodeIndexWatcher::start()

32 tests pass, clippy clean.
Cstewart-HC added a commit to Cstewart-HC/moltis-mini that referenced this pull request Apr 16, 2026
Review fixes applied:
- #1: Extract require_str/opt_usize_or to moltis_tools::params — replaced
  local helpers with params::require_str() and params::u64_param() from
  the shared workspace crate
- #2: Unified error model — CodebaseSearchTool now returns
  Ok(json!({error:..., search_available: false})) for
  BackendUnavailable, matching Peek/Status pattern
- #3: u64→usize truncating cast replaced with usize::try_from().unwrap_or()
- #4: ensure_collections() error remapped from BackendUnavailable to
  IndexFailed { project_id, message }
- moltis-org#6: result.line as usize now clamped with .max(1) minimum
- moltis-org#7: compute_delta carries forward previous hash on hash errors so
  files aren't spuriously marked as removed
- moltis-org#8: Added doc comment noting that watcher batches may contain
  duplicate paths
- moltis-org#9: Extracted effective_extension() from filter.rs, removed
  duplication between filter.rs and watcher.rs
- moltis-org#11: Added tracing::debug! for skipped files in build_initial_snapshot
- moltis-org#12: Added 'drop to stop' documentation on CodeIndexWatcher::start()

32 tests pass, clippy clean.
Cstewart-HC added a commit to Cstewart-HC/moltis-mini that referenced this pull request Apr 16, 2026
Review fixes applied:
- #1: Extract require_str/opt_usize_or to moltis_tools::params — replaced
  local helpers with params::require_str() and params::u64_param() from
  the shared workspace crate
- #2: Unified error model — CodebaseSearchTool now returns
  Ok(json!({error:..., search_available: false})) for
  BackendUnavailable, matching Peek/Status pattern
- #3: u64→usize truncating cast replaced with usize::try_from().unwrap_or()
- #4: ensure_collections() error remapped from BackendUnavailable to
  IndexFailed { project_id, message }
- moltis-org#6: result.line as usize now clamped with .max(1) minimum
- moltis-org#7: compute_delta carries forward previous hash on hash errors so
  files aren't spuriously marked as removed
- moltis-org#8: Added doc comment noting that watcher batches may contain
  duplicate paths
- moltis-org#9: Extracted effective_extension() from filter.rs, removed
  duplication between filter.rs and watcher.rs
- moltis-org#11: Added tracing::debug! for skipped files in build_initial_snapshot
- moltis-org#12: Added 'drop to stop' documentation on CodeIndexWatcher::start()

32 tests pass, clippy clean.
Cstewart-HC added a commit to Cstewart-HC/moltis-mini that referenced this pull request Apr 16, 2026
Review fixes applied:
- #1: Extract require_str/opt_usize_or to moltis_tools::params — replaced
  local helpers with params::require_str() and params::u64_param() from
  the shared workspace crate
- #2: Unified error model — CodebaseSearchTool now returns
  Ok(json!({error:..., search_available: false})) for
  BackendUnavailable, matching Peek/Status pattern
- #3: u64→usize truncating cast replaced with usize::try_from().unwrap_or()
- #4: ensure_collections() error remapped from BackendUnavailable to
  IndexFailed { project_id, message }
- moltis-org#6: result.line as usize now clamped with .max(1) minimum
- moltis-org#7: compute_delta carries forward previous hash on hash errors so
  files aren't spuriously marked as removed
- moltis-org#8: Added doc comment noting that watcher batches may contain
  duplicate paths
- moltis-org#9: Extracted effective_extension() from filter.rs, removed
  duplication between filter.rs and watcher.rs
- moltis-org#11: Added tracing::debug! for skipped files in build_initial_snapshot
- moltis-org#12: Added 'drop to stop' documentation on CodeIndexWatcher::start()

32 tests pass, clippy clean.
Cstewart-HC added a commit to Cstewart-HC/moltis-mini that referenced this pull request Apr 16, 2026
Review fixes applied:
- #1: Extract require_str/opt_usize_or to moltis_tools::params — replaced
  local helpers with params::require_str() and params::u64_param() from
  the shared workspace crate
- #2: Unified error model — CodebaseSearchTool now returns
  Ok(json!({error:..., search_available: false})) for
  BackendUnavailable, matching Peek/Status pattern
- #3: u64→usize truncating cast replaced with usize::try_from().unwrap_or()
- #4: ensure_collections() error remapped from BackendUnavailable to
  IndexFailed { project_id, message }
- moltis-org#6: result.line as usize now clamped with .max(1) minimum
- moltis-org#7: compute_delta carries forward previous hash on hash errors so
  files aren't spuriously marked as removed
- moltis-org#8: Added doc comment noting that watcher batches may contain
  duplicate paths
- moltis-org#9: Extracted effective_extension() from filter.rs, removed
  duplication between filter.rs and watcher.rs
- moltis-org#11: Added tracing::debug! for skipped files in build_initial_snapshot
- moltis-org#12: Added 'drop to stop' documentation on CodeIndexWatcher::start()

32 tests pass, clippy clean.
Cstewart-HC added a commit to Cstewart-HC/moltis-mini that referenced this pull request Apr 16, 2026
Review fixes applied:
- #1: Extract require_str/opt_usize_or to moltis_tools::params — replaced
  local helpers with params::require_str() and params::u64_param() from
  the shared workspace crate
- #2: Unified error model — CodebaseSearchTool now returns
  Ok(json!({error:..., search_available: false})) for
  BackendUnavailable, matching Peek/Status pattern
- #3: u64→usize truncating cast replaced with usize::try_from().unwrap_or()
- #4: ensure_collections() error remapped from BackendUnavailable to
  IndexFailed { project_id, message }
- moltis-org#6: result.line as usize now clamped with .max(1) minimum
- moltis-org#7: compute_delta carries forward previous hash on hash errors so
  files aren't spuriously marked as removed
- moltis-org#8: Added doc comment noting that watcher batches may contain
  duplicate paths
- moltis-org#9: Extracted effective_extension() from filter.rs, removed
  duplication between filter.rs and watcher.rs
- moltis-org#11: Added tracing::debug! for skipped files in build_initial_snapshot
- moltis-org#12: Added 'drop to stop' documentation on CodeIndexWatcher::start()

32 tests pass, clippy clean.
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.

Add zizmor GitHub Actions security scanner and harden workflows

1 participant