Skip to content

fix(ci): add least-privilege permissions to workflow files#2944

Open
waveywaves wants to merge 1 commit intochainloop-dev:mainfrom
waveywaves:fix/scorecard-token-permissions
Open

fix(ci): add least-privilege permissions to workflow files#2944
waveywaves wants to merge 1 commit intochainloop-dev:mainfrom
waveywaves:fix/scorecard-token-permissions

Conversation

@waveywaves
Copy link
Copy Markdown
Contributor

@waveywaves waveywaves commented Mar 27, 2026

Summary

Add top-level permissions blocks to workflow files following the two-tier permission pattern recommended by OpenSSF Scorecard. This tightens the default GITHUB_TOKEN scope so that each job only receives the permissions it explicitly declares.

Changes

  • stale.yml: added permissions: {} at workflow level (job-level issues: write + pull-requests: write already correct)
  • build_external_container_images.yaml: moved packages: write from workflow level to job level; set workflow level to permissions: { contents: read }
  • codeql.yml: removed id-token: write from workflow level (kept contents: read); job level already has id-token: write

Full 12-Workflow Audit

# Workflow file Workflow-level permissions Status
1 author_verification.yml read-all Already compliant
2 build_external_container_images.yaml contents: read (was also packages: write) Fixed - moved packages: write to job level
3 codeql.yml contents: read (was also id-token: write) Fixed - removed id-token: write; job already declares it
4 lint.yml contents: read, pull-requests: read Already compliant (read-only)
5 package_chart.yaml read-all Already compliant (job has packages: write + id-token: write)
6 release.yaml read-all Already compliant (jobs declare write perms as needed)
7 scm_configuration_check.yaml read-all Already compliant
8 scorecards.yml read-all Already compliant
9 secrets-scan-daily.yml read-all Already compliant
10 stale.yml {} (was missing entirely) Fixed - added empty block with comment; job has issues: write + pull-requests: write
11 sync_contracts.yml read-all Already compliant
12 test.yml contents: read Already compliant (read-only)

Result: 3 workflows fixed, 9 were already compliant. All 12 workflow files now follow the least-privilege two-tier pattern.

Test Plan

  • Verify stale.yml workflow runs correctly (cron or manual dispatch) with the new top-level permissions: {}
  • Verify build_external_container_images.yaml workflow can still build and push container images with packages: write now at job level
  • Verify codeql.yml workflow still generates SLSA provenance with id-token: write only at job level
  • Re-run OpenSSF Scorecard to confirm the Token-Permissions check score improves (currently flagged in issue Fix OpenSSF Scorecard token-permissions check (currently 0/10) #2841)

Fixes #2841

@waveywaves waveywaves force-pushed the fix/scorecard-token-permissions branch 2 times, most recently from 3da776c to dcdd23f Compare March 28, 2026 04:15
@waveywaves waveywaves marked this pull request as ready for review March 31, 2026 12:57
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 4 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="pkg/attestation/crafter/collector_aiagentconfig.go">

<violation number="1" location="pkg/attestation/crafter/collector_aiagentconfig.go:105">
P1: Deterministic file name in `/tmp` replaces `CreateTemp`, introducing predictable temp-file path risk (pre-creation/symlink attack surface).</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

tmpFile.Close()
// Use a deterministic filename based on the config hash so that retries
// produce the same file path and avoid duplicate CAS uploads.
tmpPath := filepath.Join(os.TempDir(), fmt.Sprintf("ai-agent-config-%s-%s.json", agentName, data.ConfigHash[:12]))
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Mar 31, 2026

Choose a reason for hiding this comment

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

P1: Deterministic file name in /tmp replaces CreateTemp, introducing predictable temp-file path risk (pre-creation/symlink attack surface).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At pkg/attestation/crafter/collector_aiagentconfig.go, line 105:

<comment>Deterministic file name in `/tmp` replaces `CreateTemp`, introducing predictable temp-file path risk (pre-creation/symlink attack surface).</comment>

<file context>
@@ -99,20 +100,16 @@ func (c *AIAgentConfigCollector) uploadAgentConfig(
-		tmpFile.Close()
+	// Use a deterministic filename based on the config hash so that retries
+	// produce the same file path and avoid duplicate CAS uploads.
+	tmpPath := filepath.Join(os.TempDir(), fmt.Sprintf("ai-agent-config-%s-%s.json", agentName, data.ConfigHash[:12]))
+	if err := os.WriteFile(tmpPath, jsonData, 0o600); err != nil {
 		return fmt.Errorf("writing temp file: %w", err)
</file context>
Fix with Cubic

@waveywaves waveywaves force-pushed the fix/scorecard-token-permissions branch from dcdd23f to 96bcd23 Compare March 31, 2026 13:16
Add top-level permissions blocks following the two-tier permission
pattern recommended by OpenSSF Scorecard:

- stale.yml: add `permissions: {}` at workflow level (job already has
  issues: write + pull-requests: write)
- build_external_container_images.yaml: move `packages: write` from
  workflow level to job level; set workflow level to `permissions: read-all`

scm_configuration_check.yaml already had `permissions: read-all` at
workflow level so no change was needed.

Fixes chainloop-dev#2841

Signed-off-by: Vibhav Bobade <vibhav.bobde@gmail.com>
@waveywaves waveywaves force-pushed the fix/scorecard-token-permissions branch from 96bcd23 to a5f8adc Compare March 31, 2026 13:25
@waveywaves
Copy link
Copy Markdown
Contributor Author

@jiparis @migmartri gentle ping — this is ready for review. All CI green. Adds least-privilege permissions to 3 workflow files (stale, build_external_container_images, codeql). Full 12-workflow audit in the PR description.

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.

Fix OpenSSF Scorecard token-permissions check (currently 0/10)

1 participant