Skip to content

Latest commit

 

History

History
252 lines (221 loc) · 13.2 KB

File metadata and controls

252 lines (221 loc) · 13.2 KB

Trust Verification

ard currently implements an MVP trust verification path for artifact source integrity.

Source Digest Pinning

Artifact add commands can pin a URL artifact digest into trustManifest:

ard add mcp https://example.com/mcp/server.json --pin-source-digest
ardctl admin add mcp https://example.com/mcp/server.json \
  --pin-source-digest \
  --registry-url https://registry.example.com \
  --admin-token "$ARD_ADMIN_TOKEN"

Pinning writes:

{
  "trustManifest": {
    "identity": "https://example.com",
    "sourceDigest": "sha256:<hex>"
  }
}

--pin-source-digest requires a URL source. Local files are embedded as data, so the original source bytes are not available from an exported catalog for later URL integrity checks.

Verification

Use:

ard verify catalog ./ai-catalog.json --source-digests
ard verify catalog ./ai-catalog.json --require-source-digests
ard verify catalog ./ai-catalog.json --attestation-digests
ard verify catalog ./ai-catalog.json --require-attestation-digests
ard verify catalog ./ai-catalog.json --provenance-digests
ard verify catalog ./ai-catalog.json --require-provenance-digests
ard verify catalog ./ai-catalog.json --jws-trust-anchors ./trust-anchors.json
ard verify catalog ./ai-catalog.json --jws-remote-jwks https://example.com/.well-known/jwks.json
ard verify catalog ./ai-catalog.json --jws-discover-did-web
ard verify catalog ./ai-catalog.json --jws-discover-oidc
ard verify catalog ./ai-catalog.json --jws-discover-spiffe
ard verify catalog ./ai-catalog.json --jws-discover-tls-cert
ard verify catalog ./ai-catalog.json --jws-discover-tls-cert --jws-tls-spki-pin example.com=sha256:<hex>
ard verify catalog ./ai-catalog.json --jws-discover-tls-cert --jws-tls-spki-pin example.com=sha256:<hex> --require-jws-tls-spki-pins
ard verify catalog ./ai-catalog.json --jws-trust-anchors ./trust-anchors.json --require-jws-signatures

When --source-digests is enabled, ard fetches each URL entry that has trustManifest.sourceDigest, computes sha256, and fails if the digest does not match. When --require-source-digests is enabled, every URL-delivered entry must have trustManifest.sourceDigest; embedded data entries are exempt because they do not have a retrievable source URL.

When --attestation-digests is enabled, ard fetches each trustManifest.attestations[] document that has a digest, computes sha256, and fails if the digest does not match. --require-attestation-digests requires every attestation item to include digest and verifies all of them.

When --provenance-digests is enabled, ard fetches each trustManifest.provenance[] link that has a sourceDigest, computes sha256, and fails if the digest does not match. The sourceId must be an HTTP(S) URL for byte verification. --require-provenance-digests requires every HTTP(S) provenance sourceId to include sourceDigest and verifies all pinned HTTP(S) provenance sources. URN sourceId values are valid lineage identifiers but are not retrievable by this verifier.

When --jws-trust-anchors is enabled, ard verifies entries that carry trustManifest.signature as detached compact JWS signatures. The signed payload is the deterministic JSON form generated by ard from trustManifest with the signature field removed. The first supported algorithm is Ed25519 through a protected JWS header with alg: "EdDSA".

Trust anchors are explicit operator input. ard accepts either a small native format:

{
  "keys": [
    {
      "kid": "acme-ed25519",
      "alg": "EdDSA",
      "publicKey": "<base64url raw ed25519 public key>"
    }
  ]
}

or a local JWKS file with OKP/Ed25519 keys:

{
  "keys": [
    {
      "kty": "OKP",
      "crv": "Ed25519",
      "kid": "acme-ed25519",
      "alg": "EdDSA",
      "x": "<base64url raw ed25519 public key>"
    }
  ]
}

If the JWS protected header includes kid, it must match one key in the trust-anchor file. If no kid is present, verification only works when exactly one trust anchor is configured. --require-jws-signatures requires every catalog entry to carry a verifiable trustManifest.signature.

