Skip to content

Commit

Permalink
✨ cleanup for token doc and code (#552)
Browse files Browse the repository at this point in the history
* cleanup

* comment
  • Loading branch information
laurentsimon authored Jun 7, 2021
1 parent 28b1db9 commit 2c9a05c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 70 deletions.
11 changes: 2 additions & 9 deletions checks/checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,8 @@ This check looks for cryptographically signed tags in the last 5 tags. The check

## Token-Permissions

This check tries to determine if a project's GitHub workflows follow the principle of least privilege, i.e. if the GitHub tokens are set read-only by default. The check currently checks that the 'permission' keyword is used and set to read/none for the 'contents' permission for every workflow yaml file. If other permissions are set globally for the entire file, this check fails. Otherwise it succeeds.
This check tries to determine if a project's GitHub workflows follow the principle of least privilege, i.e. if the GitHub tokens are set read-only by default. For each workflow yaml file, the check looks for the permissions keyword. If it is set globally as read-only for the entire file, this check succeeds. Otherwise it fails. The check cannot detect if the "read-only" GitHub permission settings is enabled, as there is no API available.

**Remediation steps**
- Use: ``` permissions:
contents: read
``` in all your .yaml files.
- If you need more permissions, declare them in the job itself, e.g. ``` jobs: create_commit:
runs-on: ubuntu-latest
permissions:
issues: write
```
- Set permissions as `read-all` or `contents: read` as described in GitHub's [documentation](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#permissions).

25 changes: 6 additions & 19 deletions checks/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,14 @@ checks:
description: >-
This check tries to determine if a project's GitHub workflows
follow the principle of least privilege, i.e. if the GitHub tokens
are set read-only by default. The check currently checks that the 'permission'
keyword is used and set to read/none for the 'contents' permission for every workflow
yaml file. If other permissions are set globally for the entire file, this check fails.
Otherwise it succeeds.
are set read-only by default. For each workflow yaml file, the check looks
for the permissions keyword. If it is set globally as read-only for the entire file,
this check succeeds. Otherwise it fails. The check cannot detect if the "read-only"
GitHub permission settings is enabled, as there is no API available.
remediation:
- >-
Use:
```
permissions:
contents: read
```
in all your .yaml files.
- >-
If you need more permissions, declare them in the job itself, e.g.
```
jobs:
create_commit:
runs-on: ubuntu-latest
permissions:
issues: write
```
Set permissions as `read-all` or `contents: read` as described in
GitHub's [documentation](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#permissions).
Security-Policy:
description: >-
This check tries to determine if a project has published a security
Expand Down
71 changes: 29 additions & 42 deletions checks/permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,55 +79,42 @@ func validateMapPermissions(values map[interface{}]interface{}, path string,

func validateReadPermissions(config map[interface{}]interface{}, path string,
logf func(s string, f ...interface{})) (bool, error) {
permissionFound := false
permissionRead := true
var err error
var permissions interface{}

// Check if permissions are set explicitly.
permissions, ok := config["permissions"]
if !ok {
logf("!! token-permissions/github-token - no permission defined in %v", path)
return false, nil
}

// Iterate over the values.
for key, value := range config {
if key != "permissions" {
continue
// Check the type of our values.
switch val := permissions.(type) {
// Empty string is nil type.
// It defaults to 'none'
case nil:

// String type.
case string:
if !strings.EqualFold(val, "read-all") && val != "" {
logf("!! token-permissions/github-token - permission set to '%v' in %v", val, path)
return false, nil
}

// We have found the permissions keyword.
permissionFound = true

// Check the type of our values.
switch val := value.(type) {
// Empty string is nil type.
// It defaults to 'none'
case nil:

// String type.
case string:
if !strings.EqualFold(val, "read-all") && val != "" {
logf("!! token-permissions/github-token - permission set to '%v' in %v", val, path)
return false, nil
}

// Map type.
case map[interface{}]interface{}:
var res bool
if res, err = validateMapPermissions(val, path, logf); err != nil {
return false, err
}
if !res {
permissionRead = false
}

// Invalid type.
default:
return false, ErrInvalidGitHubWorkflowFile
// Map type.
case map[interface{}]interface{}:
if res, err := validateMapPermissions(val, path, logf); err != nil {
return false, err
} else if !res {
return false, nil
}
}

// Did we find a permission at all?
if !permissionFound {
logf("!! token-permissions/github-token - no permission defined in %v", path)
return false, nil
// Invalid type.
default:
return false, ErrInvalidGitHubWorkflowFile
}

return permissionRead, nil
return true, nil
}

// Check file content.
Expand Down

0 comments on commit 2c9a05c

Please sign in to comment.