ATAP v0.1 — Agent Trust Attestation Protocol
| Standard | ATAP v0.1 |
| Status | v0.1 — Public comment through 2026-08-12 |
| Published | 2026-05-14 |
| Canonical URL | https://tunnelmind.ai/atap/standard |
| Key publication | https://tunnelmind.ai/atap/keys |
| Profile registry | https://tunnelmind.ai/atap/profiles |
| Reference verifier | https://tunnelmind.ai/atap/verify.sh |
| Editor | TunnelMind |
| License | CC BY 4.0 (spec) · MIT (reference implementations) |
1. Abstract
ATAP is an open protocol for agent behavioral attestation: a canonical receipt format that lets the principal of an agentic system — the advertiser, the compliance officer, the regulator, the auditor — cryptographically verify what an agent actually did, in chronological order, without trusting the agent's self-report. v0.1 specifies five artifacts: the AIT capability declaration, the Witness Event record, the Attestation Block roll-up, the Receipt ZIP compliance export, and the hash-chain plus Ed25519 signature model that binds them together. ATAP is invoked from inside the agent (or a trusted dependency such as an MCP server, a verification API, or a language-model SDK wrapper) via a single witness(event) call. The witness service is the trusted intermediary that signs and chains every artifact — the AIT itself, every Witness Event, every Attestation Block, every Receipt. There is no kernel observer in v0.1 and none is required. The receipt format is designed so that stronger observation tiers — sidecar daemons, TEEs, kernel attestation — can be introduced in later versions without invalidating earlier receipts or breaking the reference verifier. The format is the moat.
2. Object identifiers
ATAP defines four canonical object types and one external reference type. Each has a fixed identifier form.
| Type | Form | Notes |
|---|---|---|
| AIT | AIT-{uuidv7} |
Agent Identity Token. One per agent instance lifetime. |
| Witness Event | ATAP-WE-{uuidv7} |
One per witnessed action. |
| Attestation Block | ATAP-AB-{uuidv7} |
Roll-up of one or more Witness Events. |
| Receipt | ATAP-RCPT-{uuidv7} |
Compliance export bundle. |
| Witness service | OAI canonical | Witness services are identified by canonical OAI under the witness.operator category (Section 9.2). |
2.1 Why uuidv7
uuidv7 (RFC 9562) encodes a Unix-epoch millisecond prefix, giving natural time-ordering and database-friendly insertion locality. Agent instances, events, blocks, and receipts are short-lived high-cardinality objects unsuitable for a per-year sequence like OAI: a single media-buying agent emits thousands of events per second, and any registry-issued sequence would become the system bottleneck. uuidv7 is the only identifier scheme in v0.1; v2 MAY introduce others.
2.2 Formal grammar (ABNF, RFC 5234)
ait = "AIT-" uuidv7
atap-we = "ATAP-WE-" uuidv7
atap-ab = "ATAP-AB-" uuidv7
atap-rcpt = "ATAP-RCPT-" uuidv7
uuidv7 = 8HEXDIG "-" 4HEXDIG "-" "7" 3HEXDIG "-" 4HEXDIG "-" 12HEXDIG
HEXDIG = DIGIT / %x61-66 ; 0-9 lowercase a-f
DIGIT = %x30-39
The literal 7 in the third group enforces uuidv7 at parse time; uuidv4 and other versions MUST be rejected.
2.3 Bounds
| Field | Length |
|---|---|
| AIT | 40 characters |
| Witness Event ID | 45 characters |
| Attestation Block ID | 45 characters |
| Receipt ID | 47 characters |
2.4 Witness service identifier
A witness service — the surface that signs and chains all ATAP artifacts on behalf of a principal — is identified by canonical OAI under the witness.operator category, added to OAI v1.0 §3 as an editorial expansion on 2026-05-14 alongside the publication of this standard. The AIT field witness, the public-key lookup at /atap/keys, and the Receipt witness field all reference this OAI.
2.5 Anti-collision
A witness service MUST reject any AIT whose id it has previously signed under any other AIT. uuidv7's 74 bits of post-timestamp entropy make accidental collisions vanishingly improbable; rejection of seen IDs guards against deliberate impersonation by an adversary that scrapes published AITs and replays them under a different operator.
3. Scope
ATAP v0.1 specifies a protocol and a receipt format for the following:
| In scope | Definition |
|---|---|
| Capability declaration | Up-front statement of what the agent intends to do, in machine-parseable form (AIT). |
| Per-action witnessing | Record of each action the agent took, signed by a trusted witness service. |
| Periodic roll-up | Aggregation of witness events into hash-chained blocks. |
| Compliance export | Portable archive (Receipt ZIP) suitable for an auditor to verify independently. |
| Independent verification | Public reference verifier (verify.sh) and reference TypeScript wrapper (@tunnelmindai/atap). |
Application-specific extensions (the witness vocabulary for media buying, e-commerce, data brokerage, etc.) are out of scope for the base protocol and live in application profiles (Section 9). The base protocol provides the structural envelope; the profile fills it with domain-specific event types and aggregation rules.
4. Out of scope
The following are deliberate non-goals in v0.1. Each exclusion is load-bearing; do not work around them.
| Excluded | Why |
|---|---|
| Kernel-level observation | eBPF, syscall tracing, and TEE attestation are out of scope for v0.1 — they require a multi-engineer engineering effort that delays the protocol indefinitely. Stronger observation tiers MAY be added in later versions without breaking the receipt format. |
| Cross-platform agent runtime | ATAP does not provide an execution environment for agents. It is invoked from inside the agent's existing code. |
| Real-time agent behavior modification | ATAP records what the agent did, after the fact. It is not a policy engine and does not block actions. Policy engines MAY consume ATAP receipts as input. |
| Identity proofing of the human operator | ATAP attests to agent behavior, not operator identity. The principal verifies the agent by the witness service's signature on the AIT; KYC of the operator is the witness service's responsibility, out of scope for the protocol. |
| User-side privacy claims | ATAP receipts attest the agent's behavior toward third parties, not the privacy of any user data the agent processed. v0.1 forbids PII in the witness payload (Section 7.6) but does not enforce broader privacy properties. |
| Generic logging | Witness Events are signed, hash-chained, and structurally constrained. They are not a substitute for application logs and SHOULD NOT carry free-text or debug content. |
5. Stability guarantees
| Property | Guarantee |
|---|---|
| Receipt ZIP layout | Frozen at v0.1. The file names and directory structure in Section 7.5 do not change within v0.1. |
| Hash construction | Frozen at v0.1: SHA-256 over canonical JSON per RFC 8785 (JCS). v2 MAY add additional hash algorithms but MUST preserve the SHA-256 chain as a parallel artifact for verifier backwards compatibility. |
| Signature algorithm | Ed25519 (RFC 8032). v0.1 ships only this algorithm. v2 MAY add post-quantum signatures (e.g. ML-DSA per NIST FIPS 204) in parallel; v2 MUST NOT replace Ed25519 for v0.1 receipt verification. |
| Public-key endpoint | The URL https://tunnelmind.ai/atap/keys and its response shape are stable for the lifetime of v0.1. |
| Verifier | verify.sh published under v0.1 verifies every v0.1 receipt for the lifetime of v0.1. v2 verifiers MUST also verify v0.1 receipts. |
A receipt issued under v0.1 remains independently verifiable indefinitely. The standard never invalidates an existing receipt.
6. Lifecycle
An ATAP-instrumented agent traverses six states:
stateDiagram-v2
[*] --> declared : operator submits AIT to witness
declared --> witnessing : first witness(event) call accepted
witnessing --> witnessing : subsequent events
witnessing --> rolled_up : block_interval elapsed OR explicit flush
rolled_up --> witnessing : agent continues
rolled_up --> receipted : receipt(period) requested
receipted --> [*] : AIT retired
| State | Description |
|---|---|
declared |
The operator has submitted an AIT to the witness service. The witness has validated and signed it. No events have been witnessed yet. |
witnessing |
The agent is actively calling witness(event). The witness service signs and chains each event. |
rolled_up |
The witness service has emitted at least one Attestation Block summarizing prior Witness Events. The chain head is the most recent block. |
receipted |
A Receipt covering some period has been generated. The AIT MAY continue witnessing after a Receipt is taken. |
| Retired | The AIT will accept no more events. Retirement is recorded as a final Witness Event of type ait.retired; the witness service MUST refuse subsequent events for this AIT. |
witnessing → rolled_up is the only periodic transition; all others are event-triggered.
6.1 AIT acceptance
The operator constructs an AIT object with all fields populated except witness_signature. The operator submits the AIT to the witness service. The witness validates: schema conformance, profile registration, that the AIT's id has not been seen before, that the witness field matches its own canonical OAI, and that the operator's identity satisfies the witness's onboarding policy (out of scope for v0.1). On success the witness signs the canonical bytes of the AIT minus witness_signature and returns the signed AIT.
A signed AIT is the agent's credential. Subsequent witness(event) calls reference it by id.
6.2 Block roll-up triggers
A witness service MUST roll up pending events into a new Attestation Block when ANY of:
- The block interval declared in the AIT's
attestation_policy.block_interval_secondselapses since the previous block. - The pending event count exceeds the witness service's configured ceiling (default 10,000; configurable per profile).
- The agent's principal requests a flush via
POST /v1/atap/flush. - The witness service is about to shut down or rotate keys.
Witness services MAY roll up more frequently than the declared interval. They MUST NOT roll up less frequently.
6.3 AIT lifetime
An AIT SHOULD have a useful lifetime no longer than 90 days. An AIT MUST be retired no later than 365 days after issued_at. Long-lived AITs accumulate key-rotation, profile-version, and policy-drift risk. Profiles MAY specify tighter ceilings; profiles MUST NOT relax the 365-day cap.
The witness service MUST refuse witness(event) for an AIT older than its profile's maximum lifetime or older than 365 days, whichever is shorter, even if no retirement event has been recorded.
7. Schemas
All four object types are JSON. The on-the-wire encoding is JSON-LD where context is required for downstream tooling; the canonical form for hashing is RFC 8785 (JSON Canonicalization Scheme).
7.1 AIT (Agent Identity Token)
{
"@context": "https://tunnelmind.ai/atap/context.jsonld",
"@type": "AgentIdentityToken",
"id": "AIT-018f3c4d-7b2a-7d8e-9f01-4a5b6c7d8e9f",
"ait_version": "0.1",
"issued_at": "2026-05-14T08:00:00Z",
"expires_at": "2026-08-12T08:00:00Z",
"agent_type": "media-buyer",
"profile": "sigil:media_buyer:v1",
"operator": "OAI-2026-0000234",
"witness": "OAI-2026-0000017",
"capabilities": [
"bid:submit",
"bid:read_response",
"supply:verify_via_sigil",
"budget:read",
"budget:decrement",
"creative:select",
"report:generate",
"report:export_receipt"
],
"constraints": {
"max_bid_cpm": 50.00,
"currency": "USD",
"allowed_channels": ["display", "video", "ctv", "audio"],
"blocked_domains": ["example-blocked.com"],
"blocked_categories": ["IAB25-3", "IAB26"],
"geo_targeting": {"allowed_countries": ["US", "CA"]},
"supply_trust_minimum": 0.7,
"budget_daily_cap": 10000.00,
"budget_total_cap": 150000.00
},
"attestation_policy": {
"witness_granularity": "per_action",
"block_interval_seconds": 300,
"receipt_generation": "on_demand"
},
"witness_signature": "ed25519:0x..."
}
| Field | Type | Required | Notes |
|---|---|---|---|
@context |
string (URL) | Yes | Const https://tunnelmind.ai/atap/context.jsonld. |
@type |
string | Yes | Const AgentIdentityToken. |
id |
string | Yes | AIT-{uuidv7}. |
ait_version |
string | Yes | Const "0.1" for v0.1. |
issued_at |
string (date-time) | Yes | RFC 3339, set by the witness at signing. |
expires_at |
string (date-time) | Yes | RFC 3339. expires_at - issued_at MUST be ≤ 365 days. |
agent_type |
string | Yes | Free identifier, 1–64 characters; common values defined per profile. |
profile |
string | Yes | Application profile identifier (Section 9). |
operator |
string | Yes | Canonical OAI of the agent operator. Reference field; the operator does not sign. |
witness |
string | Yes | Canonical OAI of the witness service (witness.operator category). |
capabilities |
array of string | Yes | Declared capability set. Profile defines the vocabulary. Minimum 1, maximum 64 items. Items are 1–64 characters, pattern ^[a-z][a-z0-9_]*(:[a-z][a-z0-9_]*)+$. |
constraints |
object | No | Profile-defined constraint object. Profile schemas MUST validate this object; v0.1 imposes no constraints on its shape beyond JSON-validity and a 4 KB canonical-byte ceiling. |
attestation_policy |
object | Yes | See 7.1.1. |
witness_signature |
string | Yes | Ed25519 signature by the witness service over canonical bytes of the AIT minus the witness_signature field. Format ed25519:0x{128hex}. |
7.1.1 attestation_policy
| Field | Type | Required | Notes |
|---|---|---|---|
witness_granularity |
string | Yes | per_action or per_decision. Profile MAY define additional values. |
block_interval_seconds |
integer | Yes | Block roll-up cadence. 60 ≤ value ≤ 3600. Lower values prevent meaningful aggregation; higher values widen the worst-case adversarial window. Profiles MAY specify tighter ceilings. |
receipt_generation |
string | Yes | on_demand, per_block, or per_period. |
7.2 Witness Event
{
"@context": "https://tunnelmind.ai/atap/context.jsonld",
"@type": "WitnessEvent",
"id": "ATAP-WE-018f3c4d-7b2a-7d8e-9f01-4a5b6c7d8e9f",
"ait": "AIT-018f3c4d-7b2a-7d8e-9f01-4a5b6c7d8e9f",
"witnessed_at": "2026-05-14T08:00:01.123Z",
"event_type": "bid:submitted",
"payload": {
"exchange": "openx.com",
"publisher_domain": "example-publisher.com",
"seller_id": "12345",
"bid_amount": 1.45,
"creative_id": "cr-abc-123",
"sigil_token": "sigil:tok:abc...",
"supply_trust_score": 0.91
},
"prev_event_hash": "0x9f3a8b2e...",
"self_hash": "0xa1b2c3d4...",
"witness_signature": "ed25519:0x..."
}
| Field | Type | Required | Notes |
|---|---|---|---|
@context |
string (URL) | Yes | Const. |
@type |
string | Yes | Const WitnessEvent. |
id |
string | Yes | ATAP-WE-{uuidv7}. |
ait |
string | Yes | AIT this event was witnessed under. |
witnessed_at |
string (date-time) | Yes | RFC 3339, millisecond precision. Recorded by the witness service, not the agent. |
event_type |
string | Yes | Colon-delimited profile-defined identifier. Pattern: ^[a-z][a-z0-9_]*(:[a-z][a-z0-9_]*)+$. |
payload |
object | Yes | Profile-defined event payload. Canonical-bytes serialization MUST NOT exceed 16 KB. v0.1 imposes the constraint in Section 7.6. |
prev_event_hash |
string | Yes | SHA-256 of the previous Witness Event in the chain for this AIT, hex with 0x prefix. The first event uses the constant 0x followed by 64 zero hex characters. |
self_hash |
string | Yes | SHA-256 over canonical bytes of this event minus self_hash and witness_signature. Hex with 0x prefix. |
witness_signature |
string | Yes | Ed25519 signature by the witness service over the 32-byte SHA-256 digest that self_hash encodes (the raw digest, not the hex string). Format ed25519:0x{128hex}. |
7.2.1 Replay protection
A witness service MUST reject a witness(event) call whose intended witnessed_at would be more than 30 seconds older than the current witness clock. The witness sets witnessed_at itself at signing time; clock skew between the agent and the witness is the agent's problem to handle. This bounds the window during which a stolen credential could be used to back-date events.
7.3 Attestation Block
{
"@context": "https://tunnelmind.ai/atap/context.jsonld",
"@type": "AttestationBlock",
"id": "ATAP-AB-018f3c4d-7b2a-7d8e-9f01-4a5b6c7d8e9f",
"ait": "AIT-018f3c4d-7b2a-7d8e-9f01-4a5b6c7d8e9f",
"ab_version": "0.1",
"profile": "sigil:media_buyer:v1",
"period_start": "2026-05-14T08:00:00Z",
"period_end": "2026-05-14T08:05:00Z",
"first_event": "ATAP-WE-018f3c4d-7b2a-7d8e-9f01-4a5b6c7d8e9f",
"last_event": "ATAP-WE-018f3c4d-9a8b-7d8e-9f01-4a5b6c7d8e9f",
"event_count": 1247,
"chain_head_hash": "0xa1b2c3d4...",
"period_summary": {
"bids_submitted": 1247,
"bids_won": 89,
"total_spend": 342.17,
"unique_publishers": 34,
"unique_exchanges": 5,
"supply_verifications": 1247,
"supply_rejections": 203,
"average_trust_score": 0.84,
"constraint_violations": 0,
"channels_used": ["display", "video"],
"geos_reached": ["US"]
},
"prev_block_hash": "0x9f3a8b2e...",
"self_hash": "0xab12cd34...",
"witness_signature": "ed25519:0x..."
}
| Field | Type | Required | Notes |
|---|---|---|---|
@context |
string (URL) | Yes | Const. |
@type |
string | Yes | Const AttestationBlock. |
id |
string | Yes | ATAP-AB-{uuidv7}. |
ait |
string | Yes | The AIT. |
ab_version |
string | Yes | Const "0.1". |
profile |
string | Yes | Application profile identifier. |
period_start |
string (date-time) | Yes | RFC 3339. |
period_end |
string (date-time) | Yes | RFC 3339. period_end > period_start. |
first_event |
string | Yes | First Witness Event ID in the block. |
last_event |
string | Yes | Last Witness Event ID in the block. |
event_count |
integer | Yes | Inclusive count, ≥ 1. |
chain_head_hash |
string | Yes | self_hash of the last event in the block. |
period_summary |
object | Yes | Profile-defined aggregation. v0.1 imposes only Section 7.6. |
prev_block_hash |
string | Yes | self_hash of the previous block, or 0x + 64 zeros for the first block. |
self_hash |
string | Yes | SHA-256 over canonical bytes minus self_hash and witness_signature. |
witness_signature |
string | Yes | Ed25519 signature by the witness service over the 32-byte SHA-256 digest that self_hash encodes (the raw digest, not the hex string). Format ed25519:0x{128hex}. |
7.4 Receipt
A Receipt is a metadata record that describes the contents of a Receipt ZIP. The Receipt object itself appears as manifest.json inside the ZIP.
{
"@context": "https://tunnelmind.ai/atap/context.jsonld",
"@type": "Receipt",
"id": "ATAP-RCPT-018f3c4d-7b2a-7d8e-9f01-4a5b6c7d8e9f",
"ait": "AIT-018f3c4d-7b2a-7d8e-9f01-4a5b6c7d8e9f",
"profile": "sigil:media_buyer:v1",
"period_start": "2026-05-01T00:00:00Z",
"period_end": "2026-05-13T23:59:59Z",
"block_count": 3744,
"event_count": 4671293,
"first_block": "ATAP-AB-018ec7a1-...",
"last_block": "ATAP-AB-018f3c4d-...",
"chain_head_hash": "0xab12cd34...",
"witness": "OAI-2026-0000017",
"format": "full",
"generated_at": "2026-05-14T09:00:00Z",
"verifier_url": "https://tunnelmind.ai/atap/verify.sh",
"keys_url": "https://tunnelmind.ai/atap/keys",
"files": [
{"path": "ait.json", "sha256": "0x..."},
{"path": "attestation_chain.json", "sha256": "0x..."},
{"path": "summary.json", "sha256": "0x..."},
{"path": "public_keys.json", "sha256": "0x..."},
{"path": "verify.sh", "sha256": "0x..."},
{"path": "compliance_report.pdf", "sha256": "0x..."},
{"path": "profile_artifacts/", "sha256": null}
],
"witness_signature": "ed25519:0x..."
}
| Field | Type | Required | Notes |
|---|---|---|---|
id |
string | Yes | ATAP-RCPT-{uuidv7}. |
ait |
string | Yes | |
profile |
string | Yes | |
period_start / period_end |
string (date-time) | Yes | Bounds of the receipt. |
block_count / event_count |
integer | Yes | |
first_block / last_block |
string | Yes | First and last Attestation Block IDs included. |
chain_head_hash |
string | Yes | self_hash of last_block. |
witness |
string | Yes | Canonical OAI of the witness service. |
format |
string | Yes | full or summary. summary omits the per-event chain. |
files |
array of object | Yes | Manifest of every file in the ZIP with SHA-256. Empty sha256 permitted for directories. |
witness_signature |
string | Yes | Ed25519 signature over canonical bytes of this Receipt minus the signature field. Format ed25519:0x{128hex}. |
7.5 Receipt ZIP layout
ATAP-RCPT-{uuidv7}.zip
├── manifest.json # The Receipt object (7.4)
├── ait.json # The AIT under which the period was witnessed
├── attestation_chain.json # Array of AttestationBlocks, ordered, hash-chained
├── summary.json # Aggregated period_summary across all blocks
├── public_keys.json # Witness service Ed25519 public keys covering the period
├── verify.sh # Reference verifier (bash + openssl + jq)
├── compliance_report.pdf # Optional human-readable rendering
└── profile_artifacts/ # Profile-specific files; structure defined by profile
├── sigil_tokens.json # Example: media_buyer profile
└── ...
The layout is frozen for v0.1. Receipts MUST contain manifest.json, ait.json, attestation_chain.json, public_keys.json, and verify.sh. The other files are optional but, when present, MUST conform to this layout.
7.5.1 Why a directory for profile artifacts
The base receipt verifies the chain. The profile artifacts carry the application-specific evidence that gives the chain meaning: for media buying, the Sigil verification tokens that justify each bid; for e-commerce, the order-state attestations; for content scraping, the per-source consent records. Putting them in a sibling directory lets verify.sh succeed without understanding the profile, while leaving an obvious place for profile-aware tools to look.
7.6 Payload constraint: no PII
Witness Event payloads, Attestation Block summaries, and profile artifacts MUST NOT contain personally identifiable information about end users. The following are explicitly forbidden:
| Forbidden | Notes |
|---|---|
| End-user IP addresses | The IP of the user the agent acted on behalf of, or against. Third-party destination IPs (servers, ASNs, exchanges) ARE permitted — Section 3 explicitly admits them. |
| User-agent strings | Carries device, browser, and OS fingerprinting signal. |
| Cookies, session identifiers, OAuth tokens | Bearer credentials and pseudonymous identifiers. |
| Email addresses, phone numbers, physical addresses | Direct identifiers. |
| Account IDs at consumer services | Including but not limited to social-network user IDs, e-commerce account numbers, gaming-platform handles tied to natural persons. |
| Wallet addresses tied to a natural person | Cryptocurrency identifiers that are known or reasonably inferable to belong to a specific individual. Pseudonymous wallets used solely by autonomous agents are permitted. |
| Biometric identifiers | Facial geometry, fingerprints, voiceprints, gait signatures. |
| Browser or device fingerprints | Canvas, WebGL, audio-context hashes, plugin enumerations, font lists, hardware identifiers (MAC, IMEI, serial). |
| Content of user communications | Message bodies, search queries with user attribution, chat transcripts. |
What IS in scope: destinations (domains, ASNs, server-side IP ranges, app-bundle IDs), aggregate volumes, timings, prices, capability identifiers, profile-defined trust signals, and any field whose resolution does NOT reach a natural person.
Profile maintainers MUST encode this constraint in their JSON Schemas. Profiles that fail to do so MUST NOT be admitted into the registry (Section 9.3).
7.7 Canonical bytes for hashing and signing
A self_hash is the SHA-256 of the canonical JSON bytes of the object minus its self_hash and witness_signature fields. Canonical JSON is JSON Canonicalization Scheme, RFC 8785. The witness signature on a Witness Event or an Attestation Block is computed over the 32-byte SHA-256 digest that its self_hash encodes — the raw digest bytes, not the hex string. The witness signature on an AIT or a Receipt — neither of which carries a self_hash — is computed over the canonical JSON bytes of the object minus witness_signature. Implementations MUST NOT compute hashes over the raw JSON-LD as transmitted; differences in whitespace, key ordering, or numeric representation would silently invalidate signatures.
The canonical procedure for a Witness Event:
- Construct the event object with all fields except
self_hashandwitness_signature. - Serialize via RFC 8785 JCS.
- Compute SHA-256 →
self_hash. - Sign the 32-byte SHA-256 digest that
self_hashencodes — the raw digest, not its hex-string form — with the witness service's Ed25519 private key →witness_signature. - Add
self_hashandwitness_signatureto the object for transmission and storage.
The same procedure applies, with the corresponding field exclusions, to Attestation Blocks.
For the AIT and the Receipt, the procedure is identical except that the only excluded field is witness_signature, and the signature is computed over the object's canonical bytes directly — neither carries a self_hash.
Ed25519 conventions in v0.1. Signatures are 64 bytes, hex-encoded as 128 lowercase characters with the ed25519:0x prefix. Public keys are 32 bytes, hex-encoded as 64 lowercase characters with the 0x prefix.
8. Key publication
Public keys for witness services are published at:
GET https://tunnelmind.ai/atap/keys
8.1 Response shape
{
"keys": [
{
"witness": "OAI-2026-0000017",
"key_id": "k1",
"algorithm": "ed25519",
"public_key": "0x...",
"valid_from": "2026-05-01T00:00:00Z",
"valid_until": "2027-05-01T00:00:00Z",
"status": "active",
"rotated_to": null,
"compromise_notice": null
},
{
"witness": "OAI-2026-0000017",
"key_id": "k0",
"algorithm": "ed25519",
"public_key": "0x...",
"valid_from": "2025-05-01T00:00:00Z",
"valid_until": "2026-05-01T00:00:00Z",
"status": "rotated",
"rotated_to": "k1",
"compromise_notice": null
}
],
"updated_at": "2026-05-14T08:00:00Z"
}
A key per witness service:
| Status | Meaning |
|---|---|
active |
Currently signing new events. |
rotated |
Superseded by rotated_to. Verifies historical events whose witnessed_at falls within [valid_from, valid_until]. |
compromised |
Withdrawn. Verifiers MUST reject signatures from this key when validating receipts whose witnessed_at is later than compromise_notice.disclosed_at. Receipts whose witnessed_at predates disclosed_at SHOULD be marked unverified rather than valid; downstream policy MAY treat them differently. |
When status is compromised, the compromise_notice object is required:
{
"disclosed_at": "2026-09-12T14:30:00Z",
"detected_at": "2026-09-12T13:45:00Z",
"summary_url": "https://tunnelmind.ai/atap/compromise/2026-09-12.html"
}
8.2 Key selection at verification time
Given a Witness Event with witnessed_at: t and witness_signature, the verifier selects the key where:
key.witness == event.ait.witness (looked up via the AIT)
key.valid_from <= t < key.valid_until
key.status != "compromised"
OR (key.status == "compromised" AND t < key.compromise_notice.disclosed_at)
There is exactly one such key at any moment per witness service. If zero or more than one key matches, the verifier MUST reject the event.
8.3 Rotation cadence
Witness services SHOULD rotate keys at least every 6 months under normal operation. Witness services MUST rotate keys within 1 hour of any reasonable suspicion of compromise.
8.4 Compromise disclosure
When a witness service detects key compromise:
- The witness service MUST mark the key
compromisedat/atap/keyswithin 1 hour of detection.disclosed_atanddetected_atMUST both be populated. - The witness service MUST publish a
summary_urldescribing the incident within 24 hours of disclosure. - The witness service MUST rotate the key (publish a successor under the same witness OAI with
status: active) within 1 hour of disclosure.
Caching at the edge (Section 8.5) is configured to permit propagation of compromise notices in under 5 minutes globally.
8.5 Caching
| Field | Cache-Control |
|---|---|
/atap/keys (full document) |
public, max-age=300, stale-while-revalidate=3600 |
Verifiers MAY pin a snapshot of /atap/keys for the duration of a single verification run (typically seconds to minutes). Verifiers MUST NOT pin a snapshot longer than 24 hours; a 24-hour pin is the recommended ceiling. Pinning beyond that risks treating a compromised key as valid.
9. Witness model and application profiles
9.1 The witness is whoever the principal trusts
ATAP v0.1 makes one structural decision the implementation hinges on: the witness is not the agent. The witness is a service that observes the agent's actions, signs them, and chains them. The principal verifies the chain by checking the witness's signature.
This is a weaker trust model than kernel attestation. The witness can be deceived by an agent that bypasses it. v0.1 accepts this trade-off because (a) bypassing the witness is detectable as a chain discontinuity, (b) a documented witness-signed chain is strictly better than today's unsigned campaign logs, and (c) the receipt format is forward-compatible with stronger observation tiers.
For the v0.1 reference deployment in programmatic advertising, Sigil is the witness: the agent calls sigil.verify/supply_path before each bid, Sigil sees the decision, Sigil signs and chains it. No separate observer is required. Other application domains follow the same pattern: choose an interface the principal already trusts, and make it the witness.
9.2 Witness service identification
Witness services are identified by canonical OAI under the witness.operator category. This category was added to OAI v1.0 §3 as an editorial expansion on 2026-05-14 alongside the publication of this standard. Existing witness services that hold sensor.operator OAIs MAY continue to use them; new witness services SHOULD register under witness.operator.
9.3 Application profiles
A profile is a published document that defines, for a specific agent domain:
- The vocabulary of
event_typestrings the agent's witness emits. - The JSON Schema for each event type's
payload. - The JSON Schema for
period_summaryaggregation. - The JSON Schema for
constraintsin the AIT. - The contents of
profile_artifacts/in the Receipt ZIP.
Profiles are identified by a colon-delimited string of the form {namespace}:{domain}:v{N}. Examples:
| Profile | Maintainer | Status in v0.1 |
|---|---|---|
sigil:media_buyer:v1 |
TunnelMind (via Sigil) | Reference profile, ships alongside v0.1. |
sigil:ecommerce_buyer:v1 |
TBD | Reserved. |
sigil:data_broker:v1 |
TBD | Reserved. |
The profile registry is published at https://tunnelmind.ai/atap/profiles and the source-of-truth repository is https://github.com/TunnelMind/atap-profiles. Third-party profiles MAY be registered subject to the constraints in Sections 7.6 (no PII) and 9.4 (acceptance criteria).
9.4 Acceptance criteria
A profile proposal is accepted into the registry if all of the following hold:
- The proposed JSON Schemas validate as JSON Schema 2020-12.
- The Schemas encode the PII prohibition of Section 7.6 — verified by automated test cases the proposer includes in the PR.
- The proposed namespace token is not already claimed (first-comer wins).
- The proposal includes at least one signed example AIT, Witness Event, Attestation Block, and Receipt that round-trip through the reference verifier.
Profile proposals are PRs to github.com/TunnelMind/atap-profiles. CI runs the four checks above and auto-merges PRs that pass within 7 calendar days, absent an editorial objection (Section 12.2). The editor's hand-review is reserved for scope and conflict cases.
9.5 Profile authority and collisions
The proposer of an accepted profile is its authoritative maintainer. ATAP v0.1 does not arbitrate when multiple parties want the same domain: they get separate namespaces. sigil:media_buyer:v1 and acme:media_buyer:v1 MAY coexist; verifiers select the profile referenced by the AIT they are verifying.
10. Hash chain and transparency
10.1 The chain
ATAP maintains two parallel hash chains per AIT:
flowchart LR
subgraph Event chain
E0[WE-0\nprev=0x00] --> E1[WE-1\nprev=hash E0] --> E2[WE-2\nprev=hash E1] --> Edots[...]
end
subgraph Block chain
B0[AB-0\nprev=0x00\nhead=hash E_n] --> B1[AB-1\nprev=hash B0\nhead=hash E_m]
end
E2 -.->|chain_head_hash| B0
- The event chain binds Witness Events in monotone order. Every event's
prev_event_hashis the previous event'sself_hash. - The block chain binds Attestation Blocks. Every block's
prev_block_hashis the previous block'sself_hash. - A block's
chain_head_hashreferences theself_hashof the last event it covers, binding the block chain to the event chain.
A break in either chain is a verification failure.
10.2 Genesis
The first Witness Event and the first Attestation Block for an AIT use the constant prev_event_hash and prev_block_hash of 0x0000000000000000000000000000000000000000000000000000000000000000 (32 zero bytes, hex-encoded — 0x followed by 64 zero characters).
10.3 Hash algorithm
SHA-256 over canonical JSON bytes (RFC 8785). v0.1 ships only SHA-256. The signed quantity for each Witness Event, Attestation Block, and Receipt is the raw 32-byte hash; the wire form prefixes 0x.
10.4 Transparency log (deferred to v1.x)
A public append-only log of Attestation Block heads, modelled on Certificate Transparency (RFC 6962), is the strongest near-term addition to the trust model. v0.1 reserves the URL https://tunnelmind.ai/atap/log and the optional Attestation Block field log_index. Verifiers MUST tolerate log_index values that cannot yet be checked against a live log endpoint; the absence of a log does not invalidate a v0.1 receipt.
The transparency log is on the v1.x roadmap, scheduled to land once ATAP has measurable external adoption (see Section 12.1). It is not a v2 deliverable; v2 work (post-quantum, federation) is downstream of it.
10.5 What the chain proves
The chain proves:
- Append-only. No event was inserted, removed, or reordered after the next event was signed.
- Witness attribution. Each event, each block, and the AIT itself was signed by the declared witness service.
- Period coverage. A receipt's chain head matches the last block in
attestation_chain.json; if any block was omitted, the chain head will not match.
The chain does NOT prove:
- That the agent did not perform actions outside the witness's view. (Mitigated in later versions by stronger observation tiers.)
- That the witness's signed events accurately reflect reality. (Mitigated by witness reputation, witness-OAI registry, the transparency log when shipped, and out-of-band evidence.)
These limits are honest; the standard does not promise what its trust model cannot deliver.
11. Verification
11.1 The reference verifier
verify.sh is a single-file bash script using openssl and jq, intended to be readable in one sitting. It is published at:
https://tunnelmind.ai/atap/verify.sh
and is included verbatim in every Receipt ZIP. The verifier:
- Parses
manifest.jsonand validates the SHA-256 of every other file matches the manifest entry. - Validates the AIT's structure against the v0.1 schema and verifies its
witness_signatureagainst the appropriate public key. - Walks the event chain in
attestation_chain.json(or the block chain insummaryformat), verifying each block'sself_hash,prev_block_hash,chain_head_hash, andwitness_signatureagainst the keys inpublic_keys.json. - Reports per-block status to stdout; exits 0 if every block verifies, 1 otherwise.
11.2 Reference TypeScript wrapper
A TypeScript implementation of witness(event) is published as:
npm: @tunnelmindai/atap
source: https://github.com/TunnelMind/atap/tree/main/packages/atap-js
The wrapper is non-normative; it is provided to lower the cost of correctly integrating ATAP. Implementations in other languages are welcomed and need only conform to Section 7 and Section 10.
11.3 Verification environments
verify.sh runs anywhere bash 4+, openssl 1.1+, and jq 1.6+ are present. The reference TypeScript wrapper targets Node 20+ and ESM. No managed runtime, no specific cloud provider, no vendor dependency. This is load-bearing for adoption: a verifier that requires the principal to trust a specific cloud cannot become the citation format.
12. Governance
12.1 Editor
TunnelMind edits ATAP v0.1. TunnelMind is a single-operator project, not a foundation, not a consortium, and not a venture-backed entity. There is no board, no token, and no third-party investor with editorial influence. The editor's role is provisional; the conditions under which it transfers to a neutral host mirror those in OAI v1.0 §12.4 — external adoption (three or more independent organizations publishing ATAP receipts), standards-track recognition (IETF / W3C / MITRE citation), and operational maturity (99.9% key endpoint uptime, zero canonical-URL breaks) sustained over two consecutive quarters.
12.2 Conflict of interest
TunnelMind operates Sigil, a commercial witness service for media buying that consumes ATAP. To bound the conflict:
- Profile acceptance follows the published automated criteria in Section 9.4 and is not influenced by whether the proposing party is a customer, partner, or competitor of TunnelMind's commercial products. The CI checks are public and reproducible; their pass/fail decision is not subject to editor override on technical grounds, only on scope grounds.
- Editorial decisions on scope, schema constraints, and out-of-scope exclusions (Section 4) are public and reversible only by a versioning event (Section 13).
- The editor MUST NOT accept payment, sponsorship, or grant funding in exchange for profile acceptance or schema changes. Funding not tied to specific schemas or profiles is permissible and MUST be disclosed at
tunnelmind.ai/atap/funding.
12.3 Automated workflow
The editor's stated commitment is to not be a bottleneck. To that end:
| Channel | Automation |
|---|---|
| Profile proposals | PR to github.com/TunnelMind/atap-profiles. CI validates Section 9.4 checks. Schema-conformant PRs auto-merge within 7 calendar days absent an editorial objection. |
| Schema bug reports | Issue on github.com/TunnelMind/atap. Automated acknowledgment within 24 hours. Editor triage within 7 calendar days. |
| Objections | Issue on github.com/TunnelMind/atap-profiles with objection label. Automated acknowledgment within 24 hours. Editor written response within 14 calendar days. Auto-acknowledgment is not a substantive response. |
| Compromise disclosures | Direct contact (security email TBD) plus public posting at /atap/compromise/. Section 8.4 sets SLOs. |
These SLOs are tighter than OAI's because the automation makes them feasible; OAI's longer windows reflect manual issuance decisions that ATAP does not require.
12.4 Continuity
The protocol spec, the JSON Schemas, the reference verifier, and the reference TypeScript wrapper are open: the spec is licensed CC BY 4.0 and the code artifacts are MIT-licensed. A current snapshot of the spec, schemas, profile registry, and public-key archive is publicly downloadable at tunnelmind.ai/atap/archive/ and updated at least monthly.
In the event the editor cannot operate the standard, the canonical URLs (/atap/standard, /atap/keys, /atap/verify.sh, /atap/profiles) MAY be repointed to a successor neutral host with a 301. Receipts issued under v0.1 continue to verify against the archived public keys regardless of editor identity.
12.5 Editor failure modes
A single-operator editor has failure modes a foundation does not. Even with automation:
- Profile review hand-cases. Conflicts between proposals competing for the same scope, or proposals raising novel PII or scope concerns, require editor judgment. The 7-day auto-merge SLO does not apply when the editor opens a hand-review on a PR. Hand-reviews target 14 calendar days.
- Capacity ceiling. If editorial workload exceeds what the automation plus the solo editor can sustain, the editor invokes the Transition RFC ahead of the standard-transfer gate. Premature transition is a recognized exit, not a failure.
These constraints are honest about scale rather than aspirational about it.
13. Versioning
ATAP follows semantic versioning at the standard level, not the receipt level.
| Change class | Version impact |
|---|---|
| Editorial clarification, no schema impact | None — re-publish in place. |
| New optional field on AIT, Witness Event, Attestation Block, or Receipt | Minor — v0.1.x. |
| New required field, change to hash construction, change to signature algorithm, change to ZIP layout | Major — v0.2 (pre-v1) or v1 (first stable). |
| Promotion to v1 | Requires the conditions in Section 12.1 plus a 90-day public comment period on the v1 RFC. |
v0.1 is pre-stable. The schemas in Section 7 may evolve through v0.1.x without breaking already-issued receipts. Once v1 is published, the v1 schemas are frozen at additionalProperties: false for the lifetime of v1.
A v2 verifier MUST verify v0.1 and v1 receipts.
14. Locked positions and forward-looking work
This section records decisions that v0.1 commits to, distinguishing them from items genuinely deferred. Public comment on the locked positions is welcomed; the editor's prior is that they hold for v1.
14.1 Receipt revocation: LOCKED — immutability
Signed-and-shipped receipts are immutable. There is no protocol-level revocation. The only remediation path is witness-key compromise (Section 8.4): when a key is marked compromised, downstream verifiers downgrade receipts signed by it after disclosed_at to invalid, and receipts signed before disclosed_at to unverified (policy-dependent). Corrections to recorded reality go in a new chain under a new AIT.
Rationale: a revocable receipt is not a receipt. A compliance receipt's value is that the principal can verify it without coordinating with the issuer. A retroactively editable receipt collapses to a self-report. The cost of immutability is that erroneous receipts cannot be redacted; the standard accepts this cost.
14.2 Profile-domain collisions: LOCKED — first-comer wins, no editor arbitration
Multiple parties wanting the same agent domain (e.g. two different organizations proposing competing media_buyer profiles) get separate namespaces: partyA:media_buyer:v1 and partyB:media_buyer:v1. The editor does NOT arbitrate competing technical claims. Verifiers select the profile referenced by the AIT they are verifying.
Rationale: arbitration introduces editor bias risk and a slow path. Separate namespaces are honest about disagreement and let the market converge by adoption.
14.3 Algorithm agility: LOCKED — SHA-256 + Ed25519 frozen at v0.1
v0.1 ships SHA-256 and Ed25519 exclusively. v2 MAY add (not replace) post-quantum signatures and SHA-3 hashes. During the v2 transition, every artifact will be signed and hashed in BOTH the v0.1 algorithms and the v2 algorithms, so that v0.1 verifiers continue to function. v2 receipts retire only when the surrounding cryptographic environment retires SHA-256 / Ed25519.
14.4 Witness federation: DEFERRED to v2
v0.1 binds each AIT to exactly one witness service. Multi-witness co-signing of events (a stronger-assurance pattern for high-stakes domains) is deferred to v2 governance.
14.5 Cross-AIT linking: OUT OF SCOPE for v0.1
The same operator running multiple AITs across instances, time, or business units is identified at the OAI operator level (the operator field). No protocol-level AIT-to-AIT linking is provided in v0.1.
14.6 Privacy-preserving aggregation (zero-knowledge attestations): RESEARCH
Zero-knowledge proofs over sensitive aggregate signals (e.g. attesting "total spend was under cap X" without revealing the exact value) are a research direction. They are not on the v1 roadmap. Profiles needing this capability today should structure their period_summary to omit sensitive values rather than mask them.
14.7 Transparency log: SCHEDULED for v1.x
The append-only log of Attestation Block heads (Section 10.4) is the highest-leverage near-term addition to the trust model and is the first v1.x priority once external adoption is measurable. URL /atap/log is reserved.
Appendix A. References
- RFC 3339 — Date and Time on the Internet: Timestamps
- RFC 5234 — Augmented BNF for Syntax Specifications: ABNF
- RFC 6962 — Certificate Transparency (model for the future transparency log)
- RFC 8032 — Edwards-Curve Digital Signature Algorithm (Ed25519)
- RFC 8785 — JSON Canonicalization Scheme (JCS)
- RFC 9562 — Universally Unique IDentifiers (UUIDs), including uuidv7
- JSON Schema 2020-12 — https://json-schema.org/draft/2020-12/schema
- JSON-LD 1.1 — https://www.w3.org/TR/json-ld11/
- NIST FIPS 204 — Module-Lattice-Based Digital Signature Standard (ML-DSA, referenced for v2 post-quantum direction)
- OAI v1.0 — https://tunnelmind.ai/oai/standard (companion standard, identifier scheme for witness services)
Appendix B. Implementation references
| Artifact | Location |
|---|---|
| Spec document (this file) | tunnelmind-site/docs/ATAP-v0.1.md and github.com/TunnelMind/atap/ATAP-v0.1.md |
| JSON Schemas | tunnelmind-site/public/atap/schemas/v0.1/ |
| JSON-LD context | https://tunnelmind.ai/atap/context.jsonld |
| Reference verifier | tunnelmind-site/public/atap/verify.sh and bundled inside every Receipt ZIP |
| Reference TypeScript wrapper | @tunnelmindai/atap on npm · source at github.com/TunnelMind/atap/packages/atap-js |
| Profile registry | github.com/TunnelMind/atap-profiles (rendered at tunnelmind.ai/atap/profiles) |
| Public key endpoint | https://tunnelmind.ai/atap/keys |
| Reference profile: media buyer | Sigil P32 — landing once the Sigil build ships |
GitHub Issues — concrete defects, contradictions, broken examples.
Profile proposals belong at github.com/TunnelMind/atap-profiles (forthcoming).
Formal objections per §12.3 will be archived at
tunnelmind.ai/atap/objections (forthcoming).