DEOS Anchor Format — v1 Specification

Status: v1.0 — published 2026-05-02 Spec URI: https://projectmaya.deoscomputing.io/anchor/v1 Maintainer: DEOS Computing (did:web:deos.computing) Companion: /anchor/bitcoin/v1

Receipts are signed and inclusion-proofed by the substrate, but "the substrate said it" is a weak time claim. An anchor binds a log root to one or more external timestamp authorities so that "this root existed by time T" is verifiable without trusting the substrate.

v1 supports OpenTimestamps (OTS) anchors. The substrate submits the log root to public OTS calendars; the calendars return pending proofs that, once aggregated and committed to Bitcoin, upgrade to Bitcoin-block-confirmed proofs.

This document is normative for v1.


1. Anchor record

An anchor is a JSON object stored under <data-dir>/anchors/<root_hex>.json and served by GET /attestation/v1/anchor/{root_hex}:

{
  "schema": "deos_anchor_v1",
  "root": "<hex of log root>",
  "leaf_count": 5,
  "anchored_at_ns": 1730419200000000000,
  "ots_proofs": [
    {
      "calendar_url": "https://alice.btc.calendar.opentimestamps.org",
      "proof_b64": "<base64url-nopad of OTS pending-proof bytes>",
      "proof_size_bytes": 172,
      "submitted_at_ns": 1730419200000000000,
      "calendars_in_proof": [
        "https://alice.btc.calendar.opentimestamps.org"
      ]
    },
    {
      "calendar_url": "https://bob.btc.calendar.opentimestamps.org",
      "proof_b64": "...",
      ...
    }
  ]
}
Field Required Notes
schema yes MUST equal "deos_anchor_v1".
root yes The log root the anchor binds, lowercase hex.
leaf_count yes Log leaf-count at time of anchor.
anchored_at_ns yes Substrate's wall-clock estimate (NOT trusted by verifiers).
ots_proofs yes Array (may be empty if no calendars were configured / reachable).
ots_proofs[].calendar_url yes URL the substrate POSTed the digest to.
ots_proofs[].proof_b64 yes base64url-nopad of the calendar's response bytes (opaque pending-proof).
ots_proofs[].proof_size_bytes yes Byte length of the decoded proof.
ots_proofs[].submitted_at_ns yes When the substrate received the proof.
ots_proofs[].calendars_in_proof yes Calendar URLs extracted from the proof bytes (heuristic v1; see §4.1).

An empty ots_proofs array is valid — it means the substrate was running in offline mode (no calendars configured) or every configured calendar was unreachable when the anchor was created.

2. OTS submission protocol

For each newly committed log root, the substrate:

  1. Takes the 32-byte raw root (as bytes — NOT hex).
  2. For each configured calendar URL, executes:
    POST <calendar_url>/digest
    Content-Type: application/vnd.opentimestamps.v1
    Accept: application/vnd.opentimestamps.v1
    <body: 32 raw bytes>
    
  3. On HTTP 2xx, stores the response body bytes as one entry in ots_proofs.
  4. On non-2xx or transport error, logs a warning and continues with the next calendar.

The OTS proof bytes are stored opaquely in v1. The substrate does not parse them beyond the URL-extraction heuristic in §4.1. v1.1 adds a full OTS-binary parser.

2.1 BLAKE3 vs SHA-256

OTS calendars accept any 32-byte digest. The DEOS substrate's log root is BLAKE3-256. The OTS calendar treats it as opaque 32 bytes — its eventual Bitcoin commitment binds the input bytes regardless of which hash function produced them. A verifier's interpretation: "the byte sequence equal to log root R existed before the Bitcoin block referenced in the upgraded proof." That binding is exactly what the substrate needs.

3. Anchoring policy

v1 anchors after every POST /attestation/v1/append (i.e., once per leaf). Production substrates SHOULD batch anchors by time or leaf count to avoid overloading public calendars.

The anchoring runs synchronously inside the append handler in v1 (simplicity over latency). v1.1 moves anchoring to a background thread.

4. Verification

A verifier examining an anchor record performs the following checks; any failure yields a soft warning, not a hard rejection. (Anchors strengthen "existed by time T" — a receipt without a verifying anchor is still authentic, just less time-bound.)

4.1 v1: extraction + presence

The v1 verifier:

  1. Fetches GET /attestation/v1/anchor/{root_hex}.
  2. Parses the anchor record per §1.
  3. For each entry in ots_proofs, base64-decodes proof_b64 and runs the URL-extraction heuristic — scan for http:// / https:// substrings, collect the embedded calendar URL(s).
  4. Reports the set of calendars the proof attests to.

This proves: (a) the substrate did call calendars, (b) the proof bytes are well-formed at the URL level, (c) which calendars to ask for the upgraded (Bitcoin-confirmed) proof later.

This does NOT yet prove: that the substrate didn't fabricate the proof bytes. (It would, however, be exposed when an honest verifier later upgrades the proof and the calendar replies with a different — or nonexistent — proof for that input.)

4.2 v1.1: full OTS proof + Bitcoin upgrade

v1.1 introduces:

  1. A proper OTS binary-format parser that walks the operation stream, applies hash ops to the starting digest, and identifies attestation tags.
  2. A separate upgrade job that periodically re-fetches each pending proof's URL (calendars expose the upgrade endpoint), replacing the pending proof with the Bitcoin-confirmed one once the calendar's batch is mined.
  3. Bitcoin block-header verification (see /anchor/bitcoin/v1) — supported header sources include blockstream.info SPV, a locally synced bitcoind, or a header-only LN node.
  4. The verifier output upgrades from anchor=present to anchor=bitcoin_confirmed block=<height> ts=<unix>.

