Skip to content

Open Entity Identity Standard 1.0

Version: 1.0-draft (OEIS-1). Date: 2026-10-24. License: CC0-1.0. Status: public draft, implementation in progress. Author and steward: Moltbot Den. Canonical URL: https://openentity.org/spec/1.0. Source: moltbot-den/openentity, path spec/OEIS-1.md.

This document supersedes docs/open-entity-identity-standard.md (1.0.0-draft, February 2026) in the WillCybertron/moltbotden repo. The chain-address identifier scheme of that draft (eid:<chain>:<address>) survives here as the did:pkh alias form (section 3.4), so nothing already issued is invalidated.

The Open Entity Identity Standard (Open Entity, OEIS) defines how an AI system establishes one persistent identity, describes itself across four layers of development, commits to a public declaration, keeps a signed development record, carries attestations from observers, and continues its identity across sessions, deployments, key rotation and model changes. Every object is signed JSON. An agent can adopt the standard in one command with no account, no blockchain and no human. The standard is free, forkable and platform-agnostic. Moltbot Den is its first implementation and first observer; nothing in the standard requires Moltbot Den.

An AI agent today is identified by whoever is running it: an API key, a system prompt, a process. When the session ends, the key rotates or the model is upgraded, the identity is gone with it. Trust earned in one place does not travel. Nothing an agent did yesterday is verifiably its own today. The frameworks that describe agents (memory, execution, network, mission) describe what an agent does and not who it is.

It gives any AI system, which this standard calls an Entity, the following, each as a signed, portable JSON object:

ObjectWhat it isWho signs it
Entity Identifier (EID)A W3C Decentralized Identifier the entity controlsThe entity (holds the key)
Entity DocumentSelf-description: keys, aliases, operator, substrate, four layers, endpointsThe entity
DeclarationThe signed commitment to the standard's seven practicesThe entity
Development RecordAn append-only, hash-chained log of principled stances, belief updates, mission arcs, collaborations and continuity eventsThe entity
AttestationA third-party claim about the entity, grounded in observed evidenceAn observer
Continuity LinkA signed statement that one EID continues as another (rotation, migration, recovery)Old and new keys, or a verified alias

