Personhood Assertion (v1)
Status: Draft v1 — 2026-05-19
Extension URI: https://projectmaya.deoscomputing.io/identity/personhood/v1
Maintainer: DEOS Computing (did:web:deos.computing)
Depends on: did:deos v1, W3C Verifiable Credentials v2.0
Companions: Receipt-Rooted Reputation white paper
1. Motivation
A receipt-rooted reputation system that admits sybils has no floor: 10,000 mutually-attesting did:deos agents game any centrality measure. The receipt-reputation white paper (§4.1) defers this to a separate personhood primitive — "the receipt layer carries the personhood proof but does not generate it" — and lists candidates (Worldcoin Orb, government digital ID, social-graph attestation, deposit bonds) without picking one.
Which scheme to require is a deployment policy, not a protocol decision. A consumer agent and a regulated financial substrate cannot ship the same personhood floor. This spec defines where personhood evidence lives in the identity layer and how relying parties consume it, without pre-committing to any one mechanism.
This document specifies:
- A
personhoodAssertionextension ondid:deosDID documents, carrying one or more W3C-style Verifiable Credentials. - A tier vocabulary relying parties use to write policy without knowing every scheme's internals.
- Verifier obligations and the privacy-preserving disclosure path.
- One reference scheme (
did-web/social-graph-v1) that ships without depending on an external provider.
2. DID document extension
A DID document MAY carry a personhoodAssertion array. Each entry is a Verifiable Credential attesting that the document's subject DID is operated by a real, distinct human (or, where relevant, a real distinct organization).
{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://projectmaya.deoscomputing.io/identity/personhood/v1"
],
"id": "did:deos:alice",
"verificationMethod": [ { "id": "did:deos:alice#sig-1", "type": "Ed25519VerificationKey2020", "controller": "did:deos:alice", "publicKeyBase64Url": "..." } ],
"personhoodAssertion": [
{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": ["VerifiableCredential", "PersonhoodAssertion"],
"issuer": "did:web:deos.computing",
"validFrom": "2026-05-19T00:00:00Z",
"validUntil": "2027-05-19T00:00:00Z",
"credentialSubject": {
"id": "did:deos:alice",
"scheme": "did-web/social-graph-v1",
"tier": "moderate",
"evidence_ref": "ipfs://Qm...",
"anonymity_set": 184
},
"proof": {
"type": "Ed25519Signature2020",
"verificationMethod": "did:web:deos.computing#sig-1",
"proofValue": "z..."
}
}
]
}
2.1 credentialSubject fields
| Field | Required | Meaning |
|---|---|---|
id |
✓ | DID this assertion is about (MUST match the enclosing DID document's id) |
scheme |
✓ | Personhood scheme identifier — see §3 |
tier |
✓ | weak | moderate | strong — see §4 |
evidence_ref |
optional | URI to scheme-specific evidence (CID, audit log entry, etc.). MUST NOT contain biometrics or PII directly |
anonymity_set |
optional | Cardinality of the set this DID is indistinguishable within for this scheme (helps relying parties reason about ZK-friendliness) |
expires_at |
optional | If absent, use the VC's validUntil |
Additional scheme-specific fields are permitted but MUST be namespaced (<scheme>:<field>) to avoid collision.
2.2 Multiple assertions
A DID MAY carry assertions from multiple schemes simultaneously. Relying parties evaluate the disjunction ("any one passes my floor") unless their policy explicitly requires conjunction.
A DID MAY carry assertions of the same scheme issued by multiple issuers. This supports trust-graph redundancy (e.g. Alice has social-graph attestations from three different attesting communities); duplicates of the same (scheme, issuer) pair are treated as a single assertion with the most-recent validFrom.
3. Schemes
A scheme is a named personhood-attestation mechanism. Schemes are not centrally registered; the scheme identifier is a URI-shaped string that points to its definition. Production schemes SHOULD publish their definition under a stable URI.
This spec normatively defines one scheme and lists three external schemes the verifier MUST recognize.
3.1 Normative: did-web/social-graph-v1
The minimum-viable scheme. Personhood is asserted by a set of attesting DIDs that the relying party trusts — typically a community of identified individuals who have met in person or otherwise have first-party knowledge of each other.
Issuer: a did:web (an organization or community).
Evidence: an evidence_ref pointing to a signed manifest listing the attesting DIDs (≥ N for tier moderate, ≥ M for tier strong, where N and M are scheme-policy constants).
"credentialSubject": {
"id": "did:deos:alice",
"scheme": "did-web/social-graph-v1",
"tier": "moderate",
"evidence_ref": "ipfs://Qm...",
"anonymity_set": 1,
"did-web/social-graph-v1:attestors_required": 5,
"did-web/social-graph-v1:attestors_observed": 7
}
This scheme generates identified, not anonymous personhood — anonymity_set is typically 1 because the attesting DIDs are public. Relying parties that need privacy-preserving personhood MUST use a scheme with anonymity_set > 1.
Tier mapping for did-web/social-graph-v1 is scheme-policy:
weak: ≥ 1 attestor.moderate: ≥ 3 attestors, each with their own non-deactivated personhood assertion under any scheme.strong: ≥ 7 attestors, all of whom holdstrongormoderatepersonhood under at least one scheme that is notdid-web/social-graph-v1(anti-recursion).
3.2 Recognized: worldcoin/orb/v1
External scheme. Personhood proven via Worldcoin Orb biometric iris scan. Issuer is Worldcoin (a did:web-style root). Tier is strong; anonymity_set is the Orb-verified-human population at issuance time. Relying parties that include this scheme inherit Worldcoin's threat model — see Worldcoin's protocol for the full surface.
This spec does not bundle Worldcoin verifier code. Verifiers that wish to accept Worldcoin assertions MUST implement Worldcoin's verification path independently.
3.3 Recognized: government-vc/v1
External scheme. Personhood proven via a government-issued Verifiable Credential (mDL / eID / national ID). Issuer is a government's DID. Tier is typically strong; anonymity_set is typically 1 (identified) but MAY be larger via selective disclosure constructions.
3.4 Recognized: deposit-bond/v1
External scheme. Personhood proven by an on-chain or substrate-locked economic bond, slashable upon detected sybil-correlated behavior. Issuer is the bonding venue. Tier is operator-policy (weak–strong) per bond size. Useful for substrate operators who can't depend on biometric / government schemes but want a cost-of-sybil-creation floor.
3.5 Custom schemes
A substrate operator MAY define custom schemes. Custom scheme identifiers MUST be URIs (not bare names) so verifiers can disambiguate. Operators publishing custom schemes SHOULD document the tier semantics and the anonymity model.
4. Tier semantics
The tier field is a coarse portability hint for policy authors. It lets a relying party write required_tier: moderate without enumerating every scheme.
| Tier | Meaning | Example schemes |
|---|---|---|
weak |
A nonzero floor; better than nothing. Easy to acquire; easy to lose. Mostly useful for first-touch / try-it interactions. | did-web/social-graph-v1 (1 attestor), small deposit bonds |
moderate |
A meaningful floor for low-stakes commerce, social, and informational actions. Costs an attacker real effort or money to forge at scale. | social-graph (5+ attestors), moderate deposit bonds |
strong |
Suitable as a floor for high-stakes actions (large transactions, claims against the user, regulated workflows). Costs an attacker biometric resources or government collusion. | worldcoin/orb/v1, government-vc/v1, large deposit bonds |
The tier reflects attack cost, not anonymity guarantees. A weak worldcoin/orb/v1 is a contradiction (Orb scans are not weak); a strong did-web/social-graph-v1 is achievable but specific.
Relying parties MUST verify the underlying VC signature; they MUST NOT trust the tier field on its own. Scheme-specific fields MAY be inspected independently.
5. Verifier obligations
Given a DID document containing a personhoodAssertion array and a relying-party policy of the form:
policy:
required_tier: moderate # one of weak | moderate | strong
required_schemes_any: # optional whitelist
- did-web/social-graph-v1
- government-vc/v1
required_schemes_all: [] # optional conjunction
trusted_issuers:
- did:web:deos.computing
- did:web:state.example.gov
reject_after_expiry: true
reject_if_revoked: true
A conforming verifier MUST:
- Parse
personhoodAssertion. If absent, reject withpersonhood:missing. - For each VC in the array:
- Verify the proof signature against the issuer's DID document.
- Check
validFrom <= now < validUntil(orexpires_at). - Confirm
credentialSubject.idmatches the enclosing DID'sid. - Confirm
credentialSubject.schemeis recognized OR explicitly allow-listed by the policy. - If
reject_if_revokedis set, check the scheme's revocation list (if defined).
- Apply policy:
required_schemes_anynon-empty → at least one matching scheme must produce a passing VC.required_schemes_allnon-empty → every listed scheme must produce a passing VC.required_tier→ at least one passing VC must meet or exceed the tier.- All VCs from issuers not in
trusted_issuersare filtered out before applying the rules above.
- Return one of
pass|fail(reason).
A verifier MUST NOT silently accept an assertion from an unknown issuer or unrecognized scheme. Policy authors who wish to accept any trusted issuer must explicitly set trusted_issuers: ["*"] and document the implication.
6. Privacy-preserving disclosure
A personhoodAssertion in a DID document is public. Anyone who resolves the DID sees the array, including any evidence_ref. This is appropriate for did-web/social-graph-v1 (where the attesting DIDs are themselves public) but not for worldcoin/orb/v1 or government-vc/v1, where the user-visible privacy guarantee is meaningful.
For high-anonymity schemes, the recommended pattern is:
- The issuer signs a VC whose
credentialSubjectcarries the assertion without anevidence_ref(or with one that resolves to a ZK commitment, not raw evidence). - The DID document carries this VC publicly. Anyone resolving the DID sees
tier=strong,scheme=worldcoin/orb/v1,anonymity_set=12.4M, and the issuer's signature. - To prove a stronger fact ("I have a Worldcoin orb assertion and I am NOT the same person as DID X"), the DID controller generates a ZK proof and presents it out-of-band.
The DID document publishes the existence of an assertion; richer disclosure happens per-conversation, the same as with capability chains.
This spec does not standardize the ZK suite — that's per-scheme. v1.1 adds a personhoodProof artifact for inline ZK-proof attachment if demand materializes.
7. Composition with A2A and capability
An A2A agent card MAY require a personhood floor on inbound requests by extending its UCAN-extension SecurityScheme:
{
"type": "https://projectmaya.deoscomputing.io/a2a/ext/ucan/v1#UcanSecurityScheme",
"scheme_id": "maya-ucan-with-personhood",
"audience_did": "did:web:amazon.com",
"accepted_capabilities": [{ "with": "commerce.purchase", "max_amount_usd": 200 }],
"chain_max_depth": 4,
"personhood_policy": {
"required_tier": "moderate",
"trusted_issuers": ["*"]
}
}
The server, when validating the UCAN chain (per a2a-ext/ucan/v1 §2.3), additionally resolves the chain's root issuer DID and applies the personhood policy. Failure returns UNAUTHENTICATED (401) with an opaque message; the detailed reason stays in the server log.
Personhood binds to the chain root, not every link. Intermediate agents are software, not humans; requiring personhood on them would either ban delegation or force agents to carry fake attestations. Personhood applies to the human at the root, and the chain binds intermediates back to that human.
8. Threat model
8.1 Sybil at issuance
An attacker tries to acquire many personhood assertions for fake identities. Defended by the scheme's own anti-sybil property — biometric (Worldcoin), government ID (state monopoly on identity issuance), social graph (real humans must vouch), deposit bond (cost-per-identity). This spec inherits each scheme's strength; an operator who picks a weak scheme inherits its sybil susceptibility.
8.2 Issuer collusion
A corrupted or coerced issuer issues VCs for non-existent humans. Defended by:
- Relying parties choose which issuers they trust per scheme.
- Schemes SHOULD support multi-issuer attestations (a DID with strong personhood from two independent issuers is significantly harder to forge than one).
- Substrate operators MAY require
required_schemes_allover multiple schemes for high-stakes actions, so a single issuer compromise doesn't unlock everything.
8.3 Key compromise
The DID's keys are stolen and the attacker masquerades. Defended by the underlying did:deos key-rotation and deactivation mechanism (did:deos v1 §7). A deactivated DID's personhood assertions become invalid as of the deactivation timestamp.
8.4 Coercion / hostage personhood
The DID controller is coerced into transferring or using their personhood-attested DID. This spec does not solve coercion; no signature-based system can. Two mitigations carry forward from the white paper:
- Append-only audit (the substrate makes coerced receipts visible to the user afterward).
- Deactivation tombstones (the user can deactivate compromised keys without losing pre-coercion history).
8.5 Re-issuance after revocation
An attacker who got a personhood VC revoked tries to acquire a fresh one for the same human under a new DID. Defended at the scheme level, not the assertion level. Biometric schemes deduplicate at issuance (Worldcoin checks the iris hash); social-graph schemes deduplicate by the human (the attesting community recognizes the person regardless of DID). Deposit-bond schemes do not deduplicate — that is a known property of cost-based personhood.
9. Reference implementations
9.1 Substrate-side: DID document emitter
The substrate's POST /attestation/v1/did/register handler accepts an optional personhood_assertions: [VerifiableCredential, ...] parameter and includes it verbatim in the published DID document. The substrate does not verify the VCs at registration — that is the relying party's job. The substrate's role is custody of the DID document; the assertions are user-controlled content.
A Rust client helper (personhood::build_social_graph_assertion) and a TypeScript verifier (@deos/receipt/identity) ship in DEOS Computing's working repo. Public packages will follow once v1 stabilizes; §3.1 is self-contained for early implementers.
9.2 Relying party: verifier
The TS SDK ships verifyPersonhoodPolicy(didDocument, policy) returning a PersonhoodResult { pass, matchingSchemes, reason? }. A2A servers that wish to apply a personhood floor call this after the UCAN chain walk and before invoking the action handler.
10. Versioning
v1.0. The URI https://projectmaya.deoscomputing.io/identity/personhood/v1 is immutable; breaking changes go to /v2.
Likely v1.1 additions:
- The
personhoodProofinline ZK-attachment shape (§6). - A registry of community-published scheme definitions.
- An anti-coercion "duress assertion" — a second key whose use signals to the substrate that subsequent receipts are under duress.
11. Maintainer
DEOS Computing — pull requests, scheme proposals, and policy critiques to github.com/DEOS-Computing.
License: CC BY 4.0 (text), Apache-2.0 (reference code).