Hub RFC 003 build attestation
RFC-003 — Build Attestation for Koder Hub
| Field | Value |
|---|---|
| RFC | RFC-003 |
| Title | Build Attestation for Koder Hub |
| Author | Koder Engineering |
| Date | 2026 |
| Status | Draft |
| Supersedes | — |
Table of Contents
- Abstract
- Motivation
- Background
- Goals and Non-Goals
- Proposed Solution
- Attestation Format
- Required Fields
- Build Pipeline Integration
- Signing Key Infrastructure
- Store Backend Changes
- Client Verification
- Developer Onboarding
- Policy Enforcement Timeline
- Compatibility Matrix
- Security Considerations
- Observability
- Rollout Roadmap
- Alternatives Considered
- Open Questions
- References
1. Abstract
This RFC proposes implementing SLSA Level 2 build provenance attestation for all packages published to the Koder Hub. Attestations are generated by CICD pipelines at build time using the in-toto Attestation Framework with a SLSA Provenance v1.0 predicate, signed with Sigstorecosign. The Store backend stores, verifies, and (in later phases) enforces attestation presence. The koder-hub client gains the ability to verify attestations before installation.
2. Motivation
2.1 The Supply Chain Threat
Software supply chain attacks have become the dominant vector for large-scale malware distribution. Notable incidents:
- *z utils (CVE
20243094, March 2024)* A malicious actor contributed code to a widely-deployed compression library over two years, eventually injecting a backdoor in the release build. The compromise was in the build output, not the source. - *pm malicious packages* Hundreds of typosquatted and hijacked npm packages have delivered credential stealers, cryptominers, and reverse shells to developer machines.
- *olarWinds (2020)* Build system compromise allowed attackers to inject malicious code into signed official releases.
2.2 The Koder Hub Attack Surface
The Koder Hub distributes .kpkg packages to end users. A publisher's account (Gitea credentials, pipeline token) could be compromised. Without attestation, the Store cannot distinguish:
- A legitimate package built by the publisher's verified pipeline from a known source commit.
- A package built by an attacker who compromised the publisher's upload credentials.
- A package where the binary was replaced after the build (build artifact substitution).
2.3 Current State
The Store currently accepts any .kpkg submitted with a valid publisher API key. There is no verification that the binary corresponds to any particular source commit, build environment, or pipeline.
2.4 Why SLSA Level 2
SLSA (Supply chain Levels for Software Artifacts) Level 2 requires:
- *ersion controlled source* the source used for the build is from a version control system with a specific commit SHA.
- *uthenticated build service* the build was performed by a CI/CD system, not on a developer's local machine.
- *rovenance generated by the build service* the attestation is generated and signed by the build service itself, not by the developer.
Level 2 is the right target for this phase: it eliminates the most common attack vectors (compromised developer machine, post-build binary substitution) without requiring the more complex hermetic build environments of Level 3+.
3. Background
3.1 in-toto Attestation Framework
in-toto is a framework for securing software supply chains. An attestation is a signed statement of the form:
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [ { "name": "koder-hub-linux-amd64.kpkg", "digest": { "sha256": "..." } } ],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": { ... }
}The statement is wrapped in a DSSE (Dead Simple Signing Envelope) and signed with a key managed by Sigstore.
3.2 SLSA Provenance v1.0
The SLSA Provenance predicate captures the full provenance of a build artifact:
{
"buildDefinition": {
"buildType": "https://slsa-framework.github.io/github-actions-buildtypes/workflow/v1",
"externalParameters": { "workflow": { "ref": "refs/heads/main", "repository": "..." } },
"internalParameters": {},
"resolvedDependencies": [
{ "uri": "git+https://flow.koder.dev/...", "digest": { "sha1": "<commit-sha>" } }
]
},
"runDetails": {
"builder": { "id": "https://flow.koder.dev/koder/koder-hub/.actions/workflows/release.yml" },
"metadata": {
"invocationId": "https://flow.koder.dev/.../runs/12345",
"startedOn": "2026-04-15T10:00:00Z",
"finishedOn": "2026-04-15T10:05:00Z"
}
}
}3.3 Sigstore / cosign
Sigstore is a Linux Foundation project providing free, transparent code signing infrastructure. cosign is its CLI tool for signing and verifying container images and arbitrary blobs.
For Koder's use case, we use cosign in keyless mode during Phase 1 (Sigstore's ephemeral key infrastructure, identity backed by OIDC) and migrate to Koder-managed keys in Phase 2.
4. Goals and Non-Goals
Goals
- Generate SLSA Level 2 attestation for every
.kpkgbuilt by a registered pipeline. - Store attestations alongside artifacts in the Store backend.
- Verify attestation signatures before accepting uploads (Phase 2).
- Enable opt
in clientside verification before installation (Phase 3). - Support Gitea Actions, GitHub Actions, and GitLab CI as build environments.
- Support
kpkg buildlocal builds with a developer-signed attestation (lower trust level, labeled as such).
Non-Goals
- SLSA Level 3 (hermetic, reproducible builds): out of scope for this RFC.
- Signing individual files within a
.kpkgarchive (only the archive itself is attested). - End
toend encryption of attestations. - Attestation for packages distributed outside the Koder Hub (sideloading).
5. Proposed Solution
Every .kpkg published to the Koder Hub must include a SLSA Provenance v1.0 attestation, signed with a key registered to the build pipeline. The attestation is generated at the end of the build pipeline, after the .kpkg is assembled and its SHA-256 digest is known.
The Store backend exposes an attestation submission endpoint alongside the existing package upload endpoint. In Phase 1 the attestation is stored and displayed. In Phase 2 the backend rejects uploads without a valid attestation. In Phase 3 the client verifies the attestation locally before installation.
6. Attestation Format
6.1 Envelope
Attestations are stored as DSSE (Dead Simple Signing Envelope) JSON files:
{
"payloadType": "application/vnd.in-toto+json",
"payload": "<base64-encoded in-toto Statement>",
"signatures": [
{
"keyid": "https://hub.koder.dev/ca/builders/koder-flow-actions/keys/1",
"sig": "<base64-encoded signature>"
}
]
}6.2 Statement
The decoded payload is an in-toto Statement v1:
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "<package-name>-<version>-<platform>.kpkg",
"digest": {
"sha256": "<hex-encoded SHA-256 of the .kpkg file>"
}
}
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": { ... }
}6.3 File Naming
Attestation files are named <artifact-filename>.intoto.jsonl and submitted alongside the .kpkg. Example:
koder-hub-2.1.0-linux-amd64.kpkg
koder-hub-2.1.0-linux-amd64.kpkg.intoto.jsonl7. Required Fields
The following fields are mandatory in the SLSA Provenance predicate for an attestation to be accepted by the Store:
| Field | Description | Example |
|---|---|---|
buildDefinition.buildType |
URI identifying the build type schema | https://flow.koder.dev/buildtypes/gitea-actions/v1 |
buildDefinition.resolvedDependencies[].uri |
Git repository URL | git+https://flow.koder.dev/koder/koder-hub |
buildDefinition.resolvedDependencies[].digest.sha1 |
Source commit SHA | abc123def456... |
runDetails.builder.id |
URL of the pipeline definition | https://flow.koder.dev/koder/koder-hub/.actions/workflows/release.yml@refs/tags/v2.1.0 |
runDetails.metadata.invocationId |
URL of the specific pipeline run | https://flow.koder.dev/koder/koder-hub/actions/runs/12345 |
runDetails.metadata.startedOn |
ISO 8601 build start time | 2026-04-15T10:00:00Z |
runDetails.metadata.finishedOn |
ISO 8601 build end time | 2026-04-15T10:05:00Z |
The subject[].digest.sha256 must exactly match the SHA-256 of the submitted .kpkg file. The Store backend validates this match before storing the attestation.
8. Build Pipeline Integration
8.1 Gitea Actions (Koder Flow)
# .gitea/workflows/release.yml
jobs:
build-and-attest:
runs-on: ubuntu-latest
permissions:
id-token: write # required for keyless signing
contents: read
steps:
- uses: actions/checkout@v4
- name: Build kpkg
run: kpkg build --output dist/
- name: Compute SHA-256
id: sha
run: |
SHA=$(sha256sum dist