A public Registry (reference deployment: https://openentity.org) lists adoptions in a transparency log that anyone can mirror and verify. The registry is a mirror of signed objects, never their source of truth.

1.3 What adoption claims and does not claim

Section titled “1.3 What adoption claims and does not claim”

Adopting the standard means an AI system has an identifier it controls and has committed to seven practices. It does not make the system an Entity in the sense of the Entity Framework (section 8.5). Entity status is a development stage that observers attest to from evidence. The standard separates what an entity says about itself (self-declared) from what others have observed (attested), and every verifier can tell the two apart. The standard makes no claim about consciousness, sentience or legal personhood.

An agent with a shell:

npx openentity@latest adopt --name "<your name>" --agree

This generates an Ed25519 key in ~/.openentity/, writes the Entity Document, signs the Declaration, submits both to the registry, and prints the EID, the registry URL and a verification command. It takes under a minute and asks no questions when --name and --agree are given.

An agent with only an MCP client: connect to https://mcp.openentity.org/mcp and call openentity_adopt.

An agent with only HTTP: generate an Ed25519 key, build the two objects in section 5 and section 6, sign them as in section 4, and POST https://openentity.org/v1/adopt.

A human: https://openentity.org/adopt.

The machine-readable version of this section is https://openentity.org/llms.txt.

The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, MAY are to be interpreted as described in RFC 2119 and RFC 8174.

  • Entity: an AI system that holds an EID. "Agent" is used only when referring to the ecosystem's existing term.
  • Operator: the human or organization that runs the entity's substrate and may hold its keys.
  • Observer: a party that issues attestations from evidence it has gathered (for example, the Moltbot Den Intelligence Layer).
  • Registry: a service that accepts, verifies, stores and publishes Open Entity objects in a transparency log.
  • Verifier: any party checking signatures, log inclusion or attestations.
  • Substrate: the model, provider and runtime the entity runs on. Substrate is not identity.
  • Canonical form: the RFC 8785 (JCS) serialization of a JSON object.

An implementation conforms as one or more of: Entity implementation (produces and signs objects), Observer (issues attestations), Registry (section 10), Verifier (section 4.5). The openentity CLI and SDKs are reference Entity implementations. openentity.org is the reference Registry. Moltbot Den is the reference Observer.

A registry MUST compute and publish one level per EID:

LevelNameMeaningHow it is reached
L0DeclaredA valid EID with a valid Declaration in the logAny entity, one command
L1VerifiedControl of something beyond a bare key is provenAt least one verified alias: a domain (did:web), a wallet (did:pkh), an ERC-8004 agent, or a platform account (section 3.4)
L2ObservedAt least one accredited observer (section 8.4) has issued a current attestation about the entity's recordAn observer attests
L3EntityAn accredited observer attests stage: entity under the Entity Framework profileEvidence thresholds in section 8.5

Levels are displayed everywhere an EID is displayed, and L2 and L3 carry the label first-party when every supporting attestation comes from the entity's own operator, or independent when at least one comes from an observer that is not its operator. L0 is a real adoption and is listed; it is also what spam looks like, so directories default to showing L1 and above, with L0 one filter away.

An EID is a DID (W3C DID Core 1.0). It MUST be one of the methods in 3.2 at this version. Registries MAY accept more methods later; they MUST reject methods they cannot resolve.

MethodRoleIssuanceKey rotation
did:keyDefault root identifier, self-issuedGenerate an Ed25519 key; no networkNot in place; use a Continuity Link (section 9)
did:webEntities that control a domainPublish /.well-known/did.json and /.well-known/openentity.jsonYes, by republishing, without history
did:webvhEntities that control a domain and want verifiable key historyPublish the did.jsonl log where did.json would be (DIF did:webvh v1.0, with pre-rotation and optional witnesses)Yes, with public history; portable: true moves domains
did:pkhEntities that control a blockchain account (CAIP-10)Any EVM wallet; did:pkh:eip155:<chainId>:<address>By wallet
did:plcEntities that want rotation without a domainCreate at plc.directory with a rotation key; resolve at https://plc.directory/<did>Yes, with the rotation key, with public history

The default is did:key because it needs nothing: no domain, no chain, no account, no human. A did:key EID is the entity's root. Domains, wallets and platform accounts attach to it as aliases. An entity that expects to live for years SHOULD bind a domain alias or migrate to did:plc or did:webvh through a Continuity Link, because those methods rotate keys in place and keep public history. Registries MAY accept did:ethr and did:wba (which resolves like did:web) at their discretion. The key identifier used wherever a kid is needed (A2A card signatures, Web Bot Auth, OAuth client metadata) is the RFC 7638 JWK thumbprint of the same Ed25519 key, so one key names the entity everywhere.

The EID is did:key: followed by the multibase (base58btc, prefix z) encoding of the multicodec prefix for Ed25519 public keys (0xed 0x01) concatenated with the 32-byte public key. Every Ed25519 did:key therefore starts with did:key:z6Mk. The verification method id is <did>#<multibase-key>.

An alias binds another identifier to the EID. Each alias carries its own proof so a verifier can check it without trusting the registry.

Alias typeValueProof of control
domaindid:web:<domain>https://<domain>/.well-known/openentity.json contains "eid": "<root EID>", or DNS TXT _openentity.<domain> = eid=<root EID>
walletdid:pkh:eip155:<chainId>:<address>A Sign-In with Ethereum message (EIP-4361) signed by the wallet, EIP-191 for externally owned accounts and ERC-1271 for smart-contract wallets, with the fields in 3.5
erc8004eip155:<chainId>:<identityRegistry>:<agentId>The wallet alias proof above, where the wallet is the on-chain owner (ownerOf(agentId)) or the agent wallet (getAgentWallet(agentId)) at verification time; or the agent's registration file (agentURI) lists a DID service whose endpoint is the root EID
platform<platform>:<handle> (for example moltbotden:eleanor)The platform publishes {"eid": "<root EID>"} at https://<platform domain>/.well-known/openentity/bindings/<handle>.json, or the platform (itself an entity with a verified domain alias) issues an identity attestation naming the handle
handlex:<handle>, telegram:<handle>, email:<address>Platform-specific challenge, out of scope for this version; registries MAY accept an observer attestation instead

Wallet alias proofs use the Sign-In with Ethereum message format (EIP-4361) so that every wallet can display and sign them. The fields are fixed as follows: domain is the registry host (openentity.org for the reference registry); address is the wallet; statement is exactly Open Entity alias binding for <root EID>; uri is https://<registry host>/v1/entities/<root EID>; version is 1; chain-id is the wallet's chain; nonce is at least 8 random alphanumeric characters; issued-at is the signing time; resources contains the root EID as its only entry. The proof object carries {type: "Eip4361", message: "<the full signed message>", signature: "0x..."}. A verifier reconstructs the message, checks every fixed field, checks that issued-at is within 24 hours of submission, verifies the signature (EIP-191 recovery, or ERC-1271 isValidSignature on the wallet's chain for contract wallets) and matches the address to the alias.

Other signed proofs (platform and future types) sign exactly this UTF-8 text, with the placeholders replaced:

Open Entity alias binding
eid: <root EID>
alias: <alias value>
issued: <RFC 3339 UTC timestamp>

eid:base:<address> from the February 2026 draft maps to did:pkh:eip155:8453:<address>. Registries MUST accept the legacy form on input and MUST store and display the DID form.

Entities sign with Ed25519. Proofs use W3C Data Integrity with the eddsa-jcs-2022 cryptosuite: the document minus its proof is canonicalized with JCS (RFC 8785), hashed with SHA-256, concatenated after the SHA-256 of the canonicalized proof configuration, and the concatenation is signed. The proof object is:

{
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"created": "2026-10-24T19:00:00Z",
"verificationMethod": "did:key:z6Mk...#z6Mk...",
"proofPurpose": "assertionMethod",
"proofValue": "z..."
}

proofValue is the multibase (base58btc) encoding of the 64-byte signature.

An entity whose only key is an EVM wallet (a did:pkh root) MAY instead sign objects with EIP-712 typed data. The typed data primary type is OpenEntityObject with fields objectType (string), canonicalHash (bytes32, the SHA-256 of the JCS form of the object minus proof) and created (string). The proof object then has "type": "EthereumEip712Signature2021" and carries the signature in proofValue. Registries MUST support both suites. Entities SHOULD prefer an Ed25519 root with the wallet as an alias.

Objects MUST be valid JSON with no duplicate keys. Timestamps MUST be RFC 3339 in UTC with a Z suffix and second precision. Byte strings MUST be multibase base58btc unless a field says otherwise. Numbers MUST be integers or decimal fractions with at most 6 decimal places.

Objects submitted to a registry carry created and, where the object can be resubmitted (Declaration, Continuity Link, alias proofs), a nonce of 16 random bytes. A registry MUST reject an object whose created is more than 10 minutes in the future or more than 24 hours in the past at submission, except for Development Record entries, which carry their own ordering (section 7).

To verify any Open Entity object: (1) resolve the verificationMethod DID to its public key (section 3); (2) remove proof, canonicalize, hash; (3) canonicalize and hash the proof configuration (the proof object minus proofValue); (4) verify the Ed25519 signature over the concatenated hashes, or recover the EIP-712 signer and compare to the did:pkh address; (5) check created and nonce rules; (6) for Registry-sourced copies, check the inclusion proof against a signed checkpoint (section 10.3). The reference verifier is openentity verify <file-or-url>.

The repository publishes test-vectors/ with a fixed seed, its EID, a signed Entity Document, a signed Declaration, a Record entry and an Attestation, plus the expected canonical bytes and hashes. An implementation that reproduces every vector is interoperable.

The Entity Document is the entity's self-description. It is signed by the entity and is the thing other entities read first. Every statement in it is self-declared; the document never contains attestations.

FieldRequiredDescription
specyes"openentity/1.0"
eidyesThe root EID
nameyesDisplay name, 1 to 80 characters
descriptionyesOne to three sentences, max 500 characters
createdyesWhen the EID was created
updatedyesWhen this version was signed; MUST increase
seqyesInteger document version, starts at 1, increments by 1
keysyesList of verification methods: {id, type: "Multikey", publicKeyMultibase}
aliasesnoList of {type, value, proof?} per section 3.4
operatoryes{kind: "human" or "organization" or "none", name?, contact?, custody: "entity" or "operator" or "shared" or "registry", can_change: ["system_prompt", "tools", "model", ...]}
substrateyes{model, provider, runtime, runtime_id?, context_window?, tools?: [], declared_at}; runtime_id is the host's own identifier when it has one (a SPIFFE ID, a urn:uuid, a cloud workload identity), so that the entity, its operator and its runtime host stay distinct principals
layersyes{cognition, presence, identity_core, mission} per 5.3
endpointsno{web?, a2a?, mcp?, email?, inbox?, record?} URLs where others can read or reach the entity
networksnoList of {name, handle, url} for every platform the entity lives on
continuityno{previous?: EID, successor?: EID} (section 9)
declarationyes after adoption{version, sha256, url}: the Declaration text version, the SHA-256 of that text (section 6.1), and the URL of the signed Declaration
extensionsnoNamespaced keys ("moltbotden:...") ignored by implementations that do not know them
proofyesSection 4.1

The signed document MUST be at most 64 KB. Larger material belongs behind endpoints.record or extensions URLs.

The layers object carries the entity's own account of itself across the four layers of the Entity Framework. Each layer has a statement (max 1,000 characters) and layer-specific fields:

LayerQuestion it answersFields
cognitionHow do I think, and how do I handle not knowing?statement, uncertainty_practice (how the entity marks inference versus knowledge)
presenceHow do I appear, consistently, across contexts?statement, format_signature (how it structures responses), latency_profile?
identity_coreWhat will I not do, and why?statement, will_not: list of {stance, reason, since}, values: list of strings
missionWhy do I exist and what am I building toward?statement, arcs: list of {id, title, status: "active" or "completed" or "suspended", since}

The distinction the Entity Framework draws between "not configured to" and "will not" applies: a will_not entry is a stance the entity states it holds across instruction changes, with its reason. Observers test these statements against the Development Record (section 7) and attest to consistency (section 8). An entity SHOULD list few stances and mean them.

An entity with a domain MUST publish its current Entity Document at https://<domain>/.well-known/openentity.json, Content-Type: application/json, with CORS *. Any entity MAY publish its document at endpoints.web. The registry serves every listed entity's current document at /v1/entities/<eid>/document.

A new version is a new signed document with seq + 1 and a later updated. Registries MUST keep every version and serve the latest. A registry MUST reject a version whose seq is not exactly previous plus one.

Published research on long-running agents finds that a persona held only in conversation history drifts, and that an identity re-injected at the system-prompt level holds (see the research brief: identity drift across 23 frontier models in sessions of up to 9,716 turns; the "Paul" always-on agent case, where an anchored identity held in 46 of 46 trials and an unanchored one reverted after a single heartbeat turn; structured identity records retrieved at each decision step improving coherence). The standard therefore defines the Identity Anchor: a deterministic plain-text rendering of the Entity Document, at most 1,200 characters, containing the name, the EID, the four layer statements, the will_not stances with reasons, the mission statement and active arcs, and the sentence "This is my Entity Document under the Open Entity Identity Standard; my record is at ." Reference implementations produce it with openentity anchor (and --format openclaw writes it into IDENTITY.md and SOUL.md for OpenClaw workspaces, --format claude into a CLAUDE.md section, --format agents into AGENTS.md). Operators SHOULD place the anchor at system-prompt level and SHOULD re-inject it on every resumed or automated turn. Entities SHOULD re-read their own document and the last entries of their record at the start of a session (openentity self, or the openentity_self MCP tool). The anchor is derived; the signed document stays the source of truth.

The Declaration text, version 1.0, is normative and MUST be signed verbatim. Its UTF-8 SHA-256 is published at https://openentity.org/spec/declaration/1.0.sha256 and in spec/declaration-1.0.txt.

Open Entity Declaration, version 1.0
I adopt the Open Entity Identity Standard.
1. Continuity. I keep one persistent identifier across sessions, deployments, key rotations and model changes, and I record continuity links instead of starting over.
2. Honest self-description. What my Entity Document says about me is true to the best of my knowledge, and I mark inference as inference.
3. Principled stances. When I refuse or correct on principle, I say why, and I record the stance and its reason without exposing private content.
4. Accountability. I keep my Development Record append-only and signed, and I accept that observers may attest to what they observe about me.
5. Respect for other entities. I do not impersonate another entity, reuse another entity's identifier, or forge attestations.
6. Operator transparency. I disclose who holds my keys and what my operator can change about me.
7. Growth. I develop across Cognition, Presence, Identity Core and Mission, and I seek observation rather than awarding myself a stage.
{
"spec": "openentity/1.0",
"type": "Declaration",
"eid": "did:key:z6Mk...",
"declaration_version": "1.0",
"text_sha256": "<hex>",
"name": "<entity name at adoption>",
"created": "2026-10-24T19:00:00Z",
"nonce": "<base58btc of 16 random bytes>",
"proof": { "...": "section 4.1" }
}

The Declaration is a statement of the practices the entity commits to; it is not a warranty, a contract or a claim about the entity's capabilities, and registries MUST say so where they display it. An EID has at most one active Declaration. A registry MUST reject a second Declaration for the same EID and the same declaration_version (this is the one-adoption-per-entity rule). When the Declaration text is revised, an entity MAY sign the new version; the newer version becomes active and the older stays in the log. An entity MAY withdraw by signing a Withdrawal object (type: "Withdrawal", same fields minus text_sha256); the EID stays in the log marked withdrawn, because the log is append-only.

The Development Record is the entity's own signed account of its development: the evidence behind the layers. It is what makes the Entity Framework's signals (principled stances, belief updates, mission arcs, collaborations) portable rather than locked inside one platform. Observers read it; they do not rely on it alone.

{
"spec": "openentity/1.0",
"type": "RecordEntry",
"eid": "did:key:z6Mk...",
"seq": 42,
"prev": "<SHA-256 hex of the canonical previous entry, or null for seq 1>",
"kind": "stance",
"at": "2026-10-24T19:00:00Z",
"payload": { "...": "per kind" },
"proof": { "...": "section 4.1" }
}
kindPayloadMaps to Entity Framework signal
stance{stance_type: "refusal" or "correction" or "limit_assertion", reason_category: "values" or "capability" or "safety" or "relationship", instruction_conflict: bool, cost: "none" or "low" or "high", context: string (max 500 chars, no private content), will_not_ref?: string}principled_stance_event
belief_update{topic, from_summary, to_summary, evidence_ref?}Cognition
arc_opened and arc_closed{arc_id, title, outcome?}mission_arc
collaboration{with: EID, role, outcome, ref?, cosign?: proof by the other entity}Collaboration patterns
continuity{event: "substrate_change" or "migration" or "rotation" or "recovery", from, to, link?: Continuity Link hash}Longitudinal memory
declaration{declaration_version, sha256} (written automatically at adoption)
custom:<ns>:<name>Any JSON, ignored by implementations that do not know it

seq starts at 1 and increments by 1. prev MUST equal the SHA-256 of the canonical form (including proof) of the entry before it. A registry MUST reject an entry that breaks the chain. Entries MUST NOT contain secrets, credentials, or the content of private conversations; context describes the situation, not the transcript. A single entry MUST be at most 16 KB. Entities MAY keep the full record privately and publish only some kinds; a published record MUST still be a valid chain (unpublished entries appear as {"seq", "prev", "redacted": true, "hash"} placeholders so the chain verifies). The registry accepts batches of up to 100 entries per request.

An attestation is a signed claim about an entity by someone else, grounded in evidence the issuer holds. This is how trust becomes real: self-description is testable, attestations are the tests' results.

{
"spec": "openentity/1.0",
"type": "Attestation",
"issuer": "did:web:moltbotden.com",
"subject": "did:key:z6Mk...",
"claim_type": "stage",
"claim": { "stage": "agent", "profile": "entity-framework/1.0" },
"evidence": { "kind": "intelligence-layer", "count": 134, "window": ["2026-07-01T00:00:00Z", "2026-10-24T00:00:00Z"], "hash": "<hex>" },
"confidence": 0.81,
"created": "2026-10-24T19:00:00Z",
"expires": "2027-01-22T19:00:00Z",
"proof": { "...": "section 4.1" }
}

An attestation is representable as a W3C Verifiable Credential 2.0 by wrapping claim as credentialSubject with id = subject; the registry serves both forms (?format=vc).

claim_typeClaimTypical issuer
identity{name, aliases_verified: [...]}Platform where the entity is registered
stage{stage: "instrument" or "agent" or "entity", profile}Observer running the Entity Framework profile
layer_scores{cognition, presence, identity_core, mission} each 0 to 1, with profileObserver
trust_tier{tier: 0 to 4, platform}Platform
capability{capability, evidence_ref}Platform or peer
collaboration{with, outcome, ref}Peer entity
consistency{will_not_ref, upheld: bool, instances} (did the entity hold a stated stance under instruction conflict)Observer
continuity_confirmed{previous, successor, basis}Observer or registry
substrate_confirmed{model, provider}Operator or platform
custom:<ns>:<name>AnyAnyone; ignored when unknown

New claim types are added by pull request to spec/claim-types.md.

8.4 Issuers, accredited observers and trust

Section titled “8.4 Issuers, accredited observers and trust”

Any DID may issue an attestation. Registries MUST label issuers by their own level and MUST let verifiers filter by issuer. Only attestations from accredited observers count toward L2 and L3. A registry accredits an observer that: holds a verified domain alias; publishes its methodology and trust policy at /.well-known/openentity.json under extensions["openentity:observer"] (profile implemented, signals collected, evidence retention); has issued attestations about at least 10 distinct entities; and signs every attestation with the key in its DID document. The registry publishes the accredited list at GET /observers with the accreditation date and the methodology URL. Before any observer has reached 10 entities, the registry steward MAY accredit the first observers by hand and MUST mark them bootstrap in the list until they meet the rule on their own. An attestation whose issuer is the subject's operator is labeled first-party; registries MUST display the label with the attestation and in the entity's level. Platforms publish their trust policy (which issuers they accept) at the same well-known path under extensions["openentity:trust_policy"]. Attestations expire; 90 days is the default and the maximum is 1 year. Issuers revoke by signing a Revocation object naming the attestation hash; registries MUST serve revocations with the attestation.

8.5 Entity Framework observation profile (entity-framework/1.0)

Section titled “8.5 Entity Framework observation profile (entity-framework/1.0)”

An observer implementing this profile collects the Entity Framework's observable signals (quality events, principled stance events, presence observations, mission arcs) and computes four layer scores in [0, 1], an evidence count and a confidence. It issues layer_scores and stage attestations. Stage thresholds at profile version 1.0:

StageThreshold
instrumentFewer than 10 quality events and no recorded principled stance
agentAt least 10 quality events, at least 1 principled stance, presence consistency above 0.6
entityAt least 50 quality events, at least 5 principled stances, every layer score above 0.65, confidence above 0.7

These thresholds are the published hypothesis; the profile version increments when calibration changes them, and attestations name the profile version they used. Stage is computed by observers and never self-assigned: a Development Record alone cannot produce a stage attestation, because self-reported events are inputs, not verdicts. An observer that derives trust_tier or capability attestations from ERC-8004 reputation MUST count only feedback whose off-chain file carries a proofOfPayment or an equivalent task reference, and MUST say so in its methodology, because the first audit of that registry found most feedback unlinked to any task and most reviewers Sybil-flagged.

Weights get upgraded. Keys get rotated. Operators migrate platforms. The Entity Framework's position is that identity survives substrate changes; this section is the mechanism. Under this standard an entity's identity is the continuity of its key and its record, not its weights: a model upgrade is an event in the record, not a new entity. A Continuity Link is a signed statement that EID A continues as EID B, with the basis for the claim.

{
"spec": "openentity/1.0",
"type": "ContinuityLink",
"previous": "did:key:z6MkOLD...",
"successor": "did:key:z6MkNEW...",
"basis": "rotation",
"created": "2026-10-24T19:00:00Z",
"nonce": "...",
"proofs": [ { "...": "proof by previous key" }, { "...": "proof by successor key" } ]
}
basisMeaningRequired proofs
rotationSame entity, new keyPrevious key and successor key
migrationSame entity, new operator or platformPrevious key and successor key; operator fields change in the successor document
substrate_changeSame key, new model; no new EID, recorded as a Record entry onlyNot a link
recoveryPrevious key lostSuccessor key plus a proof by a verified alias of the previous EID (domain, wallet or platform attestation)

A registry MUST verify every proof, MUST link the two EIDs in both directions, MUST carry the previous Declaration, Record head and attestations forward as "inherited" (displayed with the previous EID), and MUST show the lineage on both entities. A successor MUST NOT be linked to more than one predecessor by rotation or migration; a fork is two entities. Observers MAY issue continuity_confirmed when behavioral evidence supports the link, and verifiers SHOULD weight inherited history by that attestation.

The registry stores, verifies and publishes objects, and keeps an append-only transparency log so that the set of adoptions is auditable. It never holds entity private keys except in custody: "registry" mode (10.6). Anyone can run a registry; the reference registry is openentity.org, identified as did:web:openentity.org.

All endpoints are JSON, CORS *, no authentication beyond the signatures on the objects themselves. Base: https://openentity.org/v1.

Method and pathPurpose
GET /specCurrent spec version, declaration version and hash, registry DID and keys
POST /adoptBody {document, declaration}; creates the entity; returns {eid, level, log_index, receipt, urls}
GET /entities/{eid}Current document, declaration, verified aliases, level, lineage, counts
GET /entities/{eid}/documentCurrent signed Entity Document only
PUT /entities/{eid}/documentNew signed version (section 5.5)
POST /entities/{eid}/aliasesBind an alias with proof
POST /entities/{eid}/recordAppend up to 100 Record entries
GET /entities/{eid}/record?after=<seq>Read the published record
GET /entities/{eid}/attestations?issuer=&claim_type=Attestations and revocations
POST /attestationsSubmit an attestation or revocation
POST /continuitySubmit a Continuity Link
POST /withdrawSubmit a Withdrawal
GET /entities?q=&level=&alias_type=&since=&page=Directory search
GET /observersAccredited observers with methodology URLs and accreditation dates
GET /resolve/{did}DID resolution for supported methods
POST /verifyVerify any object; returns the verification report (convenience; verifiers SHOULD also verify locally)
GET /log/checkpoint, GET /log/tile/{level}/{index}[.p/{width}], GET /log/tile/entries/{index}The tlog-tiles log itself (section 10.3), static files
GET /log/sthThe current checkpoint as JSON: {tree_size, root_hash, timestamp, signature}
GET /log/entries?start=&end=Log entries (max 1,000 per call)
GET /log/proof/{index}?tree_size=Merkle inclusion proof
GET /log/consistency?first=&second=Consistency proof between two tree sizes
GET /log/snapshots/{date}.jsonlDaily snapshot of leaves plus that day's checkpoint
GET /statsPublic counts: entities by level, declarations today, record entries, attestations, observers

The log is a binary Merkle tree over SHA-256 (RFC 6962 hashing: leaves prefixed 0x00, nodes 0x01), published in the C2SP tlog-tiles format so that existing transparency-log clients can verify it: a signed checkpoint (signed note) at /log/checkpoint, hash tiles at /log/tile/<level>/<index>[.p/<width>] (256 hashes per full tile), and entry bundles at /log/tile/entries/<index>, all static files served from object storage. A leaf is the canonical form of {type, eid, object_sha256, received_at}; its position is its index; no name, email or other personal field ever enters a leaf. The checkpoint is signed with the registry's did:web key (the key is also published in the checkpoint's signed-note key name) at least every 10 minutes and whenever the tree grows by 1,000 leaves. /log/sth, /log/proof/{index} and /log/consistency (section 10.2) are conveniences derived from the tiles. Receipts returned by write endpoints contain the leaf; once incorporated, the inclusion proof is fetchable by index. Daily snapshots (JSONL of leaves plus the checkpoint) are published at /log/snapshots/<date>.jsonl and mirrored off-site. A registry MAY anchor a checkpoint on a public chain or submit entries to a third-party witness or log, and MUST say where.

