Skip to content
Back to skills

Ct Provenance Keeper

ASecurity

Generates in-toto v1 attestations, SLSA-level provenance records, SBOMs (CycloneDX or SPDX), and sigstore/cosign signatures for published artifacts. Invoked by ct-artifact-publisher as a delegation for signing and attestation. Records the full commit, then build, then artifact, then attestation, then registry chain in .cleo/releases.json and rejects publishes whose digest does not match the attestation. Triggers when artifact-publish reaches the provenance step or when a release needs SLSA L2...

  • 160 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 28, 2026
testingrustbashdockertestinggitsecurity

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned October 1, 2026

npx -y skills add kryptobaseddev/cleo --skill ct-provenance-keeper --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ct Provenance Keeper?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ct Provenance Keeper
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/kryptobaseddev-ct-provenance-keeper/badge)](https://www.skillsdirectory.com/skills/kryptobaseddev-ct-provenance-keeper)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ct-provenance-keeper
description: "Generates in-toto v1 attestations, SLSA-level provenance records, SBOMs (CycloneDX or SPDX), and sigstore/cosign signatures for published artifacts. Invoked by ct-artifact-publisher as a delegation for signing and attestation. Records the full commit, then build, then artifact, then attestation, then registry chain in .cleo/releases.json and rejects publishes whose digest does not match the attestation. Triggers when artifact-publish reaches the provenance step or when a release needs SLSA L2+ attestation."
metadata:
  version: 1.0.2
  tier: on-demand
  install: harness
  covers:
    - packages/core/src/validation/protocols/cant/provenance.cant
    - packages/core/src/validation/protocols/protocols-markdown/provenance.md
  lastReviewed: 2026-09-28
  stability: stable
---

# Provenance Keeper

## Overview

Sub-protocol of ct-artifact-publisher. Generates cryptographic evidence for every published artifact: SHA-256 digests, in-toto Statement v1 attestations, SBOMs (CycloneDX 1.5+ or SPDX 2.3+), and signatures via sigstore/cosign keyless or gpg. Records the full commit-to-registry chain in `.cleo/releases.json`, verifies chain integrity before publishing attestations, and refuses to bind an attestation to an artifact whose digest does not match.

## Core Principle

> Provenance is non-falsifiable or it is not provenance.

## Immutable Constraints

| ID | Rule | Enforcement |
|----|------|-------------|
| PROV-001 | Chain MUST be recorded from source commit to published artifact. | `record_release()` writes the full chain; missing links set `metadata.completeness: incomplete`. |
| PROV-002 | SHA-256 digest MUST be computed for every produced artifact. | Digest binds to the in-toto subject; mismatch exits 93. |
| PROV-003 | Attestation MUST be in in-toto Statement v1 format. | Validator rejects other schemas; exit 94. |
| PROV-004 | SLSA Build Level MUST be recorded (L1 minimum). | Level stored in `releases.json`; L1 is the floor. |
| PROV-005 | Provenance record MUST be stored in `.cleo/releases.json` via `record_release()`. | Missing record fails validation. |
| PROV-006 | Chain integrity MUST be verified before publishing the attestation. | `verify_provenance_chain()` runs before emit. |
| PROV-007 | Manifest entry MUST set `agent_type: "provenance"`. | Validator rejects any other value. |

## SLSA Compliance Levels

The skill records the achieved SLSA level in every provenance record. A minimum of L1 is mandatory; L3 is the target for npm + docker releases via OIDC keyless signing.

| Level | Requirements | Typical achievement |
|-------|--------------|---------------------|
| L1 | Provenance exists, basic metadata recorded. | Any run of the skill produces at least L1. |
| L2 | Signed provenance, build on a hosted platform. | Requires sigstore keyless OR gpg signing + CI build. |
| L3 | Non-falsifiable provenance, hermetic build environment. | CI runs with isolated runners and OIDC-bound identity (this is the default for npm + docker releases). |
| L4 | Reproducible builds, two-party review, all deps signed. | Rare; requires pinned dependencies and second-reviewer sign-off. |

Full requirements and per-level checklists are in [references/slsa.md](references/slsa.md).

## Signing Methods

Three methods are supported; the skill selects based on `release.security.provenance.signing.method`:

| Method | Command | Output | When to use |
|--------|---------|--------|-------------|
| `sigstore` (default, keyless) | `cosign sign-blob --yes --output-signature <sig> --output-certificate <cert> <artifact>` | `.sig` + `.pem` + Rekor transparency log entry | Default. Requires OIDC identity (CI). |
| `sigstore` (key) | `cosign sign-blob --key <ref> <artifact>` | `.sig` | Offline or self-hosted without OIDC. |
| `gpg` | `gpg --detach-sign --armor -u <key-id> <artifact>` | `.asc` | Legacy workflows, regulated environments. |
| `none` | (skip) | (none) | SLSA L1 only; explicit opt-out. |

The decision matrix, including `GPG_KEY_ID` and OIDC trusted-publisher setup, lives in [references/signing.md](references/signing.md).

## Provenance Chain

The skill walks and records the full chain for every release:

```
commit  -->  build  -->  artifact  -->  attestation  -->  registry
  |           |            |               |                |
  sha        log         digest        signature        published
  |           |            |               |                |
source    env capture   sha256 file    cert bundle        URL
```

Each link MUST reference the previous link's output. The chain is append-only in `releases.json`: no link is ever modified after creation. Missing links are recorded as `incomplete`, never elided. Offline verification MUST be possible — every digest is stored locally, not fetched per verification.

## SBOM Generation

SBOMs are mandatory for artifacts with runtime dependencies (docker images, npm packages) and recommended for standalone binaries.

| Format | Spec | Use case |
|--------|------|----------|
| CycloneDX | 1.5+ | Default. Machine-readable JSON. |
| SPDX | 2.3+ | Compliance-focused (FedRAMP, regulated environments). |

Storage locations:

- `.cleo/sbom/<artifact-name>-<version>.cdx.json` (CycloneDX)
- `.cleo/sbom/<artifact-name>-<version>.spdx.json` (SPDX)
- `<artifact>.sbom.json` (bundled alongside the artifact)

Generate with `syft packages dir:. -o cyclonedx-json` or equivalent.

## `.cleo/releases.json` Record Structure

Each release appends a record in the following shape. The skill MUST populate every field that can be known; the remainder stay as explicit nulls (never absent).

```json
{
  "version": "v2026.4.5",
  "commitSha": "3a2f1e9c4b8d7e6a5f2c1d0e9f8a7b6c5d4e3f2a",
  "gitTag": "v2026.4.5",
  "buildInvocationId": "gh-actions-12345",
  "builder": { "id": "https://github.com/actions/runner" },
  "artifacts": [
    {
      "type": "npm-package",
      "name": "@cleocode/core",
      "sha256": "a1b2c3...",
      "registry": "https://registry.npmjs.org",
      "publishedAt": "2026-04-06T19:50:00Z",
      "attestation": ".cleo/attestations/v2026.4.5-core.intoto.jsonl",
      "signature": {
        "method": "sigstore",
        "keyless": true,
        "transparencyLog": {
          "index": "123456789",
          "url": "https://rekor.sigstore.dev"
        }
      }
    }
  ],
  "sbom": {
    "format": "CycloneDX",
    "specVersion": "1.5",
    "path": ".cleo/sbom/cleocode-core-2026.4.5.cdx.json"
  },
  "slsaLevel": "SLSA_BUILD_LEVEL_3",
  "chainVerified": true,
  "recordedAt": "2026-04-06T19:51:00Z"
}
```

## Integration

Validate the provenance entry through `cleo check protocol`:

```bash
cleo check protocol provenance \
  --task-id T4902 \
  --has-attestation true \
  --has-sbom true
```

Exit code 0 = provenance record is complete and verified. Exit code 90 = invalid config. Exit code 91 = signing key missing. Exit code 92 = signature invalid. Exit code 93 = digest mismatch (refuse to bind attestation). Exit code 94 = attestation format or subject is invalid.

## Anti-Patterns

| Pattern | Problem | Solution |
|---------|---------|----------|
| Skipping digest computation | Chain integrity cannot be verified (violates PROV-002) | Always compute SHA-256 for every artifact before attesting |
| Hardcoding signing keys in config | Key exposure, credentials in VCS | Reference env vars by name; actual keys stay in the environment |
| Generating attestation without matching digest | Attestation binds to the wrong artifact (violates PROV-006) | Compute the digest first, then attest; refuse to attest a mismatched pair |
| Publishing artifact before signing | Cannot retrofit signatures after publish | Sign before push; the sub-protocol order is build → sign → publish |
| Modifying provenance records after creation | Breaks immutability, corrupts the audit trail | `.cleo/releases.json` is append-only; never rewrite old entries |
| Skipping SBOM for artifacts with dependencies | Hidden supply-chain risk | Generate CycloneDX for every artifact with runtime deps |
| Using SHA-1 or MD5 for digests | Cryptographically broken; non-compliant with SLSA | SHA-256 is mandatory; SHA-512 is optional for high-security contexts |
| Storing private keys inside `.cleo/` | Key compromise if the repo is leaked | Keys live in the keystore / OIDC / HSM — never in the worktree |

## Critical Rules Summary

1. Compute SHA-256 for every artifact; bind the attestation to the exact digest.
2. Produce attestations in in-toto Statement v1 format only.
3. Record the full chain in `.cleo/releases.json` via `record_release()`.
4. Verify chain integrity before publishing the attestation.
5. Default to sigstore keyless signing via OIDC in CI; fall back to gpg only when configured.
6. Generate CycloneDX SBOMs for every artifact with runtime dependencies.
7. `.cleo/releases.json` is append-only; never mutate past entries.
8. Validate every run via `cleo check protocol provenance`.

Files in this skill

  • SKILL.md8.5 KB
  • manifest-entry.json906 B
  • references/signing.md5.2 KB
  • references/slsa.md4.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.