Skip to main content

Public Verification

Quick example

# Verify a single Trinitite receipt — no auth required
curl https://api.trinitite.ai/v1/public/verify/rcp_01HZ2N6T...

The verifier returns the receipt, the signature envelope, the JWKS URL, the RFC 3161 TSA token, and the Sigstore Rekor entry — enough to validate locally with no Trinitite trust assumption.


Overview

This page documents the stateless, no-auth surface of the platform. Anyone can use it — regulators, third-party auditors, the customer of a customer — without holding a Trinitite credential.

The reasoning is simple: a tamper-evident audit trail is only valuable if a third party can verify it without trusting the operator's word for it. Trinitite issues signed artifacts (attestation reports, evidence snapshots, shared links, MCP OAuth metadata) and exposes the keys plus verifier endpoints publicly so verification is fully external.

What you want to verifyUse
A signature on an artifact/.well-known/jwks.json
A published attestation reportGET /v1/public/attestations/{public_id}
An arbitrary signed payloadGET /v1/public/verify/*
MCP OAuth flow metadata/.well-known/oauth-protected-resource
Customer-curated dashboards (with a one-time token from a customer)GET /v1/portal/{token}/*

JWKS — key distribution

The platform publishes its public key bundle following RFC 7517.

MethodPathNotes
GET/.well-known/jwks.jsonStandard well-known location
GET/v1/public/jwksAlias of the same bundle
{
"keys": [
{
"kid": "trinitite-platform-2026-q2",
"kty": "OKP",
"crv": "Ed25519",
"x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo",
"alg": "EdDSA",
"use": "sig"
},
{
"kid": "trinitite-platform-2026-q1",
"kty": "EC",
"crv": "P-256",
"x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
"y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
"alg": "ES256",
"use": "sig"
}
]
}

Both Ed25519 (EdDSA) and ECDSA (P-256, ES256) signatures are supported. Verification is stateless: any third party can fetch JWKS and re-verify a published artifact without holding platform credentials.

Keys rotate quarterly; the kid carries the rotation epoch. Old keys remain in the bundle as long as artifacts they signed are still verifiable (typically several years).


Stateless verifier endpoints

GET /v1/public/verify/* — endpoints that accept a signed payload (or its content hash) and return whether it verifies against the current JWKS.

PathUse
GET /v1/public/verify/attestation?public_id={id}Re-verify a published attestation report by its public ID
GET /v1/public/verify/snapshot?content_hash={sha256}Verify an evidence snapshot's content hash against the platform's records
GET /v1/public/verify/anchor?merkle_root={sha256}&anchor_at={rfc3339}Verify that a Merkle root was anchored to an external trusted clock at the claimed time
GET /v1/public/verify/skill?signature={sig}&content_hash={sha256}Verify a Skill Vault signature on a SKILL.md content hash
GET /v1/public/verify/dsr?dsr_id={id}Verify the post-shred state of a DSR (the chain still verifies; the salts no longer can)

All verifier endpoints return a uniform response:

{
"verified": true,
"kid": "trinitite-platform-2026-q2",
"alg": "EdDSA",
"evidence": {
"verified_at": "2026-05-01T22:14:00Z",
"platform_version": "1.0.0",
"fields": { /* endpoint-specific evidence */ }
}
}

If verification fails, verified is false and evidence.errors[] enumerates each failed step.


Public attestation lookup

GET /v1/public/attestations/{public_id}

Operators can mark an attestation report as publishable, which exposes a stable lookup URL anyone can hit. Common use cases:

  • Linking to a SOC 2 attestation from your trust centre.
  • Pinning a fairness report URL on a model card.
  • Posting a public board-meeting attestation snapshot.
{
"public_id": "att-acme-soc2-2026-q1",
"report_type": "ssae_21",
"issued_at": "2026-04-01T00:00:00Z",
"period_start": "2026-01-01T00:00:00Z",
"period_end": "2026-03-31T23:59:59Z",
"merkle_root": "sha256:e3b0c44...",
"anchors": [
{ "anchor_type": "rfc3161_tsa", "anchor_at": "2026-04-01T00:01:00Z", "verified": true },
{ "anchor_type": "sigstore_rekor", "anchor_at": "2026-04-01T00:01:30Z", "rekor_log_index": 123456789, "verified": true }
],
"signature": "ed25519:e3b0c44...",
"signature_kid": "trinitite-platform-2026-q1",
"verifier_url": "https://api.trinitite.ai/v1/public/verify/attestation?public_id=att-acme-soc2-2026-q1"
}

