Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Dependabot keeps third-party GitHub Actions pinned SHAs up to date.
# This ensures we receive automated PRs when actions release security
# fixes, without relying on mutable major-version tags.
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "ci"
include: "scope"
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "deps"
include: "scope"
ignore:
# k8s.io/* is pinned to v0.35.4 due to controller-runtime
# compatibility — see DESIGN.md §7 (M12 dependency refresh).
- dependency-name: "k8s.io/*"
update-types: ["version-update:semver-minor"]
30 changes: 15 additions & 15 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: '1.26.2'
cache: true
Expand All @@ -53,8 +53,8 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: '1.26.2'
cache: true
Expand All @@ -79,23 +79,23 @@ jobs:
packages: write
id-token: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
if: github.event_name != 'pull_request'
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE }}
tags: |
type=sha
type=ref,event=branch
type=semver,pattern={{version}}
- uses: docker/build-push-action@v6
- uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
with:
context: .
platforms: linux/amd64,linux/arm64
Expand Down Expand Up @@ -125,16 +125,16 @@ jobs:
packages: write
id-token: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
if: github.event_name != 'pull_request'
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE }}
flavor: |
Expand All @@ -143,7 +143,7 @@ jobs:
type=sha
type=ref,event=branch
type=semver,pattern={{version}}
- uses: docker/build-push-action@v6
- uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6.16.0
with:
context: .
file: Dockerfile.fips
Expand All @@ -164,7 +164,7 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Compose up
run: docker compose -f deploy/docker/compose.yaml up -d --build --wait
- name: Smoke test
Expand Down
84 changes: 64 additions & 20 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
#
# Docker images (stock + FIPS) are produced by build.yaml which already
# triggers on v* tags — this workflow adds the binary/Helm/signing layer.
#
# Security:
# - All third-party actions pinned by full commit SHA.
# - Jobs split by least-privilege scope.
# - Concurrency guard prevents parallel release races.
# - Tag-on-main verification prevents rogue tag releases.

name: release

Expand All @@ -17,6 +23,11 @@ on:
tags:
- "v*"

# Prevent parallel releases from racing on the same tag or overlapping tags.
concurrency:
group: release-${{ github.ref_name }}
cancel-in-progress: false

permissions:
contents: read

Expand All @@ -25,24 +36,45 @@ env:
CHART_REPO: ghcr.io/mikeappsec/charts

jobs:
# ------------------------------------------------------------------
# Job 0: Verify the tag points to a commit on main
# ------------------------------------------------------------------
verify-tag:
runs-on: ubuntu-24.04
permissions:
contents: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0

- name: Verify tag is on main branch
run: |
git fetch origin main
if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
echo "ERROR: Tag $GITHUB_REF_NAME does not point to a commit on main."
echo "Release tags must be created on the main branch."
exit 1
fi
echo "OK: Tag $GITHUB_REF_NAME is on main."

