Skip to content

drewbernetes/container-security-action

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Container Security Scan 🔒

Description

Generally speaking when scanning a container you should generate an SBOM and then scan the resulting image to ensure you know exactly what vulnerabilities exist within the image and any packages used within it.

This action enables that process. On top of that, it signs the image with Sigstore Cosign so that you can validate the image and be confident the one you're using is the one you built, as you built it.

Whilst nothing can catch everything, this gives a decent view of what is going on within an image.

Why?

Some container registries provide scanning and signing support as part and parcel of their service. However, some do not. This action provides consistency and enables the scanning and signing of your containers during the build process, not after the push.

Scanning with Grype

Grype is used to scan the images and a [.grype.yaml](https://github.com/anchore/grype#specifying-matches-to-ignore) file can be supplied to ignore certain CVEs if desired.

If you wish to use a .grype.yaml file, then you can store it in the repo that calls this action. Make sure you run actions/checkout@v4 before calling this action and pass the grypeignore-file input parameter. It will automatically be used if the S3 option isn't explicitly enabled.

For example:

steps:
  - name: Checkout Repo
    uses: actions/checkout@v4
    - name: Build, Scan and Sign Image
      uses: drewbernetes/[email protected]
      with:
        image-repo: "drewviles"
        repo-username: < secrets.DOCKER_USER >
        repo-password: < secrets.DOCKER_PASSWORD >
        image-name: "csa-demo"
        image-tag: "1.0"
        check-severity: "HIGH,CRITICAL"
        grypeignore-file: "grypeignore"
        add-latest-tag: "true"
        publish-image: "true"
        cosign-private-key: < secrets.COSIGN_KEY >
        cosign-password: < secrets.COSIGN_PASSWORD >
        cosign-tlog: false
        dockerfile-path: .

If you wish to use the S3 approach, to prevent constantly pushing updated grypeignore files to the source repo, then you can supply the following:

steps:
  - name: Build, Scan and Sign Image
    uses: drewbernetes/[email protected]
    with:
      image-repo: "your-registry.example.com/some-project"
      repo-username: < secrets.REGISTRY_PUBLIC_USER >
      repo-password: < secrets.REGISTRY_PUBLIC_PASSWORD >
      image-name: "csa-demo"
      image-tag: "1.0"
      check-severity: "MEDIUM,HIGH,CRITICAL"
      grypeignore-from-s3: true
      s3-endpoint: "https://s3.example.com"
      s3-access-key: < secrets.S3_ACCESS_KEY >
      s3-secret-key: < secrets.S3_SECRET_KEY >
      s3-bucket: "grypeignores"
      s3-path: "image-ignorefile"
      add-latest-tag: "false"
      publish-image: "true"
      cosign-private-key: < secrets.COSIGN_KEY >
      cosign-password: < secrets.COSIGN_PASSWORD >
      cosign-tlog: true
      dockerfile-path: .

If you also supply the grypeignore-file input when using the above, then this will be used as the resulting filename when the grypeignore file is pulled from s3. It won't use any file in the source repo as S3 overrides local grypeignore files.

Signing images with Cosign

The Cosign image signing works by using the standard process used by Cosign. You will need to generate the Cosign keys as described in their documentation and store these as a secret in GitHub. This can then be supplied via the cosign-private-key and cosign-password inputs.

Publishing Results

The result of the scan will be uploaded as artifacts within the repo however, if you have it enabled, you can have this pushed to the GitHub Dependency graph instead by adding the following input parameters:

enable-dependency-graph: true
github-token: < secrets.GITHUB_TOKEN >

Hardware token verification is currently not supported.

TODO (AKA nice to haves but may not come!):

  • Support dynamic key generation for Cosign.
  • Support OIDC cosign signing.
  • Support adding to Rekor (currently does not do this by default to prevent any private images being added when the user may not want this to happen)

Usage

- uses: <baski-action>@<v0.0.4>
  with:
    image-repo:
    # The repo to push the image to. This should just be the base url, eg: my-repo or ghcr.io or, if using DockerHub, just the username you'd usually use for your repo.
    #
    # Required: true
    # Default: ""

    repo-username:
    # The username to log into the repo.
    #
    # Required: true
    # Default: ""

    repo-password:
    # The password to log into the repo.
    #
    # Required: true
    # Default: ""

    image-name:
    # The name of the image to build.
    #
    # Required: true
    # Default: ""

    image-tag:
    # The tag to build the image with - provide a matrix to build against multiple tags as each will need to be SBOM'd, scanned and signed independently.
    #
    # Required: true
    # Default: ""

    add-latest-tag:
    # Adds the latest tag to the build.
    #
    # Required: false
    # Default: false

    cosign-private-key:
    # A private key with which to sign the image using cosign.
    #
    # Required: true
    # Default: ""

    cosign-password:
    # The password to unlock the private key.
    #
    # Required: true
    # Default: ""

    cosign-tlog:
    # Set to true to upload to tlog for transparency.
    #
    # Required: false
    # Default: false

    publish-image:
    # If true the image will be published to the repo.
    #
    # Required: false
    # Default: false

    check-severity:
    # A comma delimited (uppercase) list of severities to check for. If found the pipeline will fail. Support values: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
    #
    # Required: false
    # Default: high

    severity-fail-on-detection:
    # Whether or not to fail the build should a 'check-severity' level vulnerability be found.
    #
    # Required: false
    # Default: true

    grypeignore-file:
    # Supply a Grype ignore file to ignore specific CVEs and prevent a pipeline failure.
    #
    # Required: false
    # Default: .grype.yaml

    grypeignore-from-s3:
    # If disabled, the Grype ignore can be supplied via the repo itself but actions/checkout@v4 must be used before calling this action.
    #
    # Required: false
    # Default: false

    enable-dependency-graph:
    # Will upload the SBOM to GitHub Dependency Graph - you must enable this and enable write permissions on your workflow for this to work.
    #
    # Required: false
    # Default: false

    github-token:
    # This can be a PAT or the GITHUB_TOKEN secret
    #
    # Required: true
    # Default: ""

    s3-endpoint:
    # If the endpoint isn't a standard AWS one, pass it in here.
    #
    # Required: false
    # Default: https://some-s3-endpoint.com

    s3-region:
    # The AWS Region.
    #
    # Required: false
    # Default: us-east-1

    s3-access-key:
    # The S3 access key.
    #
    # Required: false
    # Default: ""

    s3-secret-key:
    # The S3 secret key.
    #
    # Required: false
    # Default: ""

    s3-bucket:
    # The S3 bucket in which the grype ignore file is stored.
    #
    # Required: false
    # Default: grypeignores

    s3-path:
    # The path in the s3 bucket to the grype ignore file.
    #
    # Required: false
    # Default: .grype.yaml

    dockerfile-path:
    # Path to the Dockerfile (default {context}/Dockerfile).
    #
    # Required: false
    # Default: .

Inputs

name description required default
image-repo

The repo to push the image to. This should just be the base url, eg: my-repo or ghcr.io or, if using DockerHub, just the username you'd usually use for your repo.

true ""
repo-username

The username to log into the repo.

true ""
repo-password

The password to log into the repo.

true ""
image-name

The name of the image to build.

true ""
image-tag

The tag to build the image with - provide a matrix to build against multiple tags as each will need to be SBOM'd, scanned and signed independently.

true ""
add-latest-tag

Adds the latest tag to the build.

false false
cosign-private-key

A private key with which to sign the image using cosign.

true ""
cosign-password

The password to unlock the private key.

true ""
cosign-tlog

Set to true to upload to tlog for transparency.

false false
publish-image

If true the image will be published to the repo.

false false
check-severity

A comma delimited (uppercase) list of severities to check for. If found the pipeline will fail. Support values: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL

false high
severity-fail-on-detection

Whether or not to fail the build should a 'check-severity' level vulnerability be found.

false true
grypeignore-file

Supply a Grype ignore file to ignore specific CVEs and prevent a pipeline failure.

false .grype.yaml
grypeignore-from-s3

If disabled, the Grype ignore can be supplied via the repo itself but actions/checkout@v4 must be used before calling this action.

false false
enable-dependency-graph

Will upload the SBOM to GitHub Dependency Graph - you must enable this and enable write permissions on your workflow for this to work.

false false
github-token

This can be a PAT or the GITHUB_TOKEN secret

true ""
s3-endpoint

If the endpoint isn't a standard AWS one, pass it in here.

false https://some-s3-endpoint.com
s3-region

The AWS Region.

false us-east-1
s3-access-key

The S3 access key.

false ""
s3-secret-key

The S3 secret key.

false ""
s3-bucket

The S3 bucket in which the grype ignore file is stored.

false grypeignores
s3-path

The path in the s3 bucket to the grype ignore file.

false .grype.yaml
dockerfile-path

Path to the Dockerfile (default {context}/Dockerfile).

false .

About

Container action for scanning and signing container images

Resources

License

Stars

Watchers

Forks

Packages

No packages published