├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── action.yml ├── entrypoint.sh └── tfsec.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Go template 3 | # Binaries for programs and plugins 4 | *.exe 5 | *.exe~ 6 | *.dll 7 | *.so 8 | *.dylib 9 | 10 | # Test binary, built with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # Dependency directories (remove the comment below to include it) 17 | # vendor/ 18 | 19 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.16 2 | 3 | RUN apk --no-cache --update add \ 4 | bash \ 5 | curl \ 6 | git \ 7 | jq \ 8 | && rm -rf /var/cache/apk/* 9 | 10 | COPY entrypoint.sh /entrypoint.sh 11 | 12 | ENTRYPOINT ["/entrypoint.sh"] 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Liam Galvin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | # tfsec-action 6 | Run tfsec as a GitHub action with configurable output 7 | 8 | To add the action, add `tfsec.yml` into the `.github/workflows` directory in the root of your Github project. 9 | 10 | The contents of `tfsec.yml` should be; 11 | 12 | ```yaml 13 | name: tfsec 14 | on: 15 | push: 16 | branches: 17 | - main 18 | pull_request: 19 | jobs: 20 | tfsec: 21 | name: tfsec 22 | runs-on: ubuntu-latest 23 | 24 | steps: 25 | - name: Clone repo 26 | uses: actions/checkout@master 27 | - name: tfsec 28 | uses: aquasecurity/tfsec-action@v1.0.0 29 | ``` 30 | 31 | Run tfsec as part of a GitHub Action flow. Optionally prevent the failure of tfsec from breaking the build or pass additional arguments using `additional_args`. 32 | 33 | ## Optional inputs 34 | 35 | There are a number of optional inputs that can be used in the `with:` block. 36 | 37 | **working_directory** - the directory to scan in, defaults to `.`, ie current working directory 38 | 39 | **version** - the version of tfsec to use, defaults to `latest` 40 | 41 | **format** - Default format can be overridden to any of the following - [json,csv,checkstyle,junit,sarif] 42 | 43 | **additional_args** - any additional arguments you want to have passed to tfsec 44 | 45 | **soft_fail** - set to `true` if you dont want the action to break the build 46 | 47 | **github_token** - a GitHub token to be used when calling the GitHub API, which helps in avoiding rate-limiting 48 | 49 | ### tfsec_vars 50 | 51 | `tfsec` provides an [extensive number of arguments](https://aquasecurity.github.io/tfsec/v0.63.1/getting-started/usage/) which can be passed through as in the example below; 52 | 53 | ```yaml 54 | name: tfsec 55 | on: 56 | push: 57 | branches: 58 | - main 59 | pull_request: 60 | jobs: 61 | tfsec: 62 | name: tfsec 63 | runs-on: ubuntu-latest 64 | 65 | steps: 66 | - name: Clone repo 67 | uses: actions/checkout@master 68 | - name: tfsec 69 | uses: aquasecurity/tfsec-action@v1.0.0 70 | with: 71 | soft_fail: true 72 | 73 | ``` 74 | 75 | ## Open Source Attribution 76 | 77 | - bash: [GPL 3.0 or later](https://www.gnu.org/licenses/gpl-3.0.html) 78 | - curl: [curl license](https://curl.se/docs/copyright.html) 79 | - git: [GPL 2.0 or later](https://github.com/git/git/blob/master/COPYING) 80 | - jq: [MIT](https://github.com/stedolan/jq/blob/master/COPYING) 81 | 82 | ## License 83 | 84 | [MIT License](https://github.com/nkuik/tfsec-action/blob/master/LICENSE) 85 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: "tfsec action" 2 | description: "Runs tfsec and outputs any failures" 3 | author: "owen.rumney@aquasec.com" 4 | 5 | inputs: 6 | working_directory: 7 | required: false 8 | description: | 9 | Directory to run the action on, from the repo root. 10 | Default is . (root of the repository) 11 | default: "." 12 | version: 13 | required: false 14 | description: The version of tfsec to use, defaults to latest 15 | default: latest 16 | format: 17 | required: false 18 | description: the format of the output 19 | default: default 20 | additional_args: 21 | required: false 22 | description: | 23 | Space separated args specified here will be added during tfsec execution. 24 | (eg. --force-all-dirs --verbose) 25 | soft_fail: 26 | required: false 27 | description: If set to `true` the action step won't break the build 28 | github_token: 29 | description: | 30 | GitHub token used for making authenticated requests to the GitHub API, 31 | which helps avoid rate limiting 32 | required: false 33 | outputs: 34 | tfsec-return-code: 35 | description: "tfsec command return code" 36 | runs: 37 | using: "docker" 38 | image: "Dockerfile" 39 | branding: 40 | icon: "git-pull-request" 41 | color: "purple" 42 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -xe 4 | 5 | if [ -z "${INPUT_GITHUB_TOKEN}" ] ; then 6 | echo "::notice title=GitHub API token::Consider setting a GITHUB_TOKEN to prevent GitHub api rate limits" 7 | fi 8 | 9 | TFSEC_VERSION="" 10 | if [ "$INPUT_VERSION" != "latest" ] && [ -n "$INPUT_VERSION" ]; then 11 | TFSEC_VERSION="tags/${INPUT_VERSION}" 12 | else 13 | TFSEC_VERSION="latest" 14 | fi 15 | 16 | function get_release_assets() { 17 | repo="$1" 18 | version="$2" 19 | args=( 20 | -sSL 21 | --header "Accept: application/vnd.github+json" 22 | ) 23 | [ -n "${INPUT_GITHUB_TOKEN}" ] && args+=(--header "Authorization: Bearer ${INPUT_GITHUB_TOKEN}") 24 | 25 | if ! curl --fail-with-body -sS "${args[@]}" "https://api.github.com/repos/${repo}/releases/${version}"; then 26 | echo "::error title=GitHub API request failure::The request to the GitHub API was likely rate-limited. Set a GITHUB_TOKEN to prevent this" 27 | exit 1 28 | else 29 | curl "${args[@]}" "https://api.github.com/repos/${repo}/releases/${version}" | jq '.assets[] | { name: .name, download_url: .browser_download_url }' 30 | fi 31 | } 32 | 33 | function install_release() { 34 | repo="$1" 35 | version="$2" 36 | binary="$3-linux-amd64" 37 | checksum="$4" 38 | release_assets="$(get_release_assets "${repo}" "${version}")" 39 | 40 | curl -sLo "${binary}" "$(echo "${release_assets}" | jq -r ". | select(.name == \"${binary}\") | .download_url")" 41 | curl -sLo "$3-checksums.txt" "$(echo "${release_assets}" | jq -r ". | select(.name | contains(\"$checksum\")) | .download_url")" 42 | 43 | grep "${binary}" "$3-checksums.txt" | sha256sum -c - 44 | install "${binary}" "/usr/local/bin/${3}" 45 | } 46 | 47 | install_release aquasecurity/tfsec "${TFSEC_VERSION}" tfsec tfsec_checksums.txt 48 | 49 | if [ -n "${GITHUB_WORKSPACE}" ]; then 50 | cd "${GITHUB_WORKSPACE}" || exit 51 | fi 52 | 53 | if [ -n "${INPUT_ADDITIONAL_ARGS}" ]; then 54 | TFSEC_ARGS_OPTION="${INPUT_ADDITIONAL_ARGS}" 55 | fi 56 | 57 | if [ -n "${INPUT_SOFT_FAIL}" ]; then 58 | SOFT_FAIL="--soft-fail" 59 | fi 60 | 61 | FORMAT=${INPUT_FORMAT:-default} 62 | 63 | tfsec --format="${FORMAT}" ${SOFT_FAIL} ${TFSEC_ARGS_OPTION} "${INPUT_WORKING_DIRECTORY}" 64 | -------------------------------------------------------------------------------- /tfsec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aquasecurity/tfsec-action/b466648d6e39e7c75324f25d83891162a721f2d6/tfsec.png --------------------------------------------------------------------------------