Validiti Validiti
Public specification · v1.0

Mark · verifiable identity for AI

A small, simple envelope you can attach to any AI output. It answers four questions, with math, that anyone can re-check. This document is the entire spec. If you can read JSON and you can run a verifier, you can use it.

version 1.0 · published 2026-05-15 · results-only

01What Mark answers

When an AI output appears, four questions matter:

  • Who or what produced this?
  • On whose behalf?
  • Under what policy?
  • When?

Until today, those questions had no answer. Now they have one. The answer is a small envelope attached to every AI output that Validiti products produce.

02What a Mark envelope looks like

A Mark envelope is a JSON object with the following top-level fields:

FieldTypeRequiredCarries
versionintyesSpec version (currently 1)
event_idstringyesGlobally unique identifier for this envelope
event_typestringyesWhat kind of action this envelope attests to
categorystringyes"agent" for AI; "human" and "machine" reserved
ts_unixintyesUTC seconds at production
issuerobjectyesWho/what produced this
forobjectoptionalThe person or org the issuer was acting for
installationobjectoptionalThe hardware the issuer ran on
policyobjectoptionalThe policy in force at production
descended_fromobjectoptionalLineage chain back to the base model
previousstringoptionalThe envelope before this one in the issuer’s chain
payloadobjectyesThe actual signed content (shape per event_type)
sealstringyesThe cryptographic seal that makes the rest verifiable

03The issuer object

{
  "id":           "<a stable identifier for the issuer>",
  "kind":         "ai_agent" | "ai_model" | "ai_pipeline",
  "key":          "<reference to the issuer's published public key>",
  "display_name": "<human-readable, optional>"
}

The seal is verified against the public key referenced by issuer.key. The key registry is public; anyone can publish a key, anyone can read any key.

04The for object

When an AI agent acts on behalf of a person or organization, the for object names them and the scope.

{
  "principal_id":   "<identifier for the human / org>",
  "principal_kind": "human" | "organization" | "service",
  "scope_id":       "<the authorization scope>",
  "scope_hash":     "<hash proving the scope was granted>"
}

05The installation object

{
  "device_id":     "<stable identifier for the device>",
  "binary_id":     "<the Validiti product producing this>",
  "binary_hash":   "<sha256 of the producing binary>",
  "runtime_state": "<runtime-attestation token>"
}

This is how a relying party confirms the envelope came from a known, untampered installation.

06The policy object

{
  "policy_id":      "<stable identifier>",
  "policy_hash":    "<hash of the full policy>",
  "policy_version": "<semver or sequence>",
  "policy_source":  "<reference, or 'self'>"
}

The policy_hash lets a verifier confirm what policy was in force without exposing the policy’s contents. Required when event_type is inference_produced, action_taken, or policy_loaded.

07The descended_from object

{
  "base_model_id":   "<identifier>",
  "base_model_hash": "<hash>",
  "derivation_chain": [
    { "step_kind": "fine_tune" | "rlhf" | "dpo" | "distillation" | "merge",
      "step_id":   "<identifier>",
      "step_hash": "<hash>",
      "step_ref":  "<reference, or null>" }
  ],
  "training_corpus_ref": "<reference, or null>"
}

Optional. When present, anyone can walk the chain back to the base model.

08Event types

Mark v1.0 defines these event types for the agent category:

event_typeWhat it meansRequired payload
inference_producedThe issuer produced an outputoutput_hash, output_size_bytes
inference_refusedThe issuer was asked to act but refusedreason_code
inference_partialThe issuer began but did not completeoutput_hash, partial_reason
action_takenThe issuer caused an external side-effectaction_type, target_ref, result_code
action_refusedThe issuer declined an authorized actionreason_code, action_type, target_ref
delegation_requestedThe issuer handed off to another issuerdelegate_actor_id, delegation_scope
delegation_acceptedThe issuer accepted a hand-offdelegator_actor_id, scope_accepted
policy_loadedThe issuer loaded or switched policypolicy_id, policy_hash
lineage_attestedThe issuer published its lineage chain(lineage object at top level)
revocationA signing key is being revokedrevocation_target_actor_id, revocation_reason, revocation_effective_ts

Additional domain-specific event types are valid Mark v1.0 agent events, used by specific Validiti products: challenge_issued, verification_attempt, verdict_labeled, signal_published, persona_action, persona_loaded, corpus_loaded, corpus_queried, lineage_claimed.

09How to verify an envelope

A Mark envelope is verified in eight steps:

  1. Check version is supported.
  2. Strip seal from the envelope.
  3. Compute the canonical JSON of what’s left (sorted keys, no extra whitespace, no seal field).
  4. Look up the public key referenced by issuer.key.
  5. Check the seal cryptographically verifies the canonical body against that public key.
  6. Optional: walk the previous chain to confirm continuity.
  7. Optional: confirm the policy.policy_source is known.
  8. Optional: walk the descended_from.derivation_chain against the registry.

Steps 1–5 are mandatory. Steps 6–8 are optional checks that add stronger guarantees for relying parties that need them.

The reference verifier is available two ways. (1) Live now as a hosted service at POST /api/mark/verify — try it on the Mark page. (2) Coming soon as a free sealed Validiti binary bundled with every Validiti product that touches AI, when each product ships. You can also implement your own verifier from this spec; the math is straightforward.

10Selective disclosure

You can present a subset of an envelope’s fields and prove the omitted fields existed in the signed original. Selective-disclosure presentations are a separate envelope shape, specified separately. Full-envelope presentation is what v1.0 requires; selective disclosure ships in v1.1.

11Revocation

To revoke a signing key (or a specific envelope), the issuer produces an envelope with event_type = "revocation" and the appropriate payload. Verifiers check their local revocation set before validating any seal. Revocations propagate through the same channel envelopes flow on; there is no central revocation server to call.

12What Mark is NOT

  • Not a wallet you download.
  • Not a service Validiti hosts.
  • Not a registry Validiti controls.
  • Not something you pay for.

Mark is a math layer over signed records that Validiti products already produce. You add the verifier to your software in five minutes. You don’t need an account, an API key, or a contract with anyone.

13What’s coming

Mark v1.0 is for AI agents. Mark v1.1 adds selective disclosure. Later versions add category = "human" (for people) and category = "machine" (for devices), using the same envelope shape. All three categories are free, forever. Identity should never be paywalled — not for AI, not for people, not for the devices people use.

This document covers Mark · Agent v1.0. If you can read JSON and you can run a verifier, you can use it. That is the entire spec.

Reference verifier: live now as a hosted service at /api/mark/verify; the bundled sealed binary is Coming Soon. Solving tomorrow’s problems today — because we care.