Skip to content

Commit

Permalink
Merge pull request #24 from philips-labs/fatt-installer-action
Browse files Browse the repository at this point in the history
  • Loading branch information
marcofranssen authored Mar 28, 2022
2 parents 385fdb1 + bab10d1 commit a34bd8c
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 90 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.17
go-version: 1.18
check-latest: true

- name: Checkout
Expand Down Expand Up @@ -79,7 +79,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.17
go-version: 1.18
check-latest: true

- name: Install cosign
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.17-alpine as build
FROM golang:1.18-alpine as build
WORKDIR /build

COPY go.mod go.sum ./
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/philips-labs/fatt

go 1.17
go 1.18

require (
github.com/antonmedv/expr v1.9.0
Expand Down
86 changes: 0 additions & 86 deletions go.sum

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions installer-action/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# fatt/installer-action

This action enables you to install `fatt` on your runner. During installation the integrity of `fatt` is verified based on it's cosign signature.

For a quick start guide on the usage of `fatt`, please refer to https://github.com/philips-labs/fatt#quick-start.
For available `cosign` releases, see https://github.com/sigstore/cosign/releases.

## Usage

This action currently supports GitHub-provided Linux, macOS and Windows runners.

Add the following entry to your Github workflow YAML file:

```yaml
uses: philips-labs/fatt/installer-action@main
with:
fatt-release: 'v0.2.0' # optional
install-path: '.fatt/bin' #optional
```
Now you can use fatt to `list` and `publish` attestations. Keep in mind to add `packages: write` permission if you want to publish the attestations to oci.

## Example

```yaml
jobs:
publish-attestations:
runs-on: ubuntu-20.04
permissions:
packages: write
env:
PACKAGE: ghcr.io/philips-labs/fatt/attestations-example
PACKAGE_VERSION: v0.2.0
steps:
- name: Install cosign
uses: sigstore/cosign-installer@v2.1.0
with:
cosign-release: v1.6.0
- name: Install fatt
uses: philips-labs/fatt/installer-action@main
with:
fatt-release: v0.2.0
install-dir: .fatt/bin
- name: Generate SBOM
run: echo 'We could have generated a real sbom using syft here…' > sbom-spdx.json
- name: Generate provenance
run: echo 'We can use philips-labs/slsa-provenance-action to generate provenance…' > provenance.att
- name: Login to ghcr.io
uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 #v1.14.1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Install signing key
run: echo "${{ secrets.COSIGN_PRIVATE_KEY }}" > cosign.key
- name: Publish attestations
run: |
fatt publish \
--repository "${PACKAGE}" \
--version "${PACKAGE_VERSION}" \
"sbom://sbom-spdx.json" "provenance://provenance.att"
- name: Sign attestations and discovery
run: |
cosign sign --key cosign.key "${PACKAGE}:${PACKAGE_VERSION}.provenance"
cosign sign --key cosign.key "${PACKAGE}:${PACKAGE_VERSION}.sbom"
cosign sign --key cosign.key "${PACKAGE}:${PACKAGE_VERSION}.discovery"
env:
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
- name: Discover attestations
run: |
echo "${{ secrets.COSIGN_PUBLIC_KEY }}" > cosign.pub
fatt list --key cosign.pub "${PACKAGE}:${PACKAGE_VERSION}.discovery"
- name: Cleanup signing key
if: ${{ always() }}
run: rm cosign.key
```
29 changes: 29 additions & 0 deletions installer-action/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: 'fatt installer'
author: philips-labs
description: 'An action to install fatt'
branding:
icon: lock
color: purple
inputs:
fatt-release:
description: 'fatt release version to be installed'
required: false
default: 'v0.2.0-rc2'
install-dir:
description: 'Where to install the fatt binary'
required: false
default: '$HOME/.fatt/bin'
runs:
using: 'composite'
steps:
- shell: bash
run: $GITHUB_ACTION_PATH/install.sh
env:
VERSION: ${{ inputs.fatt-release }}
INSTALL_PATH: ${{ inputs.install-dir }}
- if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
run: echo "${{ inputs.install-dir }}" >> $GITHUB_PATH
shell: bash
- if: ${{ runner.os == 'Windows' }}
run: echo "${{ inputs.install-dir }}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
shell: pwsh
106 changes: 106 additions & 0 deletions installer-action/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env bash

shopt -s expand_aliases

if [ -z "$NO_COLOR" ]; then
alias log_info="echo -e \"\033[1;32mINFO\033[0m:\""
alias log_error="echo -e \"\033[1;31mERROR\033[0m:\""
alias log_warning="echo -e \"\033[1;33mWARN\033[0m:\""
else
alias log_info="echo \"INFO:\""
alias log_error="echo \"ERROR:\""
alias log_warning="echo \"WARN:\""
fi

set -e

GITHUB_API=${GITHUB_API:-'https://api.github.com'}

# default to relative path if INSTALL_PATH is not set
INSTALL_PATH=${INSTALL_PATH:-./.fatt/bin}
mkdir -p "${INSTALL_PATH}"
INSTALL_PATH="$(realpath "${INSTALL_PATH}")"

VERSION="${VERSION:-v0.2.0-rc}"
RELEASE="https://github.com/philips-labs/fatt/releases/download/${VERSION}"

if [[ "$VERSION" == *-draft ]] ; then
curl_args=(-H "Authorization: token $GITHUB_TOKEN")
assets=$(curl "${curl_args[@]}" -s "${GITHUB_API}/repos/philips-labs/fatt/releases?per_page=10" | jq "map(select(.name == \"${VERSION}\"))" | jq -r '.[0].assets')
fi

function download {
url="${2}"
if [[ "$VERSION" == *-draft ]] ; then
url="$(echo "${assets}" | jq "map(select(.name == \"$1\"))" | jq -r '.[0].url')"
curl_args+=(-H 'Accept: application/octet-stream')
fi
log_info "Downloading ${1} from ${url}"
curl -sLo "${1}" --show-error "${curl_args[@]}" "${url}"
echo
}

OS=${RUNNER_OS:-Linux}
ARCH=${RUNNER_ARCH:-X64}

case "${ARCH}" in
X64)
ARCH=amd64
;;
ARM64)
ARCH=arm64
;;
*)
log_error "unsupported ARCH ${ARCH}"
exit 1
;;
esac