--jws-remote-jwks accepts an explicit HTTPS JWKS URL and fetches OKP/Ed25519 keys for the same signature verification path. Remote JWKS is operator-supplied key resolution, not automatic discovery. A key fetched from a remote JWKS URL is only accepted for an entry when the JWKS host matches the entry's trustManifest.identity trust domain for HTTP(S), SPIFFE, or did:web identities. Multiple --jws-remote-jwks flags may be combined with a local --jws-trust-anchors file.

--jws-discover-did-web performs explicit automatic key discovery for entries whose signed trustManifest.identity is a did:web DID. It resolves the DID document over HTTPS, extracts verificationMethod[].publicKeyJwk keys, accepts only OKP/Ed25519 keys, requires the DID document id and verification method controller to match the entry identity when those fields are present, and then runs the same detached JWS verification path. This flag is opt-in and only covers did:web; it does not resolve other DID methods.

--jws-discover-oidc performs explicit automatic key discovery for entries whose signed trustManifest.identity is an HTTPS issuer URL. It fetches the issuer's OpenID Provider configuration at <issuer>/.well-known/openid-configuration, validates that the returned issuer exactly matches the normalized entry identity, reads jwks_uri, fetches that JWKS, accepts only OKP/Ed25519 keys, and then runs the same detached JWS verification path. This follows OpenID Connect Discovery's required issuer and HTTPS jwks_uri metadata fields: https://openid.net/specs/openid-connect-discovery-1_0.html

--jws-discover-spiffe performs explicit automatic key discovery for entries whose signed trustManifest.identity is a SPIFFE ID. It reads trustManifest.attestations[] items with type: "SPIFFE-X509", treats their HTTPS uri values as SPIFFE bundle JWKS endpoints, requires each bundle URI host to match the SPIFFE trust domain, accepts only OKP/Ed25519 keys, and then runs the same detached JWS verification path. This follows the ARD spec examples that publish SPIFFE bundle material through trustManifest.attestations[].uri; it does not validate an X.509-SVID chain, workload selector, federation bundle sequence, revocation state, or SPIFFE Workload API state.

--jws-discover-tls-cert performs explicit key discovery from the HTTPS trustManifest.identity TLS leaf certificate. It uses the normal Go TLS verifier for the HTTPS request, requires the verified leaf certificate public key to be Ed25519, and then runs the same detached JWS verification path. This proves the same TLS endpoint presented the key at verification time.

--jws-tls-spki-pin adds an operator-supplied certificate policy for TLS certificate discovery. Each value must be host=sha256:<hex>, where <hex> is the SHA-256 digest of the leaf certificate SubjectPublicKeyInfo bytes. When a pin is configured for a TLS identity host, the discovered leaf certificate must match it before the Ed25519 key is accepted. --require-jws-tls-spki-pins requires every TLS certificate discovery host to have a matching pin. SPKI pinning constrains which verified TLS key can be used; it does not evaluate certificate transparency, revocation, extended compliance rules, or non-Ed25519 certificate keys.

