·Canonical model

One canonical object. Adapters in, standards bridged.

Every structured Satsignal provenance anchor — from a CI build to an MCP-driven agent run — normalizes into the same canonical evidence object: satsignal.provenance.v1. One schema. One set of canonical bytes (SCJ-v1 + sha256 — Satsignal Canonical JSON, deliberately not RFC 8785/JCS; see §01 below). One on-chain commitment. Adapters (LangChain, MCP, OpenTelemetry, GitHub Action, webhook, blob, CLI, API) are ingestion routes into this model, not separate products. Raw file, blob, and raw-body webhook anchors share the same on-chain commitment primitive but hash bytes directly; they enter the canonical model when the caller supplies structured provenance metadata. Standards (C2PA, Sigstore, SLSA) bridge in by digest. This page is the public spine of the proof system.

01What the model is

A small, structured, canonicalizable record.

The current satsignal.provenance.v1 shape is seven top-level keys, three required, four optional, no unknown keys permitted. The record is canonicalized with Satsignal Canonical JSON v1 (SCJ-v1): every string (keys and values) is UTF-8 NFC-normalized, object keys are sorted by Unicode code point, the JSON is serialized with minimal separators and no whitespace, integers are bare decimals, and floats are rejected rather than rounded. The result is hashed with sha256 and the digest is committed to the public Bitcoin SV chain. The full canonical record ships back inside the .mbnt bundle so anyone can re-derive the bytes and verify the anchor without calling Satsignal again.

SCJ-v1 is deliberately not RFC 8785 (JCS). The two rules diverge in two places — SCJ-v1 sorts keys by code point where RFC 8785 sorts by UTF-16 code unit (they differ for supplementary-plane keys), and SCJ-v1 NFC-normalizes strings where RFC 8785 does not — so an off-the-shelf JCS library will compute a different hash on some inputs and a valid anchor will appear to fail. The normative rule, reference implementations, and the cross-language byte-parity corpus live at /spec-provenance §3. (RFC 8785 is used only by the separate satsignal.json.field.v1 selective-disclosure profile — a distinct canonicalization context.)

{
  "schema":  "satsignal.provenance.v1",
  "source":  { "type": "gitlab", "id": "acme/widgets" },
  "subject": { "type": "commit", "digest": "sha256:9f86d0..." },
  "identity":     { "actor": "ci-bot", "repo": "acme/widgets", ... },
  "attestations": [ { "type": "slsa", "digest": "sha256:1b4f0e..." } ],
  "claims":       { ... },
  "privacy":      { ... }
}

Status: draft 1, 2026-05-16. The implementer spec lives at /spec-provenance; the JSON Schema and the conformance suite (backward-compatibility rules, versioning policy, and test-vector layout) ship alongside in the spec directory.

02What it captures

The three required keys, four optional today, more arriving additively.

schema — required
The literal string satsignal.provenance.v1. Verifiers reject if missing.
source — required
Where the event came from: type + id. Examples: gitlab / github / otel-span / langfuse / webhook.
subject — required
What is being anchored: type + digest. Examples: commit / span_batch / file / policy_snapshot.
identity
Who / what acted: today an open string→string bag (actor, repo, agent_id, org_id, ...). In v1.x this will be broken out into typed slots — see "what’s coming" below.
attestations
External signatures Satsignal points at by digest: SLSA, in-toto, Sigstore / cosign, Rekor entries, npm provenance, PEP 740, C2PA manifests. Satsignal anchors the reference, not the payload — the signing standard stays the source of truth for who signed what.
claims
Caller-defined structured claims about the run (e.g. eval scores, decision categories, expected outputs). Free-form, but the canonical bytes are still byte-stable.
privacy
Declaration of what is and isn’t public in the manifest. Used by sealed-mode and selective-disclosure flows.

What’s coming additively in v1.x

