Skip to content

Scope Java CI token permissions to least privilege - #153

Merged
SibeiC merged 1 commit into
masterfrom
chore/tighten-ci-permissions
Jul 16, 2026
Merged

SibeiC merged 1 commit into
masterfrom
chore/tighten-ci-permissions

Conversation

@SibeiC

@SibeiC SibeiC commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Follow-up to 2f38800, which removed the redundant Update dependency graph step.

Why

maven.yml granted four write scopes to every job:

permissions:
  contents: write
  packages: write
  id-token: write
  security-events: write

Auditing what the workflow actually does:

  • id-token: write — nothing uses OIDC (no cloud login, no keyless signing). The cache-to: type=gha in build-push-action uses the Actions runtime token, not OIDC.
  • security-events: write — nothing uploads SARIF here. Code scanning lives in the separate CodeQL and Qodana workflows, which carry their own permissions.
  • contents: write — was only needed by the dependency-graph submission step removed in 2f38800. Nothing left creates a release, or pushes a commit or tag. (Extract version runs mvn versions:set locally and never pushes.)
  • packages: write — genuinely needed, but only by docker, for the GHCR login and image push.

Change

Default to contents: read, and let docker opt into the packages: write it needs.

job effective permissions
ci-test contents: read (inherited)
docker contents: read, packages: write (job-level)
deploy contents: read (inherited)

The docker job's GHCR-relevant grant is unchanged — it had packages: write from the top-level block before and has it explicitly now.

Verification

  • actionlint is clean (same 4 pre-existing shellcheck info notes as before this change).
  • Effective per-job permissions confirmed by parsing the resolved YAML.
  • Pre-push hook: 69 tests, 0 failures.

⚠️ Coverage limit: only ci-test runs on a PR — docker and deploy are gated on refs/tags/. So a green check here validates ci-test under contents: read, but the docker job's packages: write is not exercised until the next release tag. Each job only reads repo contents via actions/checkout, so the reduction to contents: read is safe by inspection.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NJNZN4SSHVBz3oHYox8x1p

The workflow granted contents/packages/id-token/security-events write to
every job. Nothing in it creates a release, pushes a commit or tag, uploads
SARIF, or uses OIDC, so id-token and security-events were never needed, and
contents:write was only required by the dependency-graph submission step
removed in 2f38800.

Default to contents:read and let the docker job opt into the packages:write
it needs for the GHCR login and image push. Effective GHCR permissions for
that job are unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJNZN4SSHVBz3oHYox8x1p
Copilot AI review requested due to automatic review settings July 16, 2026 07:40

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 tightens the GitHub Actions token permissions in the Java Maven CI workflow to follow least-privilege defaults, while preserving the specific write scope needed for pushing Docker images to GHCR.

Changes:

  • Reduced workflow-level permissions from multiple write scopes to contents: read.
  • Added job-level permissions for the docker job to explicitly grant packages: write (and retain contents: read).

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

@github-actions

Copy link
Copy Markdown

Qodana for JVM

It seems all right 👌

No new problems were found according to the checks applied

💡 Qodana analysis was run in the pull request mode: only the changed files were checked
☁️ View the detailed Qodana report

Contact Qodana team

Contact us at qodana-support@jetbrains.com

@SibeiC
SibeiC merged commit 5c34729 into master Jul 16, 2026
11 checks passed
@SibeiC
SibeiC deleted the chore/tighten-ci-permissions branch July 16, 2026 07:44
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