Skip to content

ci: add permissions block and make security checks blocking - #145

Merged
lhoupert merged 16 commits into
mainfrom
security/permissions-and-blocking-checks
Mar 30, 2026
Merged

lhoupert merged 16 commits into
mainfrom
security/permissions-and-blocking-checks

Conversation

@lhoupert

@lhoupert lhoupert commented Mar 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Part of the supply-chain security hardening tracked in EOPF-Explorer/coordination#239.

  • Fix bandit scan path — was scanning eopf_geozarr/ (missing src/ prefix), producing empty reports
  • Both tools always run — bandit uses continue-on-error: true so pip-audit is never skipped when bandit finds issues
  • pip-audit outputs JSON — pip-audit -f json -o pip-audit-report.json for structured parsing
  • Severity-based blocking thresholds:
    • bandit: only HIGH severity issues are blocking; MEDIUM/LOW are reported but non-blocking
    • pip-audit: only vulnerabilities with a known fix version are blocking; unfixable CVEs are non-blocking warnings
  • PR comment with security report — posted directly on the PR on every run, updated in place (marker-based upsert via gh api to avoid duplicate comments); shows HIGH issues in a detail table, directs to artifact for lower-severity findings
  • GitHub Actions step summary — same report also written to the job summary tab
  • Python scripts extracted — inline scripts moved to .github/scripts/security_summary.py and .github/scripts/security_check.py for linting and formatting
  • pull-requests: write permission added to the security job (job-level, not workflow-level)
  • Both JSON reports uploaded as security-reports artifact (bandit + pip-audit)

Test plan

  • CI passes on this branch (bandit and pip-audit both exit 0 for this codebase)
  • bandit scans src/eopf_geozarr/ correctly — no more empty report error
  • pip-audit always runs regardless of bandit outcome
  • PR comment is posted/updated on each push to the PR
  • HIGH bandit issues → job fails; MEDIUM/LOW → job passes with informational output
  • pip-audit fixable vulns → job fails; no-fix vulns → job passes with warning
  • Artifact contains both bandit-report.json and pip-audit-report.json

🤖 Generated with Claude Code

lhoupert and others added 7 commits March 26, 2026 11:23
- Add permissions: contents: read to ci.yml (least-privilege GITHUB_TOKEN)
- Replace safety with pip-audit (open-source, uses OSV database)
- Split security checks into separate blocking steps (remove || true)
- Upload bandit report with if: always() for visibility on failures

Part of EOPF-Explorer/coordination#239
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@lhoupert
lhoupert requested a review from d-v-b March 26, 2026 13:04
Comment thread .github/workflows/ci.yml Outdated
continue-on-error: true

- name: Run pip-audit (dependency vulnerability scan)
run: pip-audit -f json -o pip-audit-report.json

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.

which dependencies is this auditing? Because I don't think the package is installed at this point in the workflow, so maybe you need to point this at a lockfile? or install the package first.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thank you! a key issue indeed! will raise a fix to make sure we export the list from the lockfile

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

it should be fixed now @d-v-b What do you think? I am using uv export --no-dev --no-emit-project --format requirements-txt to export the dependencies of the project

Comment thread .github/scripts/security_check.py Outdated
return bool(high)


def check_pip_audit() -> bool:

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I looked but it can't replicate fixable-only blocking.

Comment thread .github/scripts/security_check.py Outdated
from pathlib import Path


def check_bandit() -> bool:

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

it would be great but they are not supporting full-length commit SHAs yet. I raised an issue 🤞

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Issue is here: PyCQA/bandit-action#28 . I created a fork with the fix. It's the action I pinned. Is it acceptable? @d-v-b , I can maybe open an issue on the repo to keep track of this?

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.

yeah that's great!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I am in the process of creating an action for this. I think it will be better so it can easily be reuse in various project. Will update the project with the dependencies when it is done. I may ask also to get it transfered to developmentseed org

Use the official PyCQA/bandit-action (v1.0.1, pinned to SHA) instead of
running bandit manually and post-processing JSON output. Setting level: high
preserves the existing policy (only HIGH severity blocks CI); MEDIUM/LOW
findings now appear in the GitHub Security tab via SARIF instead of the PR
comment.

pip-audit and its fixable-only blocking logic are unchanged, as
gh-action-pip-audit cannot replicate that behaviour natively.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@lhoupert
lhoupert marked this pull request as draft March 27, 2026 00:34
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@lhoupert
lhoupert marked this pull request as ready for review March 27, 2026 09:40
@EOPF-Explorer EOPF-Explorer deleted a comment from github-actions Bot Mar 30, 2026
@EOPF-Explorer EOPF-Explorer deleted a comment from github-actions Bot Mar 30, 2026
@lhoupert
lhoupert merged commit 25c6ebc into main Mar 30, 2026
5 checks passed
@github-actions github-actions Bot mentioned this pull request Mar 25, 2026
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.

3 participants