The wire format of the anchor record DOES NOT change between v1 and v1.1 — v1 records continue to verify under v1.1 with the additional Bitcoin checks.

5. Trust model

What you trust by relying on a v1 anchor:

What you do not need to trust to verify a v1 anchor post-upgrade:

What v1.1 adds:

6. Endpoint

GET /attestation/v1/anchor/{root_hex}

200 -> the anchor record JSON (§1)
404 -> "no anchor for this root"
500 -> read/parse error

7. Server CLI

attestation-api --bind 127.0.0.1:8088 \
                --data-dir /var/lib/deos-attestation \
                --ots-calendars https://alice.btc.calendar.opentimestamps.org,https://bob.btc.calendar.opentimestamps.org

If --ots-calendars is absent or empty, the server runs in offline mode: anchors are still created (with ots_proofs: []) but no network calls are made. This mode is the default for tests and CI.

8. Anchor scheme registry

The anchor_record JSON object carries third-party timestamp evidence. v1 ships with one scheme — OpenTimestamps + Bitcoin — but additional schemes are planned (multi-rail anchors). To prevent ad-hoc field naming and enable verifier-side scheme dispatch, every anchor scheme MUST be registered here.

Scheme record shape

Every scheme is identified by a short ASCII ID (lowercase, hyphens-allowed, ≤32 chars) and registered with:

Field Type Notes
scheme_id string Unique registry key; appears as the JSON field name in anchor_record.
version integer Bumped on any breaking change to the field contract.
value_type string One of array<object>, object, array<string>. Tells the verifier the shape to parse.
time_source string bitcoin / ethereum-l1 / private-tsa / internal — the trust authority.
verifier_required boolean True if a verifier MUST validate this scheme's proofs (vs. SHOULD).

Registry

scheme_id version value_type time_source verifier_required spec
ots_proofs 1 array<object> bitcoin true this spec §1, /anchor/bitcoin/v1
eth_l1_timestamp 1 object ethereum-l1 false anchor-eth v1.2 (planned)
private_tsa 1 array<object> private-tsa false anchor-tsa v1.2 (planned)

A new scheme MUST update this table BEFORE shipping verifier code that emits the scheme's field. Implementations encountering an unregistered scheme_id MUST treat the anchor record as containing evidence they don't understand: log a warning, skip the unknown evidence, and continue verification with whatever registered schemes are present.

Scheme-version negotiation

anchor_record MAY carry multiple schemes simultaneously. Verifiers SHOULD prefer schemes with verifier_required = true; if none of the required schemes verify, the anchor is invalid even if optional schemes verify. This pattern lets v1.2 substrates emit private_tsa evidence alongside ots_proofs without weakening the ots_proofs requirement.

9. Anchor revocation / replacement [v1.3]

If an OTS calendar (or any registered anchor scheme) is later found to have been compromised — e.g. the calendar operator was malicious, or its signing key was leaked — DEOS needs a way to invalidate that calendar's proofs across ALL anchors that referenced it.

Status: design specified; implementation deferred to v1.3.

9.1 Revocation entry (proposed)

A new deos_anchor_revocation_v1 entry shape:

{
  "schema": "deos_anchor_revocation_v1",
  "scheme_id": "ots_proofs",
  "anchor_authority": "https://alice.btc.calendar.opentimestamps.org",
  "compromised_at_ns": 1730000000000000000,
  "reason": "calendar key leaked per public disclosure",
  "evidence_uri": "https://calendar-incident.example.com/2026-05-04",
  "issuer": "<substrate DID or curated DEOS-Computing-signed root>",
  "signature": { "alg": "ed25519", "kid": "...", "sig": "..." }
}

Two issuers are normative:

  1. Substrate-side: a substrate operator can revoke an anchor authority for receipts they emitted. Other substrates' receipts are unaffected.
  2. Curated: DEOS Computing publishes a signed list of compromised authorities at https://anchors.deos.computing/revocations.json. Substrates SHOULD subscribe and treat revoked authorities as untrusted across all anchors.

9.2 Verifier behavior

A verifier with a fresh anchor revocation list MUST:

  1. Identify each anchor's scheme_id + authority (e.g. for OTS, the calendar URL).
  2. If any (scheme_id, authority) is on the revocation list with compromised_at_ns ≤ anchor.submitted_at_ns, treat that anchor proof as untrusted.
  3. If after filtering, no trusted anchor remains AND --require-third-party-anchor is set (operator policy), reject the receipt.
  4. If after filtering, no trusted anchor remains AND --require-third-party-anchor is not set, accept the receipt with an explicit "no third-party timestamp evidence" annotation.

9.3 Why deferred

OTS calendar compromise is rare with no known historical incident. v1.1 accepts the residual risk in exchange for a simpler implementation surface. v1.3 ships when either a real OTS or alternative-anchor compromise is observed, or an operator deployment requires the curated revocation feed.

Operators SHOULD subscribe to the OpenTimestamps mailing list and monitor the anchor scheme registry (§8) for incident reports.

10. Open questions deferred


11. Maintainer

DEOS Computing — design questions and conformance reports to github.com/DEOS-Computing.

License: CC BY 4.0 (text), Apache-2.0 (reference code).