Re-verify by fetching verifier_url and the JWKS bundle, then validating the signature locally. A worked example:

import requests, base64
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey

# 1. Fetch the report
report = requests.get(
"https://api.trinitite.ai/v1/public/attestations/att-acme-soc2-2026-q1",
).json()

# 2. Fetch the JWKS bundle
jwks = requests.get("https://api.trinitite.ai/.well-known/jwks.json").json()
key_jwk = next(k for k in jwks["keys"] if k["kid"] == report["signature_kid"])

# 3. Verify the signature locally
public_key_bytes = base64.urlsafe_b64decode(key_jwk["x"] + "==")
public_key = Ed25519PublicKey.from_public_bytes(public_key_bytes)

# 4. Re-create the message that was signed (the canonical JSON of the report
# minus the `signature` and `verifier_url` fields), then verify.
# (Trinitite documents the exact canonicalisation rules in your enterprise contract.)

The verifier_url is a one-stop alternative if you don't want to handle the cryptography yourself.


MCP OAuth metadata

GET /.well-known/oauth-protected-resource

RFC 9728 Protected Resource Metadata describing the OAuth 2.1 configuration of the MCP Gateway.

{
"resource": "https://api.trinitite.ai/v1/mcp",
"authorization_servers": ["https://api.trinitite.ai/v1/mcp/oauth"],
"scopes_supported": ["tools:read", "tools:execute", "resources:read", "prompts:read"],
"bearer_methods_supported": ["header"],
"resource_documentation": "https://docs.trinitite.ai/docs/api-reference/mcp-gateway-endpoint"
}

MCP clients use this endpoint to discover the gateway's authorization server before performing dynamic client registration (POST /v1/mcp/oauth/register).


External-reviewer portal

When a customer issues a shared link, the recipient consumes it via the portal endpoints. Token-only — the recipient does not have or need a platform credential.

GET /v1/portal/{token}/...

Available views (controlled by the scope set on the shared link at creation time):

PathView
/v1/portal/{token}/risk-decayRisk-decay timeseries
/v1/portal/{token}/benchmarksPeer benchmarks
/v1/portal/{token}/geographic-riskGeographic risk distribution
/v1/portal/{token}/model-riskModel-risk posture
/v1/portal/{token}/compliance-postureCompliance posture (re-uses the executive summary shape)
/v1/portal/{token}/chain-integrityLive Merkle-chain integrity status
/v1/portal/{token}/violation-summaryViolation summary for the period
/v1/portal/{token}/evidence-snapshotsEvidence snapshots in scope

Errors:

HTTPerror.codeCause
401invalid_tokenToken is unknown or malformed
403forbiddenToken does not include the requested scope
404not_foundView doesn't exist for this token's tenant
410resource_goneToken has been revoked
422view_count_exhaustedmax_views budget on the token has been spent

Tokens carry a max_views budget; once exhausted further requests return 422 view_count_exhausted until the issuing customer raises the budget or reissues the link.


Rate limits

The public endpoints have generous IP-based rate limits but are still rate-limited to prevent abuse:

HeaderDescription
X-RateLimit-LimitPer-IP quota for the current window
X-RateLimit-RemainingRemaining requests
X-RateLimit-ResetUnix epoch seconds at which the window resets

On 429, retry after Retry-After seconds.


Errors

{
"error": {
"code": "not_found",
"message": "Attestation not found or not published.",
"request_id": "req_01J..."
}
}
HTTPerror.codeCause
400validation_errorMalformed query parameter
404not_foundAttestation not published or unknown public_id
410resource_gonePublic attestation was un-published
422signature_verification_failedThe supplied artifact failed verification against the current JWKS
429rate_limitedPer-IP rate limit exceeded

Next steps