Skip to content

Commit

Permalink
Merge branch 'develop' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
clemlesne committed Sep 2, 2023
2 parents 35a81ed + 13a8828 commit d61d5a3
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 45 deletions.
108 changes: 85 additions & 23 deletions .github/workflows/pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ env:
CONTAINER_NAME: ${{ github.repository }}
CONTAINER_REGISTRY_GHCR: ghcr.io
CONTAINER_REGISTRY_DOCKER_HUB: docker.io
# https://github.com/sigstore/cosign/releases
COSIGN_VERSION: 2.2.0
# https://npmjs.com/package/@microsoft/sarif-multitool?activeTab=versions
SARIF_MULTITOOL_VERSION: 4.3.0
# https://npmjs.com/package/snyk?activeTab=versions
Expand Down Expand Up @@ -79,7 +81,7 @@ jobs:
submodules: recursive

- name: SAST - Credentials
uses: trufflesecurity/trufflehog@v3.53.0
uses: trufflesecurity/trufflehog@v3.54.1
with:
base: ${{ github.event.repository.default_branch }}
head: HEAD
Expand Down Expand Up @@ -118,7 +120,12 @@ jobs:
with:
node-version: ${{ env.NODE_VERSION }}

- name: Prepare GPG key for Helm chart
- name: Setup Cosign
uses: sigstore/[email protected]
with:
cosign-release: v${{ env.COSIGN_VERSION }}

- name: Prepare GPG key
run: |
echo "${{ secrets.GPG_KEYRING }}" | gpg --dearmor > keyring.gpg
Expand All @@ -135,6 +142,17 @@ jobs:
--version ${{ steps.version.outputs.version }} \
src/helm/azure-pipelines-agent
- name: Sign Helm chart
env:
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
run: |
cosign sign-blob \
--bundle .cr-release-packages/azure-pipelines-agent-${{ steps.version.outputs.version }}.tgz.bundle \
--key="env://COSIGN_PRIVATE_KEY" \
--yes \
.cr-release-packages/azure-pipelines-agent-${{ steps.version.outputs.version }}.tgz
- name: Cache Helm chart
uses: actions/[email protected]
with:
Expand Down Expand Up @@ -163,14 +181,15 @@ jobs:
# See: https://github.com/github/codeql-action/issues/220
- name: Merge SARIF files
run: |
npx --yes @microsoft/sarif-multitool@${{ env.SARIF_MULTITOOL_VERSION }} \
merge \
--merge-runs \
--output-file merged.sarif \
snyk.sarif
npx --yes @microsoft/sarif-multitool@${{ env.SARIF_MULTITOOL_VERSION }} merge \
--automation-id ${{ github.run_id }} \
--merge-empty-logs \
--merge-runs \
--output-file merged.sarif \
snyk.sarif
- name: Upload results to GitHub Security
uses: github/codeql-action/[email protected].4
uses: github/codeql-action/[email protected].5
with:
sarif_file: merged.sarif

Expand Down Expand Up @@ -280,7 +299,7 @@ jobs:
platforms: ${{ matrix.arch }}

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2.9.1
uses: docker/setup-buildx-action@v2.10.0
with:
version: v${{ env.BUILDX_VERSION }}
driver-opts: |
Expand All @@ -292,6 +311,11 @@ jobs:
with:
node-version: ${{ env.NODE_VERSION }}

- name: Setup Cosign
uses: sigstore/[email protected]
with:
cosign-release: v${{ env.COSIGN_VERSION }}

- name: Login to registry - GitHub
uses: docker/[email protected]
with:
Expand Down Expand Up @@ -376,7 +400,21 @@ jobs:
sbom: true
tags: ${{ steps.meta.outputs.tags }}