# ------------------------------------------------------------------
# Job 1: Build binaries, generate SBOMs, create GitHub Release
# ------------------------------------------------------------------
goreleaser:
runs-on: ubuntu-24.04
needs: verify-tag
permissions:
contents: write # create release + upload assets
packages: write # push Helm OCI chart
id-token: write # Cosign keyless signing (Sigstore OIDC)
outputs:
version: ${{ steps.version.outputs.version }}
hashes: ${{ steps.hash.outputs.hashes }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0 # GoReleaser needs full history for changelog

- uses: actions/setup-go@v5
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: "1.26.2"
cache: true
Expand All @@ -53,7 +85,7 @@ jobs:

# GoReleaser builds cross-platform binaries and creates the
# GitHub Release with archives and checksums.
- uses: goreleaser/goreleaser-action@v6
- uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf # v6.1.0
id: goreleaser
with:
distribution: goreleaser
Expand All @@ -73,31 +105,44 @@ jobs:
# uploaded alongside the release archives so consumers can
# verify the dependency tree.
- name: Generate SBOMs (syft)
uses: anchore/sbom-action@v0
uses: anchore/sbom-action@f325610c9f50a54015d37c8d16cb3b0e2c8f4de0 # v0.18.0
with:
path: ./dist
output-file: dist/lightweightauth_${{ steps.version.outputs.version }}.sbom.json
format: spdx-json

- name: Upload SBOMs to release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
with:
files: dist/*.sbom.json
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Cosign keyless signing of the checksums file. Verifiers can
# check provenance without any out-of-band key exchange.
# ------------------------------------------------------------------
# Job 2: Sign release checksums with Cosign (keyless)
# ------------------------------------------------------------------
sign:
runs-on: ubuntu-24.04
needs: goreleaser
permissions:
contents: write # upload signature files to release
id-token: write # mint OIDC token for Sigstore
steps:
- name: Download release asset (checksums.txt)
run: |
mkdir -p dist
gh release download "$GITHUB_REF_NAME" --pattern "checksums.txt" --dir dist/
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Install Cosign
uses: sigstore/cosign-installer@v3
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.0

- name: Sign checksums with Cosign (keyless)
run: cosign sign-blob --yes dist/checksums.txt --output-signature dist/checksums.txt.sig --output-certificate dist/checksums.txt.pem
env:
COSIGN_EXPERIMENTAL: "1"

- name: Upload signature + cert to release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
with:
files: |
dist/checksums.txt.sig
Expand All @@ -106,7 +151,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# ------------------------------------------------------------------
# Job 2: SLSA provenance for Go binaries (level 3)
# Job 3: SLSA provenance for Go binaries (level 3)
# ------------------------------------------------------------------
provenance:
needs: goreleaser
Expand All @@ -120,19 +165,20 @@ jobs:
upload-assets: true

# ------------------------------------------------------------------
# Job 3: Package and push Helm chart as OCI artifact
# Job 4: Package and push Helm chart as OCI artifact
# ------------------------------------------------------------------
helm:
runs-on: ubuntu-24.04
needs: goreleaser
permissions:
contents: read
packages: write
id-token: write # Cosign chart signing
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Install Helm
uses: azure/setup-helm@v4
uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 # v4.3.0
with:
version: "v3.16.0"

Expand All @@ -156,9 +202,7 @@ jobs:
# Sign the Helm chart OCI artifact with Cosign so consumers can
# verify the chart was published by this workflow.
- name: Install Cosign
uses: sigstore/cosign-installer@v3
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.0

- name: Sign Helm OCI artifact (keyless)
run: cosign sign --yes ${{ env.CHART_REPO }}/lightweightauth:${{ needs.goreleaser.outputs.version }}
env:
COSIGN_EXPERIMENTAL: "1"
6 changes: 6 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ builds:
goarch:
- amd64
- arm64
flags:
- -buildmode=pie
- -trimpath
ldflags:
- -s -w
- -X github.com/mikeappsec/lightweightauth/pkg/buildinfo.Version={{ .Version }}
Expand All @@ -42,6 +45,9 @@ builds:
goarch:
- amd64
- arm64
flags:
- -buildmode=pie
- -trimpath
ldflags:
- -s -w
- -X github.com/mikeappsec/lightweightauth/pkg/buildinfo.Version={{ .Version }}
Expand Down
11 changes: 8 additions & 3 deletions docs/operations/supply-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,14 @@ to an internal registry.
```bash
VERSION=1.2.0

# Pull from public registry (on a connected host)
crane pull ghcr.io/mikeappsec/lightweightauth:${VERSION} lwauth-${VERSION}.tar
crane pull ghcr.io/mikeappsec/lightweightauth:${VERSION}-fips lwauth-${VERSION}-fips.tar
# Resolve tags to immutable digests first (prevents tag-swap attacks
# between verification and pull).
DIGEST=$(crane digest ghcr.io/mikeappsec/lightweightauth:${VERSION})
DIGEST_FIPS=$(crane digest ghcr.io/mikeappsec/lightweightauth:${VERSION}-fips)

# Pull by digest from public registry (on a connected host)
crane pull ghcr.io/mikeappsec/lightweightauth@${DIGEST} lwauth-${VERSION}.tar
crane pull ghcr.io/mikeappsec/lightweightauth@${DIGEST_FIPS} lwauth-${VERSION}-fips.tar

# Transfer tarballs to air-gapped network, then push
crane push lwauth-${VERSION}.tar registry.internal/lwauth/lightweightauth:${VERSION}
Expand Down
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ nav:
- Design: DESIGN.md
- Architecture overview: ARCHITECTURE.md
- HTTP / gRPC API: API.md
- Cache architecture: design/cache-architecture.md
- Milestones: MILESTONES.md
- Operations:
- Deployment: DEPLOYMENT.md
Expand All @@ -166,6 +167,7 @@ nav:
- Key rotation: operations/key-rotation.md
- Policy rotation: operations/policy-rotation.md
- Disaster recovery: operations/disaster-recovery.md
- Supply-chain trust: operations/supply-chain.md
- Request invariants: testing/request-invariants.md
- Security:
- v1.0 security review: security/v1.0-review.md
Loading