← Rubric Protocol
Guide

Building on Google Credentio: From Local Validation to Durable Verdicts

Updated: 2026-09-11 Credentio commit: 4ac69fc5 Tested on: Ubuntu 22.04, Bazel 9.2, clang-18


1. What Credentio is

Google open-sourced Credentio in August 2026: the C++ C2PA Content Credentials validation engine behind nearly 40 Google products. It validates provenance for images, video, audio, and documents, locally and fast. It is validation-only today; generation and embedding are on the roadmap. Source: https://mediaprovenance.googlesource.com/credentio, Apache 2.0.

2. Building on Ubuntu 22.04

The repo is Bazel-only (no CMakeLists) and its .bazelrc pins -stdlib=libc++ and C++20. A stock 22.04 box fails with fatal error: 'cstddef' file not found until the toolchain matches. What works:

apt-get install -y clang-18 libc++-18-dev libc++abi-18-dev g++-12 libstdc++-12-dev
curl -fsSL https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64 -o /usr/local/bin/bazel
chmod +x /usr/local/bin/bazel
cd credentio
CC=clang-18 CXX=clang++-18 bazel build --repo_env=CC=clang-18 --repo_env=CXX=clang++-18 tools:c2pa_validate

Two traps. First, Ubuntu 22.04's default clang-14 is too old; use apt.llvm.org for 18. Second, Bazel caches the autodetected C++ toolchain aggressively: if you install compilers or libc++ after a failed build, bazel clean --expunge is required or the stale toolchain config keeps failing with missing-header errors that look like package problems. Expect ~3,200 actions and 10–15 minutes on first build.

3. Running validation

Credentio does not ship trust lists. Pull the official C2PA lists from github.com/c2pa-org/conformance-public/tree/main/trust-list and pin their hashes if your output feeds evidence.

bazel-bin/tools/c2pa_validate \
  --asset=photo.jpg \
  --claim_signer_trust=C2PA-TRUST-LIST.pem \
  --tsa_trust=C2PA-TSA-TRUST-LIST.pem \
  --output_format=crjson

4. Parsing crjson output

Two gotchas for programmatic consumers. First, stdout is polluted: the tool prints Validation successful! and a header line before the JSON, so slice from the first {. Second, that success line means the tool executed, not that the asset validated. The verdict lives in manifests[].validationResults.failure[]: an empty failure array is a clean pass; entries like com.google.unsupportedSpecVersion mean the manifest was declined. Read failure codes, never the prose.

The active manifest is the last element of manifests[]. Signer identity is under signature.certificateInfo (issuer, subject, serial, validity), which is worth fingerprinting: hash the whole object and you have a durable reference to the exact classical trust chain that validated, useful long after that chain rotates or, eventually, stops being trustworthy at all.

5. Making verdicts durable

Credentio's verdict dies with the process. Nothing records that asset X validated against trust list Y at time T, which is precisely what an audit, dispute, or regulator asks for later. And every C2PA trust chain today is classical crypto: once quantum computers break ECDSA, historical validations become unprovable retroactively unless the verdict was recorded with post-quantum signatures while the chain was still trusted.

Rubric sells that record. Two tiers, machine-payable over x402 (USDC on Base):

pip install autogen-rubric
from autogen_rubric import build_claim, attest_claim
claim = build_claim(credentio_crjson, asset_bytes=data,
    trust_list_path="C2PA-TRUST-LIST.pem", engine_commit="4ac69fc5")
receipt = attest_claim(claim, post=my_x402_post)

The record carries the trust list hash, engine commit, signer chain fingerprint, and verdict codes verbatim, signed ML-DSA-65 (FIPS 204) and anchored to Hedera. A real one, bought by an agent: seq 298424. Verification is free and public. Spec: rubric-cva/0.1.

One design note: Credentio recommends live-at-head. If your output is evidence, pin the commit and record it in every attestation; evidence needs a reproducible validator.


x402 endpoints · APA spec · Rubric Protocol