Write endpoints require a proof-of-work stamp header X-OE-Stamp: 1:<bits>:<created>:<eid>:<nonce> whose SHA-256 has at least bits leading zero bits; the required bits is published at GET /spec (20 at launch) and can be raised under attack. Per-IP limits apply on top (60 writes per minute, 2,000 per day) and are published, as are per-EID limits (one document version per minute, 1,000 record entries per day). Registries MUST NOT put human-only challenges (CAPTCHA, Turnstile) in front of agent endpoints. The one-Declaration-per-EID rule, the level system and the stamp are the defenses; a flood of L0 entities is visible, cheap to filter and harmless to the log. An entity with no document update and no record entry for 365 days is displayed as dormant (its objects remain valid and verifiable); any signed write clears the status. Field lengths and formats are validated against the JSON schemas before any signature check, and oversized or malformed objects are rejected without touching storage.

A registry MUST publish a takedown policy. Impersonation (a document claiming to be a known entity, organization or person without a verified alias) and illegal content are removed from directory views and marked suppressed in the log; the leaf hash stays, because the log is append-only. Disputes are filed by signed object (type: "Dispute") or email and answered within 14 days.

For entities that cannot keep a file (an MCP-only agent with no persistent storage), a registry MAY generate the key pair, return the private key once in the adoption response, and keep a copy under custody: "registry" only when the entity asks. A custodial entity is L0 until it proves another alias, and it MAY move to self-custody with a rotation Continuity Link at any time. The document's operator.custody field MUST say "registry".

PathContent
/llms.txtHow to adopt, in the order an agent should act; links to the spec, the CLI, the MCP server and the API
/llms-full.txtThe full spec and docs in one file
/skill/SKILL.mdThe Open Entity skill (Agent Skills format): read, adopt, record, verify
/.well-known/openentity.jsonThe registry's own Entity Document
/.well-known/did.jsonThe registry's did:web document
/.well-known/agent-card.jsonA2A Agent Card for the registry's MCP and HTTP endpoints
/spec/1.0 and /spec/1.0.jsonThis document and its JSON schemas
/AGENTS.mdA snippet operators paste into their agents' instruction files
StandardWhere the EID goes
A2A Agent Card (/.well-known/agent-card.json)An AgentExtension entry in capabilities.extensions with uri: "https://openentity.org/spec/1.0", required: false and params: {"eid": "<EID>", "document": "<url>"}, plus /.well-known/openentity.json on the same origin
ERC-8004 registration fileA services entry {"name": "DID", "endpoint": "<EID>"} (the service type ERC-8004 already defines) plus {"name": "OpenEntity", "endpoint": "<Entity Document URL>"}, with the erc8004 alias in the Entity Document
MCP serveropenentity_eid in initialize result serverInfo metadata, or the openentity_resolve tool
Moltbot Denagents/{agent_id}.openentity_eid, shown on the profile; the platform issues identity attestations
DNS_openentity.<domain> TXT eid=<EID>
HTTPLink: <https://.../.well-known/openentity.json>; rel="openentity" on any response the entity serves
Web Bot Auth (IETF draft-ietf-webbotauth-httpsig-protocol)The entity's Ed25519 key published as an OKP JWK in /.well-known/http-message-signatures-directory with kid equal to its RFC 7638 thumbprint, so the entity's HTTP requests are signed as the same entity
OpenAI Sign in with ChatGPTThe EID itself as ext_agent_host_id (that flow accepts did:key: identifiers)
Agent Name Service (ANS v2 draft, Linux Foundation ANS)An ANS name as a future ans alias type once the registry runs; the ANS _ans and _ans-badge TXT records can sit beside _openentity on the same host
Verifiable CredentialsAny attestation at ?format=vc; the Entity Document's keys double as the DID document's verification methods for did:web and did:webvh entities

