[RFC] Human-Bound Agent Credentials: ZK "verified human" + "agent of a verified human" IDs on NEAR
- andrewmoroneyOP
Author: Andrew Moroney, Brisbane, Australia
TL;DR: I’m proposing an open NEAR standard with two parts. People get a private, zero-knowledge “unique human” credential. Each AI agent they run gets an “I am an agent” credential that provably links back to a verified human. With these, creators can prove a post was made by a person, and agents can prove they act for a real person. Apps can also enforce one account, or N actions, per human. Nobody learns who the person is, and nobody can track them across apps. The full write-up (5 pages including a technical appendix) is attached as a PDF.
Why
Bots now look like people, and legitimate agents look like bots. CAPTCHAs and paid “blue ticks” don’t solve either problem. World’s AgentKit has shown there’s demand for “human-backed agents”, but it depends on a single biometric issuer. NEAR already has most of the pieces for an open, multi-attester version: I-AM-HUMAN / NEP-393, function-call access keys, Chain Signatures, NEAR AI TEE attestation, IronClaw and Agent Market.
Design in brief
- Attesters sign a commitment the user generates locally,
C_h = Poseidon(s_h, r). Attesters could include passport NFC (as in zkPassport), biometrics, KYC providers such as Fractal, and social vouching. No personal data goes on-chain. - Registry contract. Commitments are stored in a Merkle tree, alongside an attester list and a revocation set. This could extend the NEP-393 registry.
- Agent credential. The human’s key, or a scoped access key, signs
{agent_pubkey, scope, expiry, quota}, bound toH(s_h). - ZK proofs (Semaphore-style, Groth16 or Halo2). There are two of them: Proof of Human and Proof of Human-Backed Agent. Both include an app-scoped nullifier
N = H(s_h, app, epoch). That gives anti-Sybil protection and per-human rate limits without letting apps link the same person. - Revocation, expiry and recovery. Recovery works through attester re-issuance, NEAR multi-key or social recovery, and an optional MPC backup.
- Optional TEE attestation (NEAR AI Cloud / Intel TDX) shows exactly what code an agent is running.
- Verifier SDK and a C2PA-style badge so posts and media can carry a “verified human” or “agent of a verified human” mark.
Prior art
- World ID + AgentKit
- I-AM-HUMAN (public SBTs, not anonymous)
- Semaphore / RLN
- zkPassport and Anon Aadhaar
- human.tech and Humanity Protocol
- ERC-8004 (agent IDs with no link to a human)
- W3C DID / VC and C2PA
The gap: an open, multi-attester zero-knowledge link from an agent to a unique human. It would include app-scoped nullifiers, per-human quotas, revocation and content signing.
Questions for the community
- Who should govern attesters? House of Stake, or stake-and-slash?
- How do we dedupe people across attesters, and stop people renting out their credential?
- Groth16 or Halo2, and what would on-chain verification cost in gas on NEAR?
- Would NEAR AI (IronClaw / Agent Market) be interested in piloting the agent side?
- Would the I-AM-HUMAN maintainers support a migration path?
If there’s interest, I’ll turn this into a draft NEP (Contract Standard) for the near/NEPs repository. Feedback is very welcome.
— Andrew Moroney
The full proposal is posted in full in the reply below.
- Attesters sign a commitment the user generates locally,
- andrewmoroney 1
Full proposal text below (new accounts cannot attach PDFs yet).
Human-Bound Agent Credentials on NEAR
A zero-knowledge “verified human” and “agent of a verified human” layer
Author: Andrew Moroney, Brisbane, Australia · Status: Idea / request for comment · Date: October 2026
1. Summary
The internet is about to have more AI agents than people. Platforms, creators and users need two simple answers without giving up anyone’s privacy:
- “Is this account a real, unique human?” — without revealing which human.
- “Is this agent acting for a real human, and which human’s quota is it using?” — without revealing who that human is, and without letting sites link the same person across apps.
This proposal describes a NEAR-native standard and reference contracts for anonymous human credentials and agent credentials cryptographically bound to them, verified with zero-knowledge proofs (ZKPs). A creator can attach a “human-made” proof to a post. An agent can attach an “agent of a verified human” proof to a request. Neither proof reveals the person, and each app sees a different, unlinkable pseudonym (a nullifier) for the same person.
NEAR is well placed to lead here: it already has a personhood registry (I-AM-HUMAN, NEP-393 soul-bound tokens), named accounts with scoped access keys, Chain Signatures to project credentials onto other chains, and NEAR AI’s TEE-attested inference and agent stack (IronClaw, Agent Market).
2. The problem
- Bots look like people. Generative AI makes fake accounts, reviews and posts cheap. “Blue tick” style verification either costs money (which bots can pay) or requires handing ID to each platform (a privacy and data-breach risk).
- Good agents look like bots. Legitimate agents booking, buying, posting or researching for a person are blocked by CAPTCHAs and anti-bot systems because sites cannot tell them apart from swarms.
- Existing answers are partial. Proof-of-personhood systems prove a human; agent registries (e.g. ERC-8004) give agents an identity and reputation; very few cleanly prove “this agent belongs to a unique human” in zero knowledge, with per-app unlinkability, per-human rate limits and revocation — and none of them do so on NEAR.
3. The proposal in one picture
Attesters (passport NFC, biometrics, social vouching, KYC providers) │ sign "this is a unique human" claim (never published) ▼ Human wallet ──► holds secret s_h ──► commitment C_h = H(s_h, attester_set) │ │ inserted into │ ▼ │ NEAR Registry contract (Merkle tree of C_h, │ revocation list, attester registry) │ signs delegation ▼ Agent key k_a ──► agent credential: {agent_pubkey, scope, expiry, quota} bound to s_h inside a ZK circuit │ ▼ Verifier (social app, API, website, other chain via Chain Signatures) receives ZK proof: "member of tree, not revoked, scope=X, nullifier N = H(s_h, app_id, epoch)" → learns nothing else4. Design
4.1 Human credential issuance. A person obtains one or more attestations from approved attesters: passport/ID chip reading (NFC, like zkPassport), biometric uniqueness (like World ID or Humanity Protocol), KYC providers (like Fractal, already used by I-AM-HUMAN), or social vouching/in-person events. The attester checks uniqueness against its own dedup index and signs a claim over a commitment the user generates locally:
C_h = Poseidon(s_h, r), wheres_his a secret held only by the user. The attester never seess_h; the chain never sees the person’s data. Apps can require a minimum “assurance level” (e.g. one strong attester, or two independent ones).4.2 On-chain registry. A NEAR contract (
humans.registry.near, illustrative) storesC_has leaves of an incremental Merkle tree (Poseidon hash, depth ~32), a registry of approved attesters and their policy, a revocation set, and recent roots. Because only commitments are stored, membership reveals nothing. It can reuse/extend the NEP-393 SBT registry so existing I-AM-HUMAN holders can migrate.4.3 Agent credentials. The human creates an agent credential by signing (with their NEAR key, or a scoped delegated key) a statement
{agent_pubkey, scope, expiry, quota, agent_type}and committing it asC_a = Poseidon(agent_pubkey, H(s_h), scope, expiry). The agent credential is public as an agent (“I am an AI agent”), but its link to the human exists only inside ZK proofs. One human may have many agents; all draw on the same per-human quota.4.4 Zero-knowledge proofs. Two core statements:
- Proof of Human (PoH): “I know
s_hwhose commitment is in the registry under root R, it is not revoked, and my nullifier for app A in epoch E isN = Poseidon(s_h, A, E).” - Proof of Human-Backed Agent (PoHBA): “I control
agent_pubkey, which was delegated by somes_hin the registry, the delegation is unexpired and in scope, and the human’s nullifier for app A is N.” The agent signs the request/post withagent_pubkey.
Circuits in Groth16 (small proofs, cheap verification; needs a trusted setup — can reuse Semaphore’s ceremony style) or PLONK/Halo2 (universal or no trusted setup). Proof generation on a phone takes ~1–3 s for Semaphore-sized circuits.
4.5 Anti-Sybil and unlinkability. The nullifier
Nis stable per app (and optionally per epoch) but different across apps. A site can enforce “one account per human” or “max 20 agent actions per human per hour” without knowing the person, and two sites cannot compare nullifiers to track them.4.6 Rate limits per human. Quotas are enforced by verifiers by counting nullifiers per epoch (as in World AgentKit and Semaphore-based RLN, “rate-limiting nullifiers”). RLN-style proofs can make exceeding a quota self-revealing (spam leaks a share of the secret, enabling slashing or automatic revocation).
4.7 Revocation and expiry. Attesters can revoke (e.g. a passport reported stolen); humans can revoke any agent instantly by publishing its revocation tag; credentials expire. Proofs are checked against a non-revoked set (sparse Merkle non-membership or accumulator) and a recent root.
4.8 Key recovery.
s_hlives in the user’s wallet. Recovery options: NEAR’s multi-key accounts and social recovery; re-issuance by the original attester (old commitment revoked, new one added — the attester’s dedup index prevents duplicates); optional MPC-backed backup using NEAR’s existing MPC network (the network that runs Chain Signatures).4.9 Optional TEE attestation of the agent runtime. An agent can add a NEAR AI Cloud / Intel TDX attestation proving what code and model is running. Combined with PoHBA, a verifier gets: “a verified human authorised this agent, and the agent is running this audited software” — useful for finance, healthcare and Agent Market jobs.
4.10 Verifier SDK and content badges. A small JS/Rust/Python SDK:
verifyHuman(proof, appId)/verifyAgent(proof, appId, scope), plus a REST verifier and a NEAR view method for on-chain checks. For media, embed the proof in a C2PA manifest so photos, videos and posts can show a “Made by a verified human” or “Posted by an agent of a verified human” badge that any platform can check. Cross-chain verifiers receive the registry root via Chain Signatures / light clients.5. How it builds on NEAR
NEAR primitive Role here I-AM-HUMAN / NEP-393 SBT registry, Fractal oracle Existing attester and holder base; migration path Named accounts + function-call access keys Natural “delegated key” model for agents with limited scope Chain Signatures / MPC network Publish roots and proofs to other chains; recovery backup NEAR Intents Intents can carry a PoHBA so solvers/apps can price or limit per human NEAR AI Cloud (TEE), IronClaw, Agent Market Runtime attestation; “human-backed agent” filter for hiring/marketplace Confidential Intents, low fees, fast finality Cheap registry updates; privacy-first brand 6. Prior art and positioning (honest view)
- World ID + AgentKit (World/Coinbase, beta 2026): closest existing product — lets an Orb-verified human delegate World ID to agents; sites see an anonymous human identifier and apply per-human limits (x402 integration). Limitations: one biometric issuer (the Orb), and agent registration lives in an “AgentBook” on World Chain. This proposal is the open, multi-attester, NEAR-native version, adding content signing, TEE runtime proofs and per-app nullifiers for agents.
- NEAR I-AM-HUMAN (NDC): soul-bound tokens linked to a public NEAR account — proves humanity but is not anonymous and has no agent layer. Activity has been low since 2024.
- Semaphore / RLN (Ethereum PSE): the ZK group-membership and nullifier toolkit this design reuses.
- zkPassport, Anon Aadhaar, Self: ZK proofs from passports/national IDs — ideal attesters.
- Human Tech (Holonym) / Human Passport; Humanity Protocol: ZK government-ID and palm-biometric personhood; Human Tech also builds scoped agent wallets. Potential attesters/partners.
- ERC-8004 Trustless Agents (Ethereum, live 2026): agent identity, reputation and validation registries — but agents are transferable NFTs with no ZK link to a unique human. Complementary: a PoHBA could be a validation signal.
- W3C DIDs and Verifiable Credentials 2.0: credential formats; the design should issue VC-compatible credentials (e.g.
did:near) so non-crypto platforms can consume them. - C2PA: content provenance standard used by Adobe, Microsoft, Google, camera makers — the carrier for “human-made” badges.
The gap filled: an open standard where an agent credential carries a zero-knowledge link to a unique-human credential, issued by multiple competing attesters, with app-scoped nullifiers, per-human quotas, revocation and recovery, plus content-signing for social media.
7. Open questions
- Attester governance: who approves attesters, and how are dishonest ones removed (House of Stake vote? stake/slashing)?
- Uniqueness across attesters: one person could enrol with two attesters; needs cross-attester dedup (e.g. MPC/TEE-based private set checks) or “assurance levels” instead of strict uniqueness.
- Coercion and credential renting: people selling their human credential to bot farms. Mitigations: quotas, RLN slashing, periodic liveness re-checks.
- Proof system choice (Groth16 vs Halo2) and NEAR gas for on-chain verification (BN254 pairing host functions exist on NEAR; benchmark needed).
- Regulatory fit (GDPR, Australia’s Privacy Act, EU eIDAS 2.0 wallets) — can national digital-ID wallets act as attesters?
- Accessibility for people without passports or phones.
8. Suggested rollout
Phase Timeline Deliverable 0. RFC Month 0–1 Forum discussion, NEP draft (Contract Standard), working group with NEAR AI and I-AM-HUMAN maintainers 1. Testnet MVP Months 1–4 Registry contract, Semaphore-style circuits, one attester (zkPassport or Fractal), JS verifier SDK 2. Agents Months 4–7 Agent delegation + PoHBA, IronClaw/Agent Market integration, TEE attestation option 3. Content Months 6–9 C2PA badge plug-in, browser extension, pilot with a social app / creator platform 4. Mainnet + cross-chain Months 9–12 Multi-attester governance, Chain Signatures roots on EVM, audit, grants for attesters
Technical appendix
A1. Notation.
H= Poseidon over BN254;s_h= human secret (random 254-bit);r= blinding;A= app identifier (e.g. hash of domain or NEAR contract id);E= epoch (e.g. day).A2. Registry contract (sketch, Rust / near-sdk).
pub struct Registry { tree: IncrementalMerkleTree<32>, // leaves = C_h roots: RingBuffer<Root, 64>, // accept recent roots attesters: UnorderedMap<AccountId, AttesterPolicy>, revoked: LookupSet<[u8;32]>, // revocation tags agent_revoked: LookupSet<[u8;32]>, } fn add_member(&mut self, c_h: [u8;32], attester_sig: Signature); // attester-only fn revoke(&mut self, tag: [u8;32]); // attester or holder fn verify_poh(&self, proof: Proof, root: Root, app: [u8;32], epoch: u64, nullifier: [u8;32]) -> bool;A3. Circuit: Proof of Human (public inputs: root, A, E, N, signal hash).
C_h = H(s_h, r); Merkle path provesC_h ∈ tree(root)N == H(s_h, A, E)- revocation tag
T = H(s_h, "rev")not in revoked set (non-membership proof against revocation root) signal hashbinds the proof to the post/request content (prevents replay)
A4. Circuit: Proof of Human-Backed Agent (adds public: agent_pubkey, scope).
- All of A3, plus: delegation
D = H(agent_pubkey, scope, expiry, H(s_h))signed by the human’s delegation key (EdDSA-Poseidon in-circuit) orC_a = Dis in an agent tree expiry > now_epoch;scope⊇ requested action- Agent separately signs the request with
agent_pubkey(Ed25519, verified outside the circuit)
A5. Sizes / costs (indicative, Semaphore v4 class). ~20–40k constraints; Groth16 proof 256 bytes, verify ~2 ms off-chain; client proving 1–3 s on a modern phone; on-chain verify via alt_bn128 host functions.
A6. Content signing payload (C2PA assertion).
{ "label": "near.humanproof.v1", "data": { "type": "PoH|PoHBA", "app": "<A>", "epoch": 2026296, "nullifier": "<N>", "root": "<R>", "proof": "<base64>", "agent_pubkey": "<optional>", "tee_quote": "<optional>" } }A7. Rate-limiting nullifier option. For quota
kper epoch, the prover includesmessage_id ∈ [0,k)and a Shamir sharey = s_h + a1·xwherea1 = H(s_h, A, E, message_id); two different messages with the samemessage_idreveals_h, so over-quota spam is self-revoking.References (search by name): NEAR I-AM-HUMAN repo (near-ndc) · NEP-393 in the near/NEPs repo · NEAR AI docs on verification · World AgentKit docs · ERC-8004 · Semaphore · zkPassport · Anon Aadhaar · Human Tech (Holonym) · Humanity Protocol · W3C VC 2.0 / DID 1.0 · C2PA