Skip to content

Instantly share code, notes, and snippets.

@dangell7
Created August 7, 2026 21:40
Show Gist options
  • Select an option

  • Save dangell7/840bbdce19bd0351a79ecb02418471c2 to your computer and use it in GitHub Desktop.

Select an option

Save dangell7/840bbdce19bd0351a79ecb02418471c2 to your computer and use it in GitHub Desktop.
XLS Draft: Attestations — unilateral, revocable on-ledger statements about arbitrary subjects
  xls: TBD
  title: Attestations
  description: Unilateral, revocable on-ledger statements about arbitrary 32-byte subjects, signed by the attesting account.
  implementation: none yet
  author: Denis Angell (@dangell7)
  category: Amendment
  status: Draft
  proposal-from: TBD
  created: 2026-08-05
  updated: 2026-08-05

Attestations

1. Abstract

An attestation is an on-ledger statement by one account about one 32-byte subject: this binary hash was built from this source commit, this audit report covers this code revision, this document hash is the one we signed. The attester creates it unilaterally, can revoke it at any time, and the ledger timestamps both actions. One new ledger entry and two transactions.

The ledger does not decide whether the statement is true. It proves who said it, when they said it, and whether they still stand behind it. Everything else is the verifier's trust decision about the attester, which is exactly how signing works everywhere else.

2. Motivation

The concrete driver is source code validation: a validator operator wants to prove the binary they run was built from published source. The working answer is reproducible builds plus a signed statement linking binary hash to commit hash. Today that statement lives in a gist, a tweet, or a mailing list post, none of which offer revocation, a tamper-proof timestamp, or a stable place to look.

Once the statement is a ledger object, the same primitive covers cases we currently solve ad hoc:

  • Build attestations: binaryHash built from commitHash (reproducible builds, the source-validation case).
  • Audit attestations: auditor attests their report hash covers a specific code revision, and revokes if the finding set changes.
  • Document signing: attest the hash of an agreement, a spec revision, a policy.
  • Operational statements: a publisher attests the hash of a UNL blob, an issuer attests a reserve report.

XLS-70 Credentials does not cover this. A credential's subject must be an account, and the subject must accept before the credential is valid. That bilateral, account-to-account shape is right for KYC and permissioned domains and wrong for statements about artifacts: a git commit cannot accept anything. Attestations are the unilateral half of the space: any 32-byte subject, no acceptance, no counterparty.

3. Specification

The key words MUST, MUST NOT, SHOULD, and MAY are to be interpreted as described in RFC 2119. All behavior is gated on the featureAttestation amendment.

3.1. Ledger Entry: Attestation

3.1.1. Object Identifier

Key Space: 0xXXXX (TBD)

ID = hash(keyspace, Attester, SubjectHash, AttestationType). One attester, one subject, one type, one entry. Re-attesting the same triple updates the existing entry.

3.1.2. Fields

Field Constant Required Internal Type Description
LedgerEntryType Yes Yes UINT16 Attestation
Account No Yes ACCOUNT The attester. Owns the entry and its reserve
SubjectHash No Yes HASH256 The subject: a commit hash, binary digest, document hash, ledger object ID, or any 32-byte identifier
AttestationType No Yes UINT32 Application-defined type namespace (build, audit, document, ...). Types are conventions, not protocol semantics
Data No Optional BLOB Up to 256 bytes: a URI, a second hash, or a compact structured claim
Expiration No Optional UINT32 After this close time the attestation is expired and anyone MAY delete it
PreviousTxnID / PreviousTxnLgrSeq / OwnerNode No Yes Standard

3.1.3. Ownership, Reserves, Deletion

Owned by Account, one owner reserve, listed in the attester's owner directory only. Nothing about an attestation touches any other account's state: the subject is a hash, not a party. Deleted by AttestationDelete; an account with attestations cannot be deleted until they are removed, the standard owner-directory rule.

3.2. Transaction: AttestationSet

Creates the entry, or updates Data and Expiration in place if the (attester, subject, type) entry already exists. SubjectHash and AttestationType are immutable; a different subject or type is a different entry.

Failure conditions: amendment disabled (temDISABLED), Data over 256 bytes (temMALFORMED), Expiration in the past (temBAD_EXPIRATION), insufficient reserve on create (tecINSUFFICIENT_RESERVE).

3.3. Transaction: AttestationDelete

The attester at any time (revocation), or anyone once Expiration has passed (the keeper pattern, so expired statements do not linger). Deletion is the revocation mechanism: an attestation on the ledger is a statement the attester currently stands behind, and its PreviousTxnLgrSeq chain proves since when.

3.4. RPC

account_objects returns attestations under type attestation. ledger_entry accepts {attestation: {account, subject_hash, attestation_type}}. A verifier asks one question: does an unexpired attestation by this attester about this subject exist right now.

4. Rationale

Why not Credentials (XLS-70). Stated in Motivation: credential subjects are accounts and must accept. The one-sided, artifact-subject case is a different primitive, and bending Credentials to cover it (dummy subject accounts, auto-accept flags) would contaminate a shipped amendment for no gain.

Why on-ledger instead of a signed file. Three properties a gist cannot give: revocation with proof of when, a consensus timestamp, and key continuity (the attesting key is an account that can rotate via regular key and multisign, instead of a bare PGP key someone loses).

Why no truth machinery. An earlier framing of this idea, source code validation, tried to make the ledger verify the build. The ledger cannot run reproducible builds and should not pretend to. Attestations move the trust to where it actually lives, the attester's identity and track record, and keep the protocol surface to a signed, timestamped, revocable pointer. Verifiers that want multi-party assurance read N attestations from N independent attesters, which composes without any protocol support.

Composition. XLS-101 contracts can read attestations to gate logic (release only if two auditors attest this hash). The UNL publisher can attest each published blob. The doc pipeline can attest which commit its output covers. None of these need new protocol work beyond this spec.

5. Backwards Compatibility

None. New amendment, purely additive.

6. Test Plan

jtx suite: create/update/delete paths, immutability of subject and type, expiration boundary and third-party delete, reserve accounting, account deletion blocking, RPC lookups, amendment gating.

7. Reference Implementation

TBD. Sizing: one entry, two transactions, no asset movement, roughly 1.0 to 1.5 engineer-months to audit-ready. The smallest full amendment on the 2027 menu.

8. Security Considerations

  • Attestations move no value and touch no third-party state, so the griefing surface is the attester's own reserve.
  • Nothing prevents attesting to garbage. That is by design: the object proves authorship and timing, and verifiers MUST evaluate the attester, not the existence of the entry.
  • Revocation is deletion, so a verifier caching an attestation MUST re-check liveness at decision time, not at first sight.
  • Type collision between applications is possible in the UINT32 namespace; applications SHOULD publish their type registries. The protocol does not arbitrate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment