If your supply-chain security pipeline already speaks SLSA (running Sigstore, Cosign, or the SLSA GitHub Generator), this guide shows you where OpenChainGraph's buildType URI fits into that picture. OCG's buildType field serves the same purpose as SLSA's: it makes the hash construction algorithm explicit, auditable, and verifiable without needing to read source code. The result is an OCG artifact that satisfies SLSA Level 1 provenance requirements out of the box, with a clear path to Level 2 and Level 3 via the in-toto envelope in Guide #3.
buildType means in OCGIn OpenChainGraph v0.3, buildType is an optional URI field that identifies the exact algorithm used to construct execution_hash. The default value, and the one all conformant OCG tools use unless they declare otherwise, is:
https://ainumbers.co/chaingraph/context/v0.2#WebCryptoSHA256
This URI encodes three facts in a single string: the spec version (v0.2), the Web API used (WebCrypto), and the hash algorithm (SHA256). A verifier reading this field knows, without running the tool or reading its source, exactly how to independently reproduce and check the hash.
The construction procedure the URI refers to is deterministic: sort policy_parameters and output_payload keys recursively, serialize with JSON.stringify, encode to UTF-8, and call crypto.subtle.digest('SHA-256', bytes). The resulting 32-byte digest is hex-encoded and stored as execution_hash. No implementation-specific behaviour, no external service, no clock.
A bare algorithm name like "SHA-256" is ambiguous: it says nothing about the preimage: what gets hashed, in what order, with what serialization. A URI makes the full construction procedure resolvable. This is the same reasoning SLSA adopted for its own buildType field, and why OCG follows the same convention.
Here is a complete OCG v0.3 artifact showing the buildType field in context:
{
"@context": "https://ainumbers.co/chaingraph/context/v0.3",
"tool_id": "basel_rwa_calculator_v2",
"mandate_type": "capital_requirement",
"policy_parameters": {
"exposure_class": "corporate",
"risk_weight": 0.75,
"ead": 1000000
},
"output_payload": {
"rwa": 750000,
"capital_charge": 60000
},
"execution_hash": "sha256:a4c2f8e1b7d93...", // computed per buildType below
"buildType": "https://ainumbers.co/chaingraph/context/v0.2#WebCryptoSHA256", // ← THIS
"chain": {
"parent_hashes": [],
"depth": 0,
"chain_name": "q3_capital_review"
},
"audit_signature": { /* in-toto envelope — see Guide #3 */ }
}
buildType maps to SLSA provenanceSLSA (Supply-chain Levels for Software Artifacts) provenance attestations use a buildType URI to identify the build system that produced an artifact, for example https://github.com/slsa-framework/slsa-github-generator/... for a GitHub Actions build. OCG uses the same field for the same purpose in the financial computation context: identify the computation system and its construction procedure.
The mapping between an OCG artifact and the fields of a SLSA v1.0 provenance statement is direct:
| SLSA v1.0 Field | OCG Equivalent | Notes |
|---|---|---|
| buildType | buildType |
Identifies the construction procedure. OCG default: …#WebCryptoSHA256 |
| builder.id | tool_id |
The tool that ran the computation, the OCG equivalent of the build system |
| invocation.configSource | policy_parameters |
The inputs that parameterized the computation, equivalent to build configuration |
| metadata.buildFinishedOn | timestamp (if present) |
OCG allows an optional ISO 8601 timestamp; not required for hash validity |
| subject[].digest.sha256 | execution_hash |
The content-addressed identifier for this artifact, the primary verifiable claim |
| materials[].uri | parent_hashes[] |
Each parent hash identifies an input artifact, equivalent to SLSA build materials |
Software SLSA provenance attests to how a binary was built. OCG provenance attests to how a financial decision was computed. The cryptographic structure is identical (buildType, inputs, outputs, hash), but the payload is a compliance artifact, not a compiled artifact. This makes OCG attestations directly composable with SLSA-aware audit tooling.
If your organization already runs a SLSA-compliant CI/CD pipeline, OCG artifacts can be stored in the same attestation registry (for example, an OCI registry with cosign attachments or a Rekor transparency log entry) alongside your software build attestations. The field structure is compatible enough that existing SLSA parsers can extract and index the key fields without modification.
SLSA defines four levels (0–3) of increasing provenance strength. Here is exactly what an OCG v0.3 artifact satisfies at each level, and what additional steps are required to move up:
| SLSA Level | Requirement | OCG Status | What to do |
|---|---|---|---|
| Level 0 | No guarantees | N/A: OCG is always at least Level 1 | – |
| Level 1 | Provenance exists and identifies how the artifact was produced | ✓ Satisfied by any OCG v0.3 artifact with buildType, tool_id, policy_parameters, and execution_hash present |
Nothing. A conformant OCG artifact is SLSA Level 1 by construction. |
| Level 2 | Provenance is authenticated: signed by the build system, not just the developer | Achievable by adding a signed in-toto envelope as audit_signature |
Wrap execution_hash in a DSSE envelope, sign with Ed25519, store in audit_signature. See Guide #3 (in-toto) and Guide #4 (Ed25519). |
| Level 3 | Provenance is non-falsifiable: produced in a hardened, isolated environment; verifiable by a third party | Partially achievable: the hash is independently recomputable by any third party; isolation depends on your deployment | Run OCG tools in an isolated, audited environment (e.g., a sealed browser context or a WebAssembly sandbox). Submit execution_hash to a transparency log (Rekor). Third-party auditors can then verify independently. |
OCG tools run entirely in the browser: client-side, zero-egress. This means the computation is transparent (anyone can inspect the source), and the hash is independently recomputable (anyone can re-run the algorithm). SLSA Level 3's isolation requirement is typically interpreted as "not modifiable by the build system operator." For OCG, the equivalent claim is that the hash function is specified by buildType and cannot be swapped at runtime without changing the buildType URI, which a verifier will detect.
If your pipeline requires a formal SLSA v1.0 provenance JSON (e.g., for submission to Rekor or an OCI attestation layer), you can mechanically derive one from any OCG artifact. The conversion requires no information beyond what is already in the OCG artifact.
// Input: a conformant OCG v0.3 artifact object function ocgToSlsaProvenance(artifact) { const { tool_id, buildType, policy_parameters, output_payload, execution_hash, chain, timestamp } = artifact; return { "_type": "https://in-toto.io/Statement/v0.1", "predicateType": "https://slsa.dev/provenance/v1", // subject: the artifact being attested "subject": [{ "name": tool_id, "digest": { "sha256": execution_hash.replace(/^sha256:/, '') } }], "predicate": { "buildDefinition": { "buildType": buildType || "https://ainumbers.co/chaingraph/context/v0.2#WebCryptoSHA256", "externalParameters": policy_parameters, // the inputs "internalParameters": {} // no server-side state }, "runDetails": { "builder": { "id": "https://ainumbers.co/tools/" + tool_id, "version": {} }, "metadata": { "invocationId": execution_hash, // hash is the stable run ID "startedOn": timestamp || null, "finishedOn": timestamp || null }, "byProducts": [{ // OCG-specific additions "name": "output_payload", "content": btoa(JSON.stringify(output_payload)) }] } } }; } // Usage const provenance = ocgToSlsaProvenance(myArtifact); console.log(JSON.stringify(provenance, null, 2));
The resulting object is a valid SLSA v1.0 provenance predicate wrapped in an in-toto Statement envelope. It can be submitted directly to Rekor via the cosign attest command, or attached to an OCI image manifest as a referrer.
# Write the provenance statement to a file node -e " const art = require('./artifact.json'); const prov = ocgToSlsaProvenance(art); require('fs').writeFileSync('provenance.json', JSON.stringify(prov)); " # Sign and submit to Rekor via cosign cosign attest \ --predicate provenance.json \ --type slsaprovenance1 \ --key cosign.key \ --rekor-url https://rekor.sigstore.dev \ "${ARTIFACT_URI}" # Verify: any party can check the Rekor entry cosign verify-attestation \ --type slsaprovenance1 \ --certificate-identity-regexp ".*ainumbers.co.*" \ "${ARTIFACT_URI}"
buildType URIs for non-standard preimage constructionThe default buildType is sufficient for all tools shipping with the OCG suite. Vendors who need a different hash construction (for example, HMAC-SHA256 with a shared secret, a SHA3-256 variant, or a non-JSON serialization format) must declare a custom buildType URI. The rules are straightforward.
A custom buildType URI must:
#HMAC-SHA256){
"@context": "https://ainumbers.co/chaingraph/context/v0.3",
"tool_id": "proprietary_scoring_v1",
"buildType": "https://example-vendor.com/ocg-buildtype/v1#HMAC-SHA256",
// The URI above must resolve to documentation describing:
// 1. What fields are included in the preimage
// 2. Key derivation procedure
// 3. Serialization format
// 4. Any canonical ordering rules
"execution_hash": "sha256:b9f3a2c1..."
}
A non-default buildType means that generic OCG verifiers (including the AINumbers tools and the OpenChainGraph chain validator) will not be able to independently recompute execution_hash. They can still read and store the artifact, but verification is deferred to the vendor's own tooling. If interoperability with third-party verifiers matters, stay with the default buildType unless you have a compelling reason to deviate.
execution_hash against buildTypeIndependent verification is the point. Any party (auditor, regulator, counterparty) can verify an OCG artifact's integrity without contacting the issuing system, provided they have the artifact JSON and the buildType URI to look up the construction procedure.
For the default buildType, the verification procedure is a single browser-runnable function:
/** * Verify an OCG artifact's execution_hash against its declared buildType. * Works in any browser or Node.js 18+ environment. * * buildType: https://ainumbers.co/chaingraph/context/v0.2#WebCryptoSHA256 * Preimage: JSON.stringify({ policy_parameters, output_payload }) * with keys sorted recursively, no whitespace */ async function verifyOcgArtifact(artifact) { const { buildType, policy_parameters, output_payload, execution_hash } = artifact; // Enforce default buildType — reject unknown constructions if (buildType !== "https://ainumbers.co/chaingraph/context/v0.2#WebCryptoSHA256") { throw new Error(`Unknown buildType: ${buildType}. Cannot verify.`); } // 1. Build preimage: recursively sort all object keys function sortedStringify(obj) { if (obj === null || typeof obj !== 'object' || Array.isArray(obj)) { return JSON.stringify(obj); } const sorted = Object.fromEntries( Object.keys(obj).sort().map(k => [k, JSON.parse(sortedStringify(obj[k]))]) ); return JSON.stringify(sorted); } const preimage = sortedStringify({ policy_parameters, output_payload }); // 2. Hash via WebCrypto SHA-256 const encoded = new TextEncoder().encode(preimage); const hashBuf = await crypto.subtle.digest('SHA-256', encoded); const hashHex = Array.from(new Uint8Array(hashBuf)) .map(b => b.toString(16).padStart(2, '0')).join(''); // 3. Compare to stored hash const expected = "sha256:" + hashHex; const valid = expected === execution_hash; return { valid, expected, stored: execution_hash, mismatch: valid ? null : { expected, stored: execution_hash } }; } // Usage const result = await verifyOcgArtifact(artifact); if (!result.valid) { console.error('Hash mismatch — artifact may have been tampered with', result.mismatch); } else { console.log('✓ Artifact integrity verified', result.stored); }
The same logic runs in Python using hashlib and standard json, or in any other language with a SHA-256 implementation. The buildType URI is the stable reference that tells verifiers which procedure to run.
import hashlib, json def sorted_stringify(obj): if not isinstance(obj, dict): return json.dumps(obj, separators=(',', ':')) sorted_obj = {k: json.loads(sorted_stringify(obj[k])) for k in sorted(obj)} return json.dumps(sorted_obj, separators=(',', ':')) def verify_ocg_artifact(artifact): preimage = sorted_stringify({ "output_payload": artifact["output_payload"], "policy_parameters": artifact["policy_parameters"] }) digest = hashlib.sha256(preimage.encode()).hexdigest() expected = f"sha256:{digest}" stored = artifact["execution_hash"] return { "valid": expected == stored, "expected": expected, "stored": stored } result = verify_ocg_artifact(artifact) print("✓ Valid" if result["valid"] else f"✗ Mismatch: {result}")
The preimage sorts policy_parameters and output_payload top-level keys recursively before serializing. This is what makes the hash deterministic across environments: JavaScript engines do not guarantee object key order, so a sort step is required. The buildType URI's specification document codifies this requirement explicitly.
buildType with Sigstore and CosignSigstore's Cosign and Rekor are the most widely adopted open-source tools for SLSA attestation signing and transparency. OCG artifacts compose with this ecosystem through two integration points: the SLSA provenance conversion from §4, and the in-toto envelope from Guide #3.
The flow looks like this:
1. OCG tool runs in browser └─ emits artifact.json with execution_hash + buildType 2. Pipeline picks up artifact.json └─ calls ocgToSlsaProvenance(artifact) → provenance.json 3. cosign attest signs provenance.json with vendor Ed25519 key └─ produces DSSE-wrapped attestation 4. cosign pushes attestation to Rekor transparency log └─ Rekor returns a UUID entry 5. Auditor (regulator, counterparty) independently: a. Fetches artifact.json b. Re-runs verification (§6) → confirms execution_hash c. Looks up Rekor entry → confirms signed attestation d. Confirms buildType URI resolves to published spec ✓ Full chain of custody, no trusted third party required
Steps 1 and 2 are OCG-specific. Steps 3–5 are standard Sigstore operations that work unchanged regardless of whether the attested artifact is a Docker image, a Go binary, or an OCG financial computation artifact. The buildType URI is what makes step 5d possible: it gives the auditor a stable reference to the construction procedure without requiring access to the tool's source code.
Once an OCG artifact's provenance is logged in Rekor, it cannot be removed or altered; only new entries can be added. This is the transparency property that makes Rekor useful for compliance: a regulator can verify that an attestation exists now and that it existed at the logged timestamp, signed by the vendor's key at that time.
Six steps to integrate OCG buildType into your SLSA attestation pipeline. Each can be verified in isolation.
| Step | Action | Verified by |
|---|---|---|
| 1 | Confirm OCG tool emits v0.3 artifacts with buildType present. All AINumbers tools emit the default …#WebCryptoSHA256 URI automatically. |
JSON schema check: "buildType" in artifact returns true |
| 2 | Run the verification function from §6 against one artifact to confirm execution_hash matches the declared buildType construction |
verifyOcgArtifact(artifact) returns { valid: true } |
| 3 | Convert the artifact to a SLSA v1.0 provenance statement using ocgToSlsaProvenance() from §4 |
provenance.predicate.buildDefinition.buildType matches the artifact's buildType field exactly |
| 4 | Sign the provenance statement with your organization's signing key. Ed25519 recommended; see Guide #4. | cosign verify-attestation exits 0 with your public key |
| 5 | Submit signed attestation to Rekor (or your internal transparency log) | Rekor returns a valid UUID entry; rekor-cli get --uuid {uuid} shows the entry |
| 6 | Optional: publish your buildType URI as a resolvable URL so auditors can verify the construction procedure without contacting you |
HTTP GET on your buildType URI returns a document describing the preimage construction. No auth required. |
You do not need a dedicated build system, a container registry, or any server-side infrastructure to satisfy SLSA Level 1 with OCG artifacts. The buildType URI, execution_hash, and policy_parameters fields are all that SLSA Level 1 requires, and they are emitted automatically by every conformant OCG tool. Server infrastructure only becomes relevant at Level 2 (authenticated provenance) and Level 3 (hardened build environment).