- name: Run SAST Snyk on container image
- name: Sign containers
env:
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
run: |
while IFS= read -r tag; do
echo "Signing $tag..."
cosign sign \
--key="env://COSIGN_PRIVATE_KEY" \
--recursive \
--yes \
$tag
done <<< "${{ steps.meta.outputs.tags }}"
- name: Run SAST Snyk against containers
# Snyk can be used to break the build when it detects security issues. In this case we want to upload the issues to GitHub Security
continue-on-error: true
env:
Expand All @@ -393,19 +431,17 @@ jobs:
${{ steps.tag.outputs.tag }}
done
# Fix issue "Error: Code Scanning could not process the submitted SARIF file: rejecting SARIF, as there are more runs than allowed (XX > 20)"
# See: https://github.com/github/codeql-action/issues/220
- name: Merge SARIF files
run: |
npx --yes @microsoft/sarif-multitool@${{ env.SARIF_MULTITOOL_VERSION }} \
merge \
--merge-runs \
--output-file merged.sarif \
--recurse true \
snyk-*.sarif
npx --yes @microsoft/sarif-multitool@${{ env.SARIF_MULTITOOL_VERSION }} merge \
--automation-id ${{ github.run_id }} \
--merge-empty-logs \
--merge-runs \
--output-file merged.sarif \
*.sarif
- name: Upload results to GitHub Security
uses: github/codeql-action/[email protected].4
uses: github/codeql-action/[email protected].5
with:
sarif_file: merged.sarif

Expand Down Expand Up @@ -444,6 +480,17 @@ jobs:
echo "version=$(powershell cicd/version/version.ps1 -g . -c)" >> $Env:GITHUB_OUTPUT
echo "version_full=$(powershell cicd/version/version.ps1 -g . -c -m)" >> $Env:GITHUB_OUTPUT
# Required for running "npx" CLI
- name: Setup Node
uses: actions/[email protected]
with:
node-version: ${{ env.NODE_VERSION }}

- name: Setup Cosign
uses: sigstore/[email protected]
with:
cosign-release: v${{ env.COSIGN_VERSION }}

- name: Login to registry - GitHub
uses: docker/[email protected]
with:
Expand Down Expand Up @@ -553,7 +600,7 @@ jobs:
Write-Host "Pulling cache images:"
foreach ($tag in $tags) {
Write-Host " $tag"
Write-Host " $tag"
docker pull --quiet $tag || true
}
Expand All @@ -565,7 +612,22 @@ jobs:
docker push --quiet $tag
}
- name: Run SAST Snyk on container image
- name: Sign containers
env:
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
run: |
$tags = ('${{ steps.meta.outputs.tags }}').Split([Environment]::NewLine)
foreach ($tag in $tags) {
Write-Host "Signing $tag..."
cosign sign `
--key="env://COSIGN_PRIVATE_KEY" `
--recursive `
--yes `
$tag
}
- name: Run SAST Snyk against containers
# Snyk can be used to break the build when it detects security issues. In this case we want to upload the issues to GitHub Security
continue-on-error: true
env:
Expand All @@ -579,7 +641,7 @@ jobs:
${{ steps.tag.outputs.tag }}
- name: Upload results to GitHub Security
uses: github/codeql-action/[email protected].4
uses: github/codeql-action/[email protected].5
with:
sarif_file: snyk.sarif

Expand All @@ -600,7 +662,7 @@ jobs:
run: semgrep ci --sarif --output=semgrep.sarif

- name: Upload results to GitHub Security
uses: github/codeql-action/[email protected].4
uses: github/codeql-action/[email protected].5
with:
sarif_file: semgrep.sarif

Expand Down
35 changes: 18 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@

Features:

- Agent register and restart itself.
- Allow to build containers inside the agent using [BuildKit](https://github.com/moby/buildkit).
- Can run air-gapped (no internet access).
- Cheap to run (dynamic provisioning of agents, can scale from 0 to 100+ in few seconds with [KEDA](https://keda.sh)).
- Performances can be customized depending of the engineering needs, which goes far beyond the Microsoft-hosted agent.
- Pre-built with Windows Server, Debian, Ubuntu, Red Hat Enterprise Linux.
- SBOM (Software Bill of Materials) is packaged with each container image.
- System updates are applied every days.
- 🔄 Agent register and restart itself.
- 🏗️ Allow to build containers inside the agent using [BuildKit](https://github.com/moby/buildkit).
- 🔒 Build authenticity can be cryptographically verified with [Cosign](https://github.com/sigstore/cosign) and GPG.
- 📵 Can run air-gapped (no internet access).
- 💰 Cheap to run (dynamic provisioning of agents, can scale from 0 to 100+ in few seconds with [KEDA](https://keda.sh)).
- 💪 Performances can be customized depending of the engineering needs, which goes far beyond the Microsoft-hosted agent.
- 🖥️ Pre-built with [Windows Server](https://www.microsoft.com/en-us/windows-server), [Debian](https://debian.org), [Ubuntu](https://ubuntu.com), [Red Hat Enterprise Linux](https://access.redhat.com/products/red-hat-enterprise-linux).
- 📦 [SBOM (Software Bill of Materials)](https://en.wikipedia.org/wiki/Software_supply_chain) is packaged with each container image.
- 🔄 System updates are applied every day.

## Usage

Expand Down Expand Up @@ -59,15 +60,15 @@ helm upgrade --install agent clemlesne-azure-pipelines-agent/azure-pipelines-age

> Container images are both published to GitHub Container Registry and Docker Hub. URLs showed in the doc are GitHub Container Registry URLs, for simplicity. To use Docker Hub, replace `ghcr.io/clemlesne/azure-pipelines-agent` by `docker.io/clemlesne/azure-pipelines-agent`.
| `Ref` | OS | `Size` | `Arch` | Support |
| ----------------------------------------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ghcr.io/clemlesne/azure-pipelines-agent:bookworm-main` | Debian Bookworm (12) slim | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/bookworm-main?label=) | `amd64`, `arm64/v8` | [See Debian LTS wiki.](https://wiki.debian.org/LTS) |
| `ghcr.io/clemlesne/azure-pipelines-agent:bullseye-main` | Debian Bullseye (11) slim | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/bullseye-main?label=) | `amd64`, `arm64/v8` | [See Debian LTS wiki.](https://wiki.debian.org/LTS) |
| `ghcr.io/clemlesne/azure-pipelines-agent:focal-main` | Ubuntu Focal (20.04) minimal | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/focal-main?label=) | `amd64`, `arm64/v8` | [See Ubuntu LTS wiki.](https://wiki.ubuntu.com/Releases) |
| `ghcr.io/clemlesne/azure-pipelines-agent:jammy-main` | Ubuntu Jammy (22.04) minimal | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/jammy-main?label=) | `amd64`, `arm64/v8` | [See Ubuntu LTS wiki.](https://wiki.ubuntu.com/Releases) |
| `ghcr.io/clemlesne/azure-pipelines-agent:ubi8-main` | Red Hat UBI 8 (8.8) minimal | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/ubi8-main?label=) | `amd64`, `arm64/v8` | [See Red Hat product life cycles.](https://access.redhat.com/product-life-cycles/?product=Red%20Hat%20Enterprise%20Linux) |
| `ghcr.io/clemlesne/azure-pipelines-agent:win-ltsc2019-main` | Windows Server 2019 Core | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/win-ltsc2019-main?label=) | `amd64` | [See base image servicing lifecycles.](https://learn.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/base-image-lifecycle) |
| `ghcr.io/clemlesne/azure-pipelines-agent:win-ltsc2022-main` | Windows Server 2022 Core | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/win-ltsc2022-main?label=) | `amd64` | [See base image servicing lifecycles.](https://learn.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/base-image-lifecycle) |
| `Ref` | OS | `Size` | `Arch` | Support |
| ----------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ghcr.io/clemlesne/azure-pipelines-agent:bookworm-main` | [Debian Bookworm (12)](https://www.debian.org/releases/bookworm) slim | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/bookworm-main?label=) | `amd64`, `arm64/v8` | [See Debian LTS wiki.](https://wiki.debian.org/LTS) |
| `ghcr.io/clemlesne/azure-pipelines-agent:bullseye-main` | [Debian Bullseye (11)](https://www.debian.org/releases/bullseye) slim | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/bullseye-main?label=) | `amd64`, `arm64/v8` | [See Debian LTS wiki.](https://wiki.debian.org/LTS) |
| `ghcr.io/clemlesne/azure-pipelines-agent:focal-main` | [Ubuntu Focal (20.04)](https://www.releases.ubuntu.com/focal) minimal | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/focal-main?label=) | `amd64`, `arm64/v8` | [See Ubuntu LTS wiki.](https://wiki.ubuntu.com/Releases) |
| `ghcr.io/clemlesne/azure-pipelines-agent:jammy-main` | [Ubuntu Jammy (22.04)](https://www.releases.ubuntu.com/jammy) minimal | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/jammy-main?label=) | `amd64`, `arm64/v8` | [See Ubuntu LTS wiki.](https://wiki.ubuntu.com/Releases) |
| `ghcr.io/clemlesne/azure-pipelines-agent:ubi8-main` | [Red Hat UBI 8 (8.8)](https://developers.redhat.com/articles/ubi-faq) minimal | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/ubi8-main?label=) | `amd64`, `arm64/v8` | [See Red Hat product life cycles.](https://access.redhat.com/product-life-cycles/?product=Red%20Hat%20Enterprise%20Linux) |
| `ghcr.io/clemlesne/azure-pipelines-agent:win-ltsc2019-main` | [Windows Server 2019](https://learn.microsoft.com/en-us/windows-server) Core | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/win-ltsc2019-main?label=) | `amd64` | [See base image servicing lifecycles.](https://learn.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/base-image-lifecycle) |
| `ghcr.io/clemlesne/azure-pipelines-agent:win-ltsc2022-main` | [Windows Server 2022](https://learn.microsoft.com/en-us/windows-server) Core | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/clemlesne/azure-pipelines-agent/win-ltsc2022-main?label=) | `amd64` | [See base image servicing lifecycles.](https://learn.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/base-image-lifecycle) |

## Advanced topics

Expand Down
46 changes: 44 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,53 @@ If you think you have found a vulnerability, please do not open an issue on GitH

## Chain of trust

The Helm chart is signed with a GPG key. [The public key is available on Keybase at the following address.](https://keybase.io/clemlesne/pgp_keys.asc)
Both the containers and the Helm chart are signed:

### Containers

Containers are signed with [Cosign](https://github.com/sigstore/cosign).

Cosign public key is available in [`/cosign.pub`](cosign.pub).

```bash
# Example of verification with Cosign
❯ cosign verify --key cosign.pub ghcr.io/clemlesne/azure-pipelines-agent:bullseye-main
Verification for ghcr.io/clemlesne/azure-pipelines-agent:bullseye-main --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- Existence of the claims in the transparency log was verified offline
- The signatures were verified against the specified public key
```

### Helm chart

Helm chart is signed with two methods, [Cosign](https://github.com/sigstore/cosign) and [GPG](https://helm.sh/docs/topics/provenance). Both methods can be used to confirm authenticity of a build.

Keys:

- Cosign public key is available in [`/cosign.pub`](cosign.pub).
- GPG public key is [available on Keybase](https://keybase.io/clemlesne/pgp_keys.asc) and in [`/pubring.gpg`](pubring.gpg).

```bash
# Example of verification with Helm native signature
❯ helm fetch --keyring pubring.gpg --verify clemlesne-azure-pipelines-agent/azure-pipelines-agent --version 5.0.0
Signed by: Clémence Lesné <[email protected]>
Using Key With Fingerprint: 417E701DBC66834CA752C920460D072B9C032DFD
Chart Hash Verified: sha256:1c23e22cffc132ce12489480d139b59e97b3cb49ff1599a4ae11fb5c317c1e64
```

```bash
# Example of verification with Cosign
❯ VERSION=5.0.0
❯ wget https://github.com/clemlesne/azure-pipelines-agent/releases/download/azure-pipelines-agent-${VERSION}/azure-pipelines-agent-${VERSION}.tgz.bundle
❯ helm pull clemlesne-azure-pipelines-agent/azure-pipelines-agent --version 5.0.0
❯ cosign verify-blob azure-pipelines-agent-${VERSION}.tgz --bundle azure-pipelines-agent-${VERSION}.tgz.bundle --key cosign.pub
Verified OK
```

## Reliability notes

Systems are built every days. Each image is accompanied by a SBOM (Software Bill of Materials) which allows to verify that the installed packages are those expected. This speed has the advantage of minimizing exposure to security flaws, which will then be corrected on the build environments in 24 hours.
Systems are built every days. Each image is accompanied by a [SBOM (Software Bill of Materials)](https://en.wikipedia.org/wiki/Software_supply_chain) which allows to verify that the installed packages are those expected. This speed has the advantage of minimizing exposure to security flaws, which will then be corrected on the build environments in 24 hours.

Nevertheless it can happen that a package provider (e.g. Debian, Canonical, Red Hat) deploys a system update that introduces a bug. This is difficult to predict.

Expand Down
4 changes: 4 additions & 0 deletions cosign.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERbXillF9UqyNmGEffSXiEQAlgiKp
RJFDQRRbnqpfDYbJRAPHwDM/g13P0WOmY079JUl5tdMAoew6XK602u952Q==
-----END PUBLIC KEY-----
Binary file added pubring.gpg
Binary file not shown.
Loading

0 comments on commit d61d5a3

Please sign in to comment.