The current identity bag will be supplemented by typed slots that name what an evidence reviewer cares about. All optional, all payload-free (digests and references only). Landing behind the same backward-compat rule: existing .mbnt bundles keep verifying byte-identically.

  • authority, principal, organization, agent — typed identifiers (NIST NCCoE software-agent identity/authorization pillars).
  • delegation_grant_digest + scopes — what the agent was authorized to do, by hash of the grant.
  • policy_snapshot_digest, run_scope, capture_policy — the precommitment hooks that turn "events were anchored" into "the declared capture policy was followed for this scope."
  • artifact_roles — input / output / intermediate / policy per referenced attestation.
  • signature_ref — reference to an OUTSIDE signature over the canonical manifest (cosign / JWS / VC / similar). Not an operator-signed Satsignal claim.
  • extensions — explicit container for vendor / custom data. Verifier may hash and preserve; MUST label "not interpreted by Satsignal." Unknown top-level keys remain invalid.
03Adapters are ingestion routes

Same canonical packet, many ways in.

The judgement rule for any adapter is one line: does it produce the same satsignal.provenance.v1 object as every other adapter? If yes, it’s a thin ingestion route. If it invents its own proof shape, that’s a bug against this page.

  • Direct APIPOST /api/v1/anchors (and the structured wrapper POST /api/v1/provenance/anchor).
  • CLI / Python helpersatsignal-cli and the stdlib agent_anchor.py helper.
  • MCPsatsignal-mcp server exposing anchor_* / lookup_hash / verify_bundle over stdio.
  • OpenTelemetrysatsignal-otel processor emitting anchors for marked spans.
  • LangChainlangchain-satsignal helpers for the policy-snapshot / commitment / evidence-bundle pattern.
  • GitHub ActionSteleet/satsignal-action@v0; analogous bash adapters for GitLab CI, Bitbucket Pipelines, Docker BuildKit, npm, PyPI.
  • Webhook — raw-body anchoring with per-source signature verifiers (Stripe, GitHub, Langfuse).
  • Object storagesatsignal-blob writes .mbnt + .proof.json sidecars next to objects in S3 / R2 / GCS / Azure Blob.

None of the above is a Satsignal product category. They are capture paths. The product is the canonical model on this page.

04Standards bridge in by digest

C2PA, Sigstore, SLSA, OpenTelemetry, MCP — complements.

Satsignal does not replace content-provenance metadata, keyless code signing, supply-chain attestation frameworks, observability standards, or agent-tool transports. It is the external time-and-integrity layer those standards leave open. The bridge for each is the same shape: take the canonical bytes the standard already produces, hash them, and anchor the digest as a satsignal.provenance.v1 record (the attestations array carries the reference).

See standards bridges for the per-standard worked patterns (C2PA / Sigstore / SLSA / OTel / MCP) and where each one’s authority ends and Satsignal’s begins.

05What a canonical proof proves

Integrity. Timing. Inclusion. Commitment. Nothing more — unless precommitted.

The four things this model establishes — and the things it deliberately does not — are documented as the canonical scope statement on what a proof proves. That page restates the same claims the verifier’s own “what this verifies” panel makes, so neither page can read as a stronger claim than the verifier itself makes.

The single line worth re-reading: a proof binds bytes, not truth. Wider claims (completeness, capture-policy adherence, authority) are possible only when the manifest precommitted them via run_scope, capture_policy, or policy_snapshot_digest before the run began.

06Spec, schema, verifier

Everything an external implementer needs.

  • /spec-provenance — normative implementer spec.
  • /spec-mbnt — the .mbnt bundle format that carries canonical manifests + chain references.
  • /spec-merkle-row — selective row reveal scheme for manifests + sealed sets.
  • /verify — offline-capable verifier (single static HTML file you can save and audit; a saved copy runs the hash and fingerprint checks offline — the on-chain lookup still needs a public block explorer).
  • /agents — agent-run integration recipe (policy-snapshot, per-decision commitment, evidence-bundle manifest, handoff JSON).