BINARY=fatt
case "${OS}" in
Linux)
OS=linux
ARCHIVE="${BINARY}_${VERSION/v}_${OS}_${ARCH}.tar.gz"
;;
macOS)
ARCHIVE="${BINARY}_${VERSION/v}_${OS}_${ARCH}.tar.gz"
;;
Windows)
OS=windows
ARCHIVE="${BINARY}_${VERSION/v}_${OS}_${ARCH}.zip"
BINARY="${BINARY}.exe"
;;
*)
log_error "unsupported OS ${OS}"
exit 1
;;
esac

DOWNLOAD="${RELEASE}/${ARCHIVE}"

log_info "Installing ${BINARY} (${OS}/${ARCH}) at ${INSTALL_PATH}"
mkdir -p "$INSTALL_PATH"

trap "popd >/dev/null" EXIT
pushd "$INSTALL_PATH" > /dev/null || exit

download "${ARCHIVE}" "${DOWNLOAD}"

if [ -x "$(command -v cosign)" ] ; then
download "${ARCHIVE}.sig" "${DOWNLOAD}.sig"
download cosign.pub "$RELEASE/cosign.pub"

log_info "Verifying signature…"
cosign verify-blob --key cosign.pub --signature "${ARCHIVE}.sig" "${ARCHIVE}"
rm "${ARCHIVE}.sig" cosign.pub
else
log_warning >&2
log_warning " cosign binary not installed in PATH. Unable to verify signature!" >&2
log_warning >&2
log_warning " Consider installing cosign first, to be able to verify the signature!" >&2
log_warning >&2
fi

log_info "extracting ${BINARY} from ${ARCHIVE}"
tar -xzf "${ARCHIVE}" "${BINARY}"
rm "${ARCHIVE}"

0 comments on commit a34bd8c

Please sign in to comment.