Current Scope

  • Implemented: trustManifest.identity presence validation.
  • Implemented: catalog entry type media type syntax validation without enforcing a fixed media type allowlist.
  • Implemented: catalog entry url validation for absolute HTTP(S) URLs.
  • Implemented: catalog host metadata validation for required display name, absolute documentation/logo URIs, and host-level trustManifest structure.
  • Implemented: catalog entry updatedAt date-time validation and scalar-only metadata value validation.
  • Implemented: trustManifest.identityType type and enum validation against the ARD schema values: spiffe, did, https, and other.
  • Implemented: identityType consistency checks for https, spiffe, and did identities.
  • Implemented: trustManifest.trustSchema structure validation for required identifier and version, optional absolute governanceUri, and string verificationMethods.
  • Implemented: trustManifest.signature type validation.
  • Implemented: HTTP(S), SPIFFE, and did:web trustManifest.identity trust domains must match the urn:air: publisher domain.
  • Implemented: trustManifest.attestations structure validation for required fields, absolute uri values, mediaType syntax, and optional digest format.
  • Implemented: trustManifest.provenance structure validation for required fields, supported relation values, and optional sourceDigest format.
  • Implemented: trustManifest.sourceDigest type and format validation.
  • Implemented: schema-aligned known-field validation for trustManifest, trustManifest.trustSchema, attestation items, and provenance items. The only accepted top-level extension is trustManifest.sourceDigest.
  • Implemented: URL artifact source digest verification.
  • Implemented: strict URL artifact source digest requirements with ard verify catalog --require-source-digests.
  • Implemented: attestation document digest verification.
  • Implemented: strict attestation digest requirements with ard verify catalog --require-attestation-digests.
  • Implemented: HTTP(S) provenance source digest verification.
  • Implemented: strict HTTP(S) provenance source digest requirements with ard verify catalog --require-provenance-digests.
  • Implemented: detached compact JWS verification for trustManifest.signature with explicit Ed25519 trust anchors through ard verify catalog --jws-trust-anchors.
  • Implemented: local JWKS OKP/Ed25519 trust-anchor files for signature verification.
  • Implemented: explicit HTTPS remote JWKS OKP/Ed25519 trust-anchor fetching through ard verify catalog --jws-remote-jwks, with remote key use constrained by trustManifest.identity trust-domain matching.
  • Implemented: opt-in did:web DID document key discovery through ard verify catalog --jws-discover-did-web for DID documents that expose verificationMethod[].publicKeyJwk OKP/Ed25519 keys.
  • Implemented: opt-in OpenID Connect issuer discovery through ard verify catalog --jws-discover-oidc, validating the discovered issuer and fetching OKP/Ed25519 keys from jwks_uri.
  • Implemented: opt-in SPIFFE bundle JWKS key discovery through ard verify catalog --jws-discover-spiffe, reading SPIFFE-X509 attestation uri values and requiring the bundle URI host to match the SPIFFE trust domain.
  • Implemented: opt-in HTTPS TLS leaf certificate key discovery through ard verify catalog --jws-discover-tls-cert for verified Ed25519 leaf certificates.
  • Implemented: optional TLS certificate SPKI SHA-256 pinning through ard verify catalog --jws-tls-spki-pin and strict pin requirements through --require-jws-tls-spki-pins.
  • Implemented: strict catalog signature requirements with ard verify catalog --require-jws-signatures.
  • Implemented: admin audit event hash chaining and chain verification.
  • Not implemented yet: attestation truth, auditor trust, or freshness verification.
  • Not implemented yet: non-did:web DID methods, SPIFFE SVID validation, certificate transparency, revocation, or non-Ed25519 certificate keys.
  • Not implemented yet: externally anchored or signed audit trails.

Identity trust-domain matching is a metadata consistency check. It rejects entries that claim urn:air:acme.com:* while pointing trustManifest.identity at a different HTTP(S), SPIFFE, or did:web trust domain. It does not prove domain ownership, certificate identity, DID document control, SPIFFE SVID validity, or signature validity. Catalog host trust metadata is validated for shape and URI syntax only because host.identifier is not a catalog entry urn:air: identifier.

Attestation digest verification proves byte integrity for the fetched attestation document only. It does not decide whether the attestation is authentic, current, issued by a trusted auditor, or semantically true.

Provenance digest verification proves byte integrity for fetched HTTP(S) provenance sources only. It does not resolve URN source identifiers, prove lineage truth, prove who published the source, or decide whether a provenance relation is semantically valid.

JWS verification proves the configured, explicitly fetched, did:web-discovered, OIDC-discovered, SPIFFE-bundle-discovered, or TLS-certificate-discovered Ed25519 key signed the trust manifest bytes that ard verified. did:web discovery proves that the key was advertised by the fetched DID document at verification time. OIDC discovery proves that the key was advertised by the issuer's OpenID Provider metadata and JWKS at verification time. SPIFFE bundle discovery proves that the key was advertised by the host-matched SPIFFE bundle URI at verification time. TLS certificate discovery proves that the verified HTTPS endpoint presented the Ed25519 leaf certificate key at verification time, and optional SPKI pins can constrain the accepted TLS key for a host. None of these paths prove claim truth, validate SPIFFE SVID chains, evaluate certificate transparency or revocation, or decide whether the signed claims are true.