- Implement `SbomVexOrderingDeterminismProperties` for testing component list and vulnerability metadata hash consistency. - Create `UnicodeNormalizationDeterminismProperties` to validate NFC normalization and Unicode string handling. - Add project file for `StellaOps.Testing.Determinism.Properties` with necessary dependencies. - Introduce CI/CD template validation tests including YAML syntax checks and documentation content verification. - Create validation script for CI/CD templates ensuring all required files and structures are present.
248 lines
6.0 KiB
Markdown
248 lines
6.0 KiB
Markdown
# Keyless Signing Quick Start
|
|
|
|
Get keyless signing working in your CI/CD pipeline in under 5 minutes.
|
|
|
|
## Overview
|
|
|
|
Keyless signing uses your CI platform's OIDC identity to sign artifacts without managing private keys. The signature is bound to your repository, branch, and workflow identity.
|
|
|
|
```
|
|
┌─────────────┐ ┌─────────┐ ┌───────────────┐
|
|
│ CI Platform │────▶│ Fulcio │────▶│ Signed Artifact│
|
|
│ OIDC Token │ │ Sigstore│ │ + Rekor Entry │
|
|
└─────────────┘ └─────────┘ └───────────────┘
|
|
```
|
|
|
|
## GitHub Actions (Fastest)
|
|
|
|
### Step 1: Add the workflow
|
|
|
|
Create `.github/workflows/sign.yml`:
|
|
|
|
```yaml
|
|
name: Build and Sign
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
build-and-sign:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
id-token: write # Required for OIDC
|
|
contents: read
|
|
packages: write
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Build container
|
|
run: |
|
|
docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .
|
|
docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
|
|
|
|
- name: Install StellaOps CLI
|
|
run: curl -sL https://get.stella-ops.org/cli | sh
|
|
|
|
- name: Get OIDC Token
|
|
id: oidc
|
|
run: |
|
|
TOKEN=$(curl -sLS "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=sigstore" \
|
|
-H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \
|
|
| jq -r '.value')
|
|
echo "::add-mask::${TOKEN}"
|
|
echo "token=${TOKEN}" >> $GITHUB_OUTPUT
|
|
|
|
- name: Sign container
|
|
env:
|
|
STELLAOPS_OIDC_TOKEN: ${{ steps.oidc.outputs.token }}
|
|
run: |
|
|
DIGEST=$(docker inspect ghcr.io/${{ github.repository }}:${{ github.sha }} \
|
|
--format='{{index .RepoDigests 0}}' | cut -d@ -f2)
|
|
stella attest sign --keyless --artifact "$DIGEST"
|
|
```
|
|
|
|
### Step 2: Push and verify
|
|
|
|
```bash
|
|
git add .github/workflows/sign.yml
|
|
git commit -m "Add keyless signing"
|
|
git push
|
|
```
|
|
|
|
Check Actions tab - your container is now signed!
|
|
|
|
---
|
|
|
|
## GitLab CI (5 minutes)
|
|
|
|
### Step 1: Update `.gitlab-ci.yml`
|
|
|
|
```yaml
|
|
stages:
|
|
- build
|
|
- sign
|
|
|
|
build:
|
|
stage: build
|
|
image: docker:24
|
|
services:
|
|
- docker:dind
|
|
script:
|
|
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
|
|
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
|
- echo "ARTIFACT_DIGEST=$(docker inspect $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --format='{{index .RepoDigests 0}}' | cut -d@ -f2)" >> build.env
|
|
artifacts:
|
|
reports:
|
|
dotenv: build.env
|
|
|
|
sign:
|
|
stage: sign
|
|
image: stella-ops/cli:latest
|
|
id_tokens:
|
|
STELLAOPS_OIDC_TOKEN:
|
|
aud: sigstore
|
|
needs:
|
|
- build
|
|
script:
|
|
- stella attest sign --keyless --artifact "$ARTIFACT_DIGEST"
|
|
only:
|
|
- main
|
|
```
|
|
|
|
### Step 2: Push
|
|
|
|
```bash
|
|
git add .gitlab-ci.yml
|
|
git commit -m "Add keyless signing"
|
|
git push
|
|
```
|
|
|
|
---
|
|
|
|
## Verification Gate
|
|
|
|
Add verification before deployment:
|
|
|
|
### GitHub Actions
|
|
|
|
```yaml
|
|
deploy:
|
|
needs: [build-and-sign]
|
|
runs-on: ubuntu-latest
|
|
environment: production
|
|
steps:
|
|
- name: Verify before deploy
|
|
run: |
|
|
stella attest verify \
|
|
--artifact "${{ needs.build-and-sign.outputs.digest }}" \
|
|
--certificate-identity "repo:${{ github.repository }}:ref:refs/heads/main" \
|
|
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
|
|
--require-rekor
|
|
|
|
- name: Deploy
|
|
run: kubectl set image deployment/app app=$IMAGE
|
|
```
|
|
|
|
### GitLab CI
|
|
|
|
```yaml
|
|
deploy:
|
|
stage: deploy
|
|
environment: production
|
|
needs:
|
|
- sign
|
|
script:
|
|
- |
|
|
stella attest verify \
|
|
--artifact "$ARTIFACT_DIGEST" \
|
|
--certificate-identity "project_path:$CI_PROJECT_PATH:ref_type:branch:ref:main" \
|
|
--certificate-oidc-issuer "https://gitlab.com" \
|
|
--require-rekor
|
|
- kubectl set image deployment/app app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
|
only:
|
|
- main
|
|
```
|
|
|
|
---
|
|
|
|
## Identity Patterns Cheat Sheet
|
|
|
|
### GitHub Actions
|
|
|
|
| Pattern | Example |
|
|
|---------|---------|
|
|
| Any branch | `repo:org/repo:.*` |
|
|
| Main only | `repo:org/repo:ref:refs/heads/main` |
|
|
| Tags only | `repo:org/repo:ref:refs/tags/v.*` |
|
|
| Environment | `repo:org/repo:environment:production` |
|
|
|
|
**OIDC Issuer:** `https://token.actions.githubusercontent.com`
|
|
|
|
### GitLab CI
|
|
|
|
| Pattern | Example |
|
|
|---------|---------|
|
|
| Any ref | `project_path:group/project:.*` |
|
|
| Main only | `project_path:group/project:ref_type:branch:ref:main` |
|
|
| Tags only | `project_path:group/project:ref_type:tag:.*` |
|
|
| Protected | `project_path:group/project:ref_protected:true` |
|
|
|
|
**OIDC Issuer:** `https://gitlab.com` (or self-hosted URL)
|
|
|
|
---
|
|
|
|
## Using Reusable Workflows
|
|
|
|
For cleaner pipelines, use StellaOps reusable workflows:
|
|
|
|
### GitHub Actions
|
|
|
|
```yaml
|
|
jobs:
|
|
sign:
|
|
uses: stella-ops/workflows/.github/workflows/stellaops-sign.yml@v1
|
|
with:
|
|
artifact-digest: sha256:abc123...
|
|
artifact-type: image
|
|
permissions:
|
|
id-token: write
|
|
|
|
verify:
|
|
needs: [sign]
|
|
uses: stella-ops/workflows/.github/workflows/stellaops-verify.yml@v1
|
|
with:
|
|
artifact-digest: sha256:abc123...
|
|
certificate-identity: "repo:${{ github.repository }}:ref:refs/heads/main"
|
|
certificate-oidc-issuer: "https://token.actions.githubusercontent.com"
|
|
```
|
|
|
|
### GitLab CI
|
|
|
|
```yaml
|
|
include:
|
|
- project: 'stella-ops/templates'
|
|
file: '.gitlab-ci-stellaops.yml'
|
|
|
|
sign-container:
|
|
extends: .stellaops-sign
|
|
variables:
|
|
ARTIFACT_DIGEST: sha256:abc123...
|
|
ARTIFACT_TYPE: image
|
|
```
|
|
|
|
---
|
|
|
|
## What's Next?
|
|
|
|
- [Identity Constraints Guide](./identity-constraints.md) - Secure verification patterns
|
|
- [Troubleshooting Guide](./keyless-signing-troubleshooting.md) - Common issues and fixes
|
|
- [Offline Verification](../airgap/offline-verification.md) - Air-gapped environments
|
|
|
|
## Need Help?
|
|
|
|
- Documentation: https://docs.stella-ops.org/
|
|
- Issues: https://github.com/stella-ops/stellaops/issues
|
|
- Slack: https://stellaops.slack.com/
|