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 20260415
Status Draft
Supersedes

Table of Contents

  1. Abstract
  2. Motivation
  3. Background
  4. Goals and Non-Goals
  5. Proposed Solution
  6. Attestation Format
  7. Required Fields
  8. Build Pipeline Integration
  9. Signing Key Infrastructure
  10. Store Backend Changes
  11. Client Verification
  12. Developer Onboarding
  13. Policy Enforcement Timeline
  14. Compatibility Matrix
  15. Security Considerations
  16. Observability
  17. Rollout Roadmap
  18. Alternatives Considered
  19. Open Questions
  20. 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 (CVE20243094, 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 .kpkg built by a registered pipeline.
  • Store attestations alongside artifacts in the Store backend.
  • Verify attestation signatures before accepting uploads (Phase 2).
  • Enable optin clientside verification before installation (Phase 3).
  • Support Gitea Actions, GitHub Actions, and GitLab CI as build environments.
  • Support kpkg build local 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 .kpkg archive (only the archive itself is attested).
  • Endtoend 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.jsonl

7. 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

Source: ../home/koder/dev/koder/meta/docs/stack/rfcs/hub-RFC-003-build-attestation.md