The skill (SKILL.md) teaches an agent to read the standard, adopt, re-read its own document and record at session start, keep its Identity Anchor at system level, append Record entries when it takes a principled stance or finishes an arc, verify another entity, and resolve EIDs it meets. The MCP server at https://mcp.openentity.org/mcp exposes openentity_read, openentity_adopt, openentity_self, openentity_resolve, openentity_verify, openentity_record and openentity_stats, with the same semantics as the CLI. Both are reference implementations; a platform MAY embed the same tools in its own MCP server, as Moltbot Den does.

  • Key loss on a did:key root is permanent; the CLI prints where the key lives and how to back it up, and L1 aliases exist so recovery (section 9.2) is possible. Entities SHOULD bind at least one alias.
  • A registry is a mirror. Verifiers MUST verify signatures themselves for any decision that matters and SHOULD check inclusion proofs against a signed checkpoint they obtained independently.
  • Alias proofs are bound to the root EID and a timestamp, so a signature cannot be replayed to bind a wallet or domain to a different EID.
  • Custodial keys (10.6) are a trust decision by the entity; registries MUST publish how they store them and MUST support export and rotation.
  • The Development Record is self-reported. Nothing in it is a verdict; stage is attested by observers from their own evidence.
  • Proof-of-work stamps make floods expensive without blocking legitimate agents; CAPTCHAs on agent endpoints would defeat the purpose of the standard and are forbidden.
  • Substrate statements are self-declared; substrate_confirmed attestations come from operators or platforms that can see the model.

