For the complete documentation index, see llms.txt. This page is also available as Markdown.

Artifact catalog

Last reviewed: 2026-05-12 · Owner: Dev Infra · Linked phase: P3

Single source of truth for every artifact the CI pipelines publish. A consumer (deploy script, validator-team operator, third-party SDK integrator) can read this page top to bottom and find:

  1. Where the artifact lives (registry, scope, naming convention)

  2. How to authenticate to pull it

  3. What it's signed/attested with (so they know how to verify)

  4. How long it lives (retention policy)

  5. A working pull/install command (copy-pasteable)

Adding a new artifact? Append a section with the same five sub-headings.


1. Container images (GHCR)

Where

ghcr.io/kajlabs/lithosphere-{api,indexer,explorer}

Built by .github/workflows/publish-images.yaml on every push to main and on workflow_dispatch.

Tag scheme

Pushed by docker/metadata-action@v5:

Tag class
Example
Pushed when
Retention

latest

:latest

default-branch builds

rolling pointer, replaced

mainnet

:mainnet

every build (default tag)

rolling pointer, replaced

sha-<short>

:sha-3a14b0e

every build

90 days then pruned

semver

:v1.27.0, :1.27

tagged releases (v*)

kept forever

sha-<short> is the only addressable-and-immutable form for arbitrary commits — use it in the deploy script. Tag pointers like latest / mainnet move; verify the resolved digest separately.

Pruning runs weekly via .github/workflows/ghcr-retention.yaml (Sundays 04:00 UTC); manual dry-run via workflow_dispatch. Minimum-versions-to-keep floor is 50 per package as a safety net.

Authentication

Pulling from GHCR requires either:

  • A classic PAT with read:packages scope, OR

  • A GitHub Actions GITHUB_TOKEN (CI workflows only)

Signing & attestations

Every pushed image carries TWO independent signatures:

  1. Cosign keyless sign (Fulcio + Rekor transparency log)

  2. SLSA Build L2 provenance (in-toto, pushed as an OCI artifact)

Both verifications are wired into deploy-simple.yaml's Verify GHCR Image Signatures step. See supply-chain.md for the governance promotion path from advisory to blocking.

Reproducibility

All three Dockerfiles pin node:20-alpine to a sha256 digest so a rebuild months later produces a bit-identical image. Refresh the digest with scripts/refresh-base-image-digest.sh when upstream patches the base layer (Trivy will flag new CVEs as the signal).

Pull example


2. NPM packages (registry.npmjs.org)

Where

Package
Path
Provenance

@lithosphere/blockchain-core

Makalu/packages/blockchain-core

@lithosphere/sdk

Makalu/packages/sdk

Published by .github/workflows/release.yamlpublish_npm job. Tag- gated: the job only fires when release-please merges a Release PR and pushes a v<next> tag.

Authentication

Public packages, no auth required to pnpm install.

Internal publishing path uses NPM_TOKEN (granular access token, scope @lithosphere). Documented in docs/governance/release-process.md.

Signing & attestations

Published with npm publish --provenance so every release has an npm provenance attestation linking back to the exact GitHub Actions run + commit SHA.

Verify:

Versioning

release-please controls bumps per conventional-commit type (see release-process.md). Both packages release together with synchronised versions for now — single rolling Release PR.

Install example


3. Contract artifacts (GitHub Releases)

Where

Bundle attached to every v* GitHub Release at https://github.com/KaJLabs/Lithosphere/releases/download/v<X.Y.Z>/lithosphere-contracts-v<X.Y.Z>.tar.gz.

Built by release.yaml's contract-bundle step from the freshly compiled Hardhat artifacts.

Bundle contents

Signing & attestations

  • lithosphere-contracts-v<X.Y.Z>.sha256 accompanies the bundle for integrity checking.

  • The release itself is GPG-signed by release-please's bot identity.

  • Source-of-truth ABIs also ship inside @lithosphere/blockchain-core on npm; drift between the two surfaces is gated by abi-sync-check in ci-contracts.yaml.

Download example


4. Machine-readable API contracts

OpenAPI (REST)

  • Source: docs/api-reference/openapi.yaml

  • Drift gates: openapi-sync-check (route set matches Express routers) + openapi-codegen-check (SDK types regenerable from YAML)

  • Consumer: Makalu/packages/sdk/src/generated/openapi.ts (auto-generated, also exported from @lithosphere/sdk)

GraphQL schema

  • Source: docs/api-reference/schema.graphql

  • Drift gate: schema-sync-check (Makalu/api/scripts/verify-schema-in-sync.ts)

Both files are first-class artifacts: a third-party integrator can fork the YAML/SDL and codegen against it without running our server.


5. SBOMs

anchore/sbom-action emits an SPDX 2.3 SBOM alongside every image push in publish-images.yaml. The SBOM is attached to the GitHub Release as lithosphere-{api,indexer,explorer}-sbom.spdx.json.

Verify a SLSA attestation references the SBOM:


Cross-references

  • Signing/attestation policy and verification UX: supply-chain.md

  • Release flow + version bumps: release-process.md

  • Rotation of the keys behind the above (Cosign Fulcio, npm provenance, AWS OIDC): key-rotation-runbook.md

  • License obligations on consumed packages: license-policy.md


Open follow-ups (out of P3 closure scope)

  • Multi-arch image builds (linux/arm64 alongside linux/amd64). Deferred — production EC2 is x86 and a 2× build-time cost has no current consumer. Revisit when Graviton becomes a target or Mac developer ergonomics demand it.

  • Image promotion to a second registry (e.g., AWS ECR mirror). Deferred — GHCR availability hasn't been a reliability concern.

  • CycloneDX SBOM alongside SPDX. Same content, different schema; ship if a downstream tool requires it.

Last updated