README
¶
ghalint
GitHub Actions linter
Policies
job_permissions: All jobs should havepermissions- Why: For least privilege
- Exceptions
- workflow's
permissionsis empty{} - workflow has only one job and the workflow has
permissions
- workflow's
deny_read_all_permission:read-allpermission should not be used- Why: For least privilege
deny_write_all_permission:write-allpermission should not be used- Why: For least privilege
workflow_secrets: Workflow should not set secrets to environment variables- How to fix: set secrets to jobs
- Why: To limit the scope of secrets
- Exceptions
- workflow has only one job
job_secrets: Job should not set secrets to environment variables- How to fix: set secrets to steps
- Why: To limit the scope of secrets
- Exceptions
- job has only one step
job_permissions
❌
permissions:
contents: read
jobs:
foo:
runs-on: ubuntu-latest
# Without permissions
steps:
- run: echo hello
bar:
runs-on: ubuntu-latest
# Without permissions
steps:
- uses: actions/checkout@v3
⭕
jobs:
foo:
runs-on: ubuntu-latest
permissions: {} # Set permissions
steps:
- run: echo hello
bar:
runs-on: ubuntu-latest
permissions: # Set permissions
contents: read
steps:
- uses: actions/checkout@v3
Or
permissions: {} # empty permissions
jobs:
foo:
runs-on: ubuntu-latest
steps:
- run: echo hello
bar:
runs-on: ubuntu-latest
permissions: # Set permissions
contents: read
steps:
- uses: actions/checkout@v3
deny_read_all_permission
❌
name: test
jobs:
foo:
runs-on: ubuntu-latest
permissions: read-all # Don't use read-all
steps:
- run: echo foo
⭕
name: test
jobs:
foo:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- run: echo foo
deny_write_all_permission
Same with deny_read_all_permission.
workflow_secrets
❌
name: test
env:
GITHUB_TOKEN: ${{github.token}}
DATADOG_API_KEY: ${{secrets.DATADOG_API_KEY}}
jobs:
foo:
runs-on: ubuntu-latest
permissions: {}
steps:
- run: echo foo
bar:
runs-on: ubuntu-latest
permissions: {}
steps:
- run: echo bar
⭕
name: test
jobs:
foo:
runs-on: ubuntu-latest
permissions: {}
env:
GITHUB_TOKEN: ${{github.token}}
steps:
- run: echo foo
bar:
runs-on: ubuntu-latest
permissions: {}
env:
DATADOG_API_KEY: ${{secrets.DATADOG_API_KEY}}
steps:
- run: echo bar
job_secrets
❌
jobs:
foo:
runs-on: ubuntu-latest
permissions:
issues: write
env:
GITHUB_TOKEN: ${{github.token}} # secret is set in job
steps:
- run: echo foo
- run: gh label create bug
⭕
jobs:
foo:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- run: echo foo
- run: gh label create bug
env:
GITHUB_TOKEN: ${{github.token}} # secret is set in step
How to install
- Download a pre-built binary from GitHub Releases and locate an executable binary
ghalintinPATH - Homebrew:
brew install suzuki-shunsuke/ghalint/ghalint - aqua:
aqua g -i suzuki-shunsuke/ghalint
How to use
$ ghalint run
$ ghalint run
ERRO[0000] read a workflow file error="parse a workflow file as YAML: yaml: line 10: could not find expected ':'" program=ghalint version= workflow_file_path=.github/workflows/release.yaml
ERRO[0000] github.token should not be set to workflow's env env_name=GITHUB_TOKEN policy_name=workflow_secrets program=ghalint version= workflow_file_path=.github/workflows/test.yaml
ERRO[0000] secret should not be set to workflow's env env_name=DATADOG_API_KEY policy_name=workflow_secrets program=ghalint version= workflow_file_path=.github/workflows/test.yaml
Configuration file
Configuration file path: ^\.?ghalint\.ya?ml$
You can exclude the policy job_secrets.
e.g.
excludes:
- policy_name: job_secrets
workflow_file_path: .github/workflows/actionlint.yaml
job_name: actionlint
- policy_name: Only
job_secretsis supported
Environment variables
GHALINT_LOG_COLOR: Configure log color. One ofauto(default),always, andnever.
💡 If you want to enable log color in GitHub Actions, please try GHALINT_LOG_COLOR=always
env:
GHALINT_LOG_COLOR: always
AS IS
TO BE
How does it works?
ghalint reads GitHub Actions Workflows ^\.github/workflows/.*\.ya?ml$ and validates them.
If there are violatation ghalint outputs error logs and fails.
If there is no violation ghalint succeeds.
Why not actionlint?
We develop ghalint to support our policies that actionlint doesn't cover.
We don't aim to replace actionlint to ghalint. We use both actionlint and ghalint.
LICENSE
Click to show internal directories.
Click to hide internal directories.