-
Notifications
You must be signed in to change notification settings - Fork 7
ImplicitPersistCredentials and GlobalPermissionsBlock #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
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 adds two new security-focused rules for GitHub Actions workflows to help prevent credential leakage and over-permissioned jobs. Both rules address common security issues in CI/CD pipelines that could be exploited during supply chain attacks.
- Adds
ImplicitPersistCredentialsrule to flagactions/checkoutusage without explicitpersist-credentialssetting - Adds
GlobalPermissionsBlockrule to flag workflow-level permissions when multiple jobs exist - Introduces a new
dighelper function for traversing nested objects in rule expressions
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/claws/rule/implicit_persist_credentials.rb | Implements the ImplicitPersistCredentials rule using expression-based step checking |
| lib/claws/rule/global_permissions_block.rb | Implements the GlobalPermissionsBlock rule using custom workflow-level validation |
| spec/claws/rule/implicit_persist_credentials_spec.rb | Adds test coverage for the ImplicitPersistCredentials rule with positive and negative cases |
| spec/claws/rule/global_permissions_block_spec.rb | Adds test coverage for the GlobalPermissionsBlock rule with various job configurations |
| lib/claws/base_rule.rb | Adds the dig helper function and updates rubocop suppressions for complexity metrics |
| lib/claws/rule.rb | Registers the two new rules for loading |
| README.md | Documents both new rules with examples and security rationale |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| end | ||
| end |
Copilot
AI
Jan 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test suite is missing a test case for when persist-credentials is explicitly set to true. According to the documentation, explicitly setting it to true (when needed) is also a valid way to satisfy this rule. Add a test case to verify that persist-credentials: true does not trigger a violation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| YAML | ||
|
|
||
| expect(violations.count).to eq(1) | ||
| expect(violations[0].line).to eq(8) |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The line number expectation appears incorrect. Looking at the YAML structure, the uses: actions/checkout@v6 statement is on line 76 of the YAML, but the test expects the violation to be on line 8. This seems to be checking the wrong line number - should verify the line numbering matches where the violation actually occurs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😑
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| ### GlobalPermissionsBlock | ||
|
|
||
| [The permissions block](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#permissions) dictates which permissions a workflow or a job have or don't have. When permissions are defined at the workflow level, each job gets the same set of permissions, potentially giving more access than a job or a step truly needs. Instead, permissions should be defined at the job level, making sure each job and step has access only to the permissions it needs. This can minimize the impact of untrusted code using an overly permissive `$GITHUB_TOKEN`, such as during a supply chain attack. |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation URL appears to use an older or incorrect path structure. Based on other GitHub Actions documentation links in this file (e.g., line 304), the URL should likely be https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#permissions instead of using the /actions/reference/workflows-and-actions/ path.
| [The permissions block](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#permissions) dictates which permissions a workflow or a job have or don't have. When permissions are defined at the workflow level, each job gets the same set of permissions, potentially giving more access than a job or a step truly needs. Instead, permissions should be defined at the job level, making sure each job and step has access only to the permissions it needs. This can minimize the impact of untrusted code using an overly permissive `$GITHUB_TOKEN`, such as during a supply chain attack. | |
| [The permissions block](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#permissions) dictates which permissions a workflow or a job have or don't have. When permissions are defined at the workflow level, each job gets the same set of permissions, potentially giving more access than a job or a step truly needs. Instead, permissions should be defined at the job level, making sure each job and step has access only to the permissions it needs. This can minimize the impact of untrusted code using an overly permissive `$GITHUB_TOKEN`, such as during a supply chain attack. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the suggested url literally redirects to my url. what r u doin
btrautmann
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awesome! Very clean PR, easy to review/follow
domain lgtm
rdadlani
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well explained, well documented. tests make it really clear what's happening. love it. domain lgtm. 💪 nice work.
|
/no-platform |
Backfilling two rules. Normally I'd do separate PRs for each rule, but they're both small enough that I don't think it'll be an issue to review.
actions/checkoutwherepersist-credentialsis not explicitly set. Not setting it means we fall back to the default value oftrue(valid for versions v2 to v6 (current at the time)). This will cause the action to write these temporary credentials to~/.git/configor a temporary directory, where it can be found by malicious code and used by an attacker from an external system to gain access to the repository being cloned or even other repositories./task https://betterconfluence.atlassian.net/browse/SEC-385
/task https://betterconfluence.atlassian.net/browse/SEC-390
Both of these flagged behaviors are unfortunately pretty common, so we will need to be particular about the upgrade process here.