Back to skills
SKILL.md
Sigstore Cosign
BSecuritySigstore — keyless signing for software artifacts using OIDC identities and short-lived certificates from Fulcio CA, with Rekor transparency log. Cosign is the CLI for signing/verifying containers, OCI artifacts, blobs, and attestations (SBOMs, provenance). Covers GitHub Actions OIDC integration, policy enforcement (cosign-policy-controller, Kyverno), Notary v2 vs Cosign, and supply-chain attestation patterns (SLSA). USE WHEN: user mentions "Sigstore", "Cosign", "Fulcio", "Rekor", "keyless s...
- 31 stars
- 0 votes
- 0 copies
- 1 view
- Added September 8, 2026
Works with
Security analysis
84/100- Uses curl or wget to download content
- Exfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study
npx -y skills add claude-dev-suite/claude-dev-suite --skill sigstore-cosign --agent claude-codeAre you the author of Sigstore Cosign?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/claude-dev-suite-sigstore-cosign)---
name: sigstore-cosign
description: |
Sigstore — keyless signing for software artifacts using OIDC identities and
short-lived certificates from Fulcio CA, with Rekor transparency log. Cosign
is the CLI for signing/verifying containers, OCI artifacts, blobs, and
attestations (SBOMs, provenance). Covers GitHub Actions OIDC integration,
policy enforcement (cosign-policy-controller, Kyverno), Notary v2 vs Cosign,
and supply-chain attestation patterns (SLSA).
USE WHEN: user mentions "Sigstore", "Cosign", "Fulcio", "Rekor", "keyless signing",
"OIDC signing", "cosign sign", "cosign verify", "SLSA provenance",
"OCI artifact signing", "attestation cosign"
DO NOT USE FOR: GPG-style signing - use GPG-specific docs
DO NOT USE FOR: Code signing certificates (Apple Developer ID, Authenticode) - platform-specific
DO NOT USE FOR: Reproducible builds spec - use `infrastructure/reproducible-builds`
allowed-tools: Read, Grep, Glob, Write, Edit
---
# Sigstore + Cosign — Keyless Artifact Signing
> **Deep Knowledge**: Use `mcp__documentation__fetch_docs` with technology: `sigstore` or `cosign`.
## Why Sigstore
Traditional signing requires long-lived private keys: distribute, secure, rotate, audit. Sigstore replaces the model with **keyless signing**:
1. CI proves identity via OIDC (e.g., GitHub Actions has built-in OIDC token)
2. **Fulcio** issues short-lived (10 min) X.509 cert bound to that identity
3. Sign artifact, attach signature + cert to artifact
4. **Rekor** transparency log records the signing event (Merkle tree)
5. Verifier checks: cert chain is valid, identity matches expected, log entry exists
No keys to manage. Identity-based trust. Public auditability via Rekor.
**Sigstore project includes**:
- **Cosign** — CLI for sign/verify (most-used component)
- **Fulcio** — Code-signing CA
- **Rekor** — Transparency log (https://search.sigstore.dev/)
- **Gitsign** — Sign git commits with sigstore (replaces GPG)
Adopted by Kubernetes, npm (since 2023), GitHub container registry, JFrog, Wolfi/Chainguard images.
## Install Cosign
```bash
# macOS
brew install cosign
# Linux
curl -LO https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
chmod +x cosign-linux-amd64 && sudo mv cosign-linux-amd64 /usr/local/bin/cosign
# Verify
cosign version
```
## Sign a Container Image (Keyless)
```bash
# Push image first
docker push ghcr.io/bhodl/api:1.0.0
# Sign with keyless OIDC (browser opens for OAuth)
cosign sign ghcr.io/bhodl/api:1.0.0
# In CI (no interactive auth — uses ambient OIDC):
COSIGN_EXPERIMENTAL=1 cosign sign --yes ghcr.io/bhodl/api:1.0.0
```
The signature is stored as a separate OCI artifact next to the image (`<image>:<digest>.sig`).
## Verify
```bash
cosign verify ghcr.io/bhodl/api:1.0.0 \
--certificate-identity-regexp="^https://github\.com/bhodl/api/" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"
```
`--certificate-identity-regexp` constrains who could have signed (the workflow URL). `--certificate-oidc-issuer` constrains the OIDC provider.
For a specific workflow:
```bash
cosign verify ghcr.io/bhodl/api:1.0.0 \
--certificate-identity="https://github.com/bhodl/api/.github/workflows/release.yml@refs/heads/main" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"
```
## Sign with a Key (Traditional)
If you must use a key (e.g., air-gapped CI):
```bash
# Generate keypair (encrypted private key)
cosign generate-key-pair
# → cosign.key, cosign.pub
# Sign
cosign sign --key cosign.key ghcr.io/bhodl/api:1.0.0
# Verify
cosign verify --key cosign.pub ghcr.io/bhodl/api:1.0.0
```
For HSM/KMS-backed keys:
```bash
cosign sign --key azurekms://my-vault.vault.azure.net/my-key ghcr.io/bhodl/api:1.0.0
cosign sign --key gcpkms://projects/PROJ/locations/LOC/keyRings/RING/cryptoKeys/KEY ...
cosign sign --key awskms://us-east-1/KEY-UUID ...
cosign sign --key hashivault://my-key ...
```
## Sign Blobs (Files, Not Containers)
```bash
# Sign a binary
cosign sign-blob --yes my-app.tar.gz \
--output-signature my-app.tar.gz.sig \
--output-certificate my-app.tar.gz.pem
# Verify
cosign verify-blob my-app.tar.gz \
--signature my-app.tar.gz.sig \
--certificate my-app.tar.gz.pem \
--certificate-identity-regexp="^https://github\.com/bhodl/" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"
```
For a release: sign the SHA-256 of the artifact:
```bash
cosign sign-blob --yes <(sha256sum my-app.tar.gz | cut -d' ' -f1)
```
## Attestations (Verifiable Metadata)
Attach SBOM, provenance, or custom predicates to an artifact:
```bash
# Generate SBOM (e.g., with syft)
syft ghcr.io/bhodl/api:1.0.0 -o spdx-json > sbom.spdx.json
# Attach as attestation
cosign attest --yes \
--predicate sbom.spdx.json \
--type spdxjson \
ghcr.io/bhodl/api:1.0.0
# Verify attestation
cosign verify-attestation \
--type spdxjson \
--certificate-identity-regexp="^https://github\.com/bhodl/" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
ghcr.io/bhodl/api:1.0.0
```
Predicate types:
- `slsaprovenance` — build provenance (SLSA spec)
- `spdxjson`, `cyclonedx` — SBOM formats
- `vuln` — vulnerability scan
- `custom` — your own JSON schema
## SLSA Provenance
SLSA (Supply-chain Levels for Software Artifacts) — framework for build attestation. Generate provenance via SLSA GitHub action:
```yaml
# .github/workflows/release.yml
permissions:
id-token: write
contents: read
packages: write
jobs:
build:
runs-on: ubuntu-latest
outputs:
digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v4
- id: build
run: |
docker buildx build --push --tag ghcr.io/bhodl/api:${{ github.sha }} . > digest.txt
echo "digest=$(cat digest.txt)" >> $GITHUB_OUTPUT
provenance:
needs: build
permissions:
actions: read
id-token: write
packages: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
with:
image: ghcr.io/bhodl/api
digest: ${{ needs.build.outputs.digest }}
registry-username: ${{ github.actor }}
secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }}
```
Attestation auto-pushed alongside image, signed by Sigstore.
## GitHub Actions OIDC Setup
Cosign keyless requires GitHub's `id-token` permission:
```yaml
permissions:
id-token: write # required for OIDC
contents: read
packages: write # if pushing to ghcr.io
jobs:
sign:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build & push
run: |
docker build -t ghcr.io/bhodl/api:${{ github.sha }} .
docker push ghcr.io/bhodl/api:${{ github.sha }}
- name: Install cosign
uses: sigstore/cosign-installer@v3.7.0
- name: Sign image
env:
COSIGN_EXPERIMENTAL: "true"
run: cosign sign --yes ghcr.io/bhodl/api:${{ github.sha }}
```
## Policy Enforcement (Kubernetes)
### Cosigned (deprecated) → policy-controller
```bash
helm install policy-controller \
sigstore/policy-controller \
--version 0.10.0 \
-n cosign-system --create-namespace
```
Define policy:
```yaml
apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
name: bhodl-images-must-be-signed
spec:
images:
- glob: ghcr.io/bhodl/**
authorities:
- keyless:
url: https://fulcio.sigstore.dev
identities:
- issuer: https://token.actions.githubusercontent.com
subjectRegExp: ^https://github\.com/bhodl/api/\.github/workflows/release\.yml@refs/heads/main$
```
Pods using `ghcr.io/bhodl/*` images that aren't signed by the right workflow → rejected.
### Kyverno Equivalent
```yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-signatures
spec:
validationFailureAction: Enforce
rules:
- name: check-image-signatures
match:
any:
- resources:
kinds: [Pod]
verifyImages:
- imageReferences:
- "ghcr.io/bhodl/*"
attestors:
- entries:
- keyless:
subject: "https://github.com/bhodl/*"
issuer: "https://token.actions.githubusercontent.com"
```
## Sign Git Commits — Gitsign
Sigstore replacement for GPG commit signing.
```bash
brew install gitsign
git config --global commit.gpgsign true
git config --global tag.gpgsign true
git config --global gpg.x509.program gitsign
git config --global gpg.format x509
# Sign a commit (browser opens for OAuth)
git commit -m "feat: add wallet sync"
# View signature
git log --show-signature -1
```
## Inspect Sigstore Records
```bash
# Search Rekor for transparency log entries
rekor-cli search --email user@example.com
rekor-cli search --artifact my-app.tar.gz
rekor-cli get --uuid 24296fb24b8ad77a...
# Search via web UI
open https://search.sigstore.dev
```
## Cosign vs Notary v2
| Feature | Cosign (Sigstore) | Notary v2 |
|---|---|---|
| Backed by | OpenSSF | CNCF |
| Standard for OCI signature | Yes (de facto) | Yes (formal) |
| Keyless (OIDC) | ✅ Native | Plugin |
| Transparency log | ✅ Rekor | Optional |
| Adoption | Wider (npm, GitHub, k8s) | Growing (registry vendors) |
| Key-based fallback | ✅ | ✅ |
| Attestations | ✅ in-toto, SBOMs | ✅ |
For most users: **Cosign**. For enterprise registries (JFrog Artifactory, Harbor) that prefer Notary v2 spec: both supported, often interoperable.
## Mobile App Signing (BHODL-style)
For wallet apps shipping APKs/IPAs/binaries publicly:
```yaml
# .github/workflows/release.yml
jobs:
release:
runs-on: macos-14
permissions:
id-token: write
contents: write
steps:
- uses: actions/checkout@v4
- name: Build APK
run: ./gradlew :apps:android:bundleRelease
- name: Build XCFramework
run: ./gradlew :shared:assembleSharedXCFramework
- uses: sigstore/cosign-installer@v3.7.0
- name: Sign artifacts
run: |
cosign sign-blob --yes apps/android/app/build/outputs/bundle/release/app-release.aab \
--output-signature app-release.aab.sig \
--output-certificate app-release.aab.pem
cosign sign-blob --yes Bhodl.xcframework.zip \
--output-signature Bhodl.xcframework.zip.sig \
--output-certificate Bhodl.xcframework.zip.pem
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: |
apps/android/app/build/outputs/bundle/release/app-release.aab
app-release.aab.sig
app-release.aab.pem
Bhodl.xcframework.zip
Bhodl.xcframework.zip.sig
Bhodl.xcframework.zip.pem
```
Users verify before installing:
```bash
cosign verify-blob app-release.aab \
--signature app-release.aab.sig \
--certificate app-release.aab.pem \
--certificate-identity="https://github.com/bhodl/wallet/.github/workflows/release.yml@refs/tags/v1.0.0" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"
```
Pair with reproducible builds (see `infrastructure/reproducible-builds`) for full chain: code → reproducible build → signed → verifiable.
## Anti-Patterns
| Anti-pattern | Why it's bad | Correct approach |
|---|---|---|
| Sharing private signing key in CI secrets | Single point of compromise | Use keyless OIDC |
| Skipping `--certificate-identity-regexp` on verify | Any signer accepted | Always pin identity |
| Signing on dev workflows | Pollutes Rekor with non-release signs | Sign only on tag/release workflows |
| Storing `cosign.key` in repo | Even encrypted, exposes ciphertext | Use HSM/KMS or keyless |
| `cosign verify` without `--certificate-oidc-issuer` | Accepts any issuer | Pin issuer |
| Bundling signatures inside the artifact | Can't verify externally | Distribute alongside (`.sig`, `.pem`) |
| No attestation for build provenance | Can't trace artifact → source | Use SLSA provenance |
| Signing only the latest tag, not each release | Old releases unverifiable | Sign every release |
| Ignoring Rekor inclusion proof during verify | Could miss tampering | `cosign verify` checks by default |
| Trusting `latest` tag | Mutable | Sign + verify by digest |
## Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| `Error: getting signer: getting key from KMS provider: getting OIDC token` | Missing OIDC permission | Add `id-token: write` to workflow |
| `verifying signature: no matching signatures` | Wrong certificate-identity-regexp | Loosen regex or check actual identity in Rekor |
| `cosign sign` opens browser locally but fails | Behind firewall, no OAuth callback | Use `--identity-token` flag with pre-fetched token |
| Signature pushed but `cosign verify` fails | Image moved/retagged | Verify by digest, not tag |
| `unsupported predicate type` | Custom predicate, no built-in type | Use `--type custom` and provide schema |
| Slow verify in CI | Network round trip to Rekor | Cache Rekor public key, use `--rekor-url` to point to mirror if needed |
| `policy-controller` denies known-good image | Identity regex too strict | Test with `cosign verify` first, match regex |
| `Error reading signing key` | Encrypted key + missing password | `COSIGN_PASSWORD` env or `--password-file` |
| Build artifact hash mismatch on verify | Artifact modified after signing | Re-sign; ensure no post-build mutation |
## When NOT to Use This Skill
| Scenario | Use Instead |
|----------|-------------|
| Apple Developer ID code signing | `mobile/ios-native` (build & distribution) |
| Android APK signing for Play Store | Android Gradle signing (`signingConfigs`) |
| Authenticode (Windows EXE/MSI) | Windows-specific signing tooling |
| GPG-style signing for legacy systems | GPG docs |
| Reproducible builds spec | `infrastructure/reproducible-builds` |
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.