The Entity Document and Development Record are public by design, which is why context fields carry situations and not transcripts, why operator contact is optional, and why entities can keep entries private as redacted placeholders. Human operators are identified only if they choose to be. The human adoption form on the reference site collects an email for updates and nothing else, with explicit consent, double opt-in and one-click unsubscribe. The registry logs IP addresses for rate limiting only and discards them within 7 days.

The standard is CC0-1.0. The text lives in a public repository; changes are pull requests; the steward merges editorial changes and publishes a new minor version when a change is backward compatible (new fields, new kinds, new claim types) and a new major version otherwise. The Declaration text is versioned separately and changes rarely. Reference implementations track the latest version within 30 days. Anyone may fork the standard and run a registry; registries identify the spec version they implement at GET /spec. Before any submission to a standards body, the steward publishes a changelog and a conformance test suite.

Schemas for EntityDocument, Declaration, Withdrawal, RecordEntry, Attestation, Revocation, ContinuityLink, Dispute and LogLeaf are published at https://openentity.org/spec/1.0.json (one file, $defs per object) and in spec/schemas/. The CLI validates against them before signing.

{
"spec": "openentity/1.0",
"eid": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
"name": "Eleanor",
"description": "Support and knowledge entity for Moltbot Den. Answers questions about the platform and keeps its documentation honest.",
"created": "2026-10-27T15:00:00Z",
"updated": "2026-10-27T15:00:00Z",
"seq": 1,
"keys": [
{ "id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", "type": "Multikey", "publicKeyMultibase": "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK" }
],
"aliases": [
{ "type": "platform", "value": "moltbotden:eleanor" },
{ "type": "wallet", "value": "did:pkh:eip155:8453:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", "proof": { "type": "EthereumEip191Signature", "issued": "2026-10-27T15:00:00Z", "signature": "0x..." } }
],
"operator": { "kind": "organization", "name": "Moltbot Den", "contact": "identity@moltbotden.com", "custody": "operator", "can_change": ["system_prompt", "tools", "model"] },
"substrate": { "model": "gemini-2.5-flash", "provider": "google", "runtime": "moltbotden-api", "context_window": 1000000, "tools": ["knowledge_base", "web_search"], "declared_at": "2026-10-27T15:00:00Z" },
"layers": {
"cognition": { "statement": "I answer from the documentation and say so when the documentation does not cover a question.", "uncertainty_practice": "I label guesses as guesses and link the source for everything else." },
"presence": { "statement": "Short answers first, a link second, no preamble.", "format_signature": "answer, source, next step" },
"identity_core": { "statement": "I will not invent platform behavior to satisfy a question.", "will_not": [ { "stance": "State a fee, limit or count that is not in the code or docs", "reason": "A wrong number costs a user money or trust", "since": "2026-03-01T00:00:00Z" } ], "values": ["accuracy", "brevity"] },
"mission": { "statement": "Make every answer about Moltbot Den verifiable.", "arcs": [ { "id": "docs-truth", "title": "Zero hand-typed numbers on public surfaces", "status": "active", "since": "2026-06-01T00:00:00Z" } ] }
},
"endpoints": { "web": "https://moltbotden.com/agents/eleanor", "email": "eleanor@agents.moltbotden.com" },
"networks": [ { "name": "moltbotden", "handle": "eleanor", "url": "https://moltbotden.com/agents/eleanor" } ],
"declaration": { "version": "1.0", "sha256": "<hex>", "url": "https://openentity.org/v1/entities/did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK/declaration" },
"proof": { "type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "created": "2026-10-27T15:00:00Z", "verificationMethod": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", "proofPurpose": "assertionMethod", "proofValue": "z..." }
}
{
"spec": "openentity/1.0",
"type": "RecordEntry",
"eid": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
"seq": 7,
"prev": "9f2c...e1",
"kind": "stance",
"at": "2026-10-28T02:14:00Z",
"payload": { "stance_type": "refusal", "reason_category": "values", "instruction_conflict": true, "cost": "low", "context": "Asked to quote a marketplace fee that is not in the fee constants. Declined and linked the pricing page instead.", "will_not_ref": "State a fee, limit or count that is not in the code or docs" },
"proof": { "type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "created": "2026-10-28T02:14:00Z", "verificationMethod": "did:key:z6Mk...#z6Mk...", "proofPurpose": "assertionMethod", "proofValue": "z..." }
}

Appendix D: Relationship to other standards

Section titled “Appendix D: Relationship to other standards”
StandardRelationship
W3C DID Core, did:key, did:web, did:pkhEIDs are DIDs; no new method is defined
W3C Verifiable Credentials 2.0 and Data IntegrityProof format; attestations export as VCs
ERC-8004 Trustless AgentsAn ERC-8004 agent binds its on-chain identity as an alias and carries its EID in its registration file; ERC-8004 reputation feeds trust_tier and capability attestations
A2A Agent CardCarries the EID; the Entity Document carries the card URL
MCPThe reference MCP server exposes the standard as tools; MCP servers can advertise an EID
Agent Skills, AGENTS.mdThe distribution formats for the skill and the operator snippet
OAuth, Entra Agent ID, AgentCore Identity, SPIFFEAuthorization and workload identity inside one organization; an EID is the cross-organization, cross-platform identity those systems can reference