Content
# x424
> Human Dependency Protocol · public pre-alpha · unaudited
[x424.org](https://x424.org) · [Protocol specification](docs/PROTOCOL.md) ·
[OpenAPI](openapi/x424.openapi.json)
**x424 makes an HTTP action depend on one uniquely verified human.**
x402 makes an action depend on payment. x424 makes it depend on a unique
human—whether the caller is a browser, wallet, backend, or autonomous agent.
The server returns `424 Failed Dependency` plus a `HUMAN-REQUIRED` header. A
human completes an explicitly accepted provider method, a verifier issues a
short-lived result bound to the exact request and caller, and the client retries
with that token in `HUMAN-PROOF`.
World ID 4.0 Orb is the first provider adapter. The core is provider-neutral,
but providers are never presumed equivalent: a relying party must name every
accepted provider, method, descriptor version, uniqueness scope, assurance
label, verification mode, and freshness rule.
## The wire flow
```text
Agent or app Resource server x424 verifier
| POST /action | |
|---------------------------------->| |
| 424 + HUMAN-REQUIRED | |
|<----------------------------------| |
| human completes accepted provider ceremony |
| POST provider-native proof ----------------------------------->|
|<--------------------------- HUMAN-RESULT (signed, short-lived) |
| POST /action + HUMAN-PROOF | |
|---------------------------------->| verify signature, request, |
| | audience, binding, replay |
| 2xx, or next dependency (e.g. x402) |
|<----------------------------------| |
```
```http
HTTP/1.1 424 Failed Dependency
HUMAN-REQUIRED: <base64url-canonical-json>
Cache-Control: no-store, private
Content-Type: application/problem+json
```
After verification:
```http
POST /action HTTP/1.1
HUMAN-PROOF: <x424-result+jws>
Idempotency-Key: <application-key-for-mutations>
```
`HUMAN-RESULT` is the verifier-to-client copy of the same signed result token.
Provider-native proofs do not belong in headers or at the resource server.
## What is implemented
- Canonical, base64url HTTP requirement/result codecs.
- Exact request digest, audience, purpose, nonce, and wallet/agent/session
binding.
- Explicit provider alternatives without cross-provider equivalence.
- Provider-local uniqueness scopes: global, relying-party, action, or session.
- Atomic challenge consumption and optional result-token replay consumption.
- Audience-pairwise human identifiers derived with a relying-party HMAC secret.
- Ed25519 `x424-result+jws` signing and verification.
- Deterministic fail-closed result evaluation.
- World ID 4.0 Orb reference adapter using the current `/api/v4/verify/{rp_id}`
backend boundary and an application-supplied binding validator.
- Reference Express router and OpenAPI 3.1 contract.
- MCP server over stdio or local stateless Streamable HTTP.
- No-build dependency console UI.
- Fixed conformance fixtures, MCP evaluations, and negative tests.
- Problee first-adopter policy and migration design.
This repository does not contain a hosted verifier, production database,
production RP key, World proof fixture, on-chain registry, identity wallet,
generic credential protocol, or authorization engine.
## Quick start
Requirements: Node.js 22+ and pnpm 9+.
```bash
pnpm install
pnpm check
pnpm example
```
Run the MCP server locally:
```bash
pnpm mcp
```
Or bind a stateless MCP endpoint to localhost:
```bash
pnpm mcp:http
# http://127.0.0.1:4240/mcp
```
The browser console is in [`demo/`](demo/). Serve that directory from the same
trusted origin as a configured reference API; it intentionally contains no
provider or RP secrets.
## Minimal resource-server challenge
```ts
import { createHumanRequirement, humanRequiredResponse } from "x424";
const requirement = createHumanRequirement({
purpose: "publish-market",
method: "POST",
uri: "https://api.example.com/markets",
audience: "https://api.example.com",
body: requestBody,
binding: { kind: "agent_key", value: agentPublicKeyFingerprint },
accepts: [
{
providerId: "world",
methodId: "world-id-4-orb",
descriptorVersion: "1",
assuranceLevel: "orb",
acceptedScopeKinds: ["action"],
verificationModes: ["backend"],
maximumProofAgeSeconds: 300,
},
],
providerRequests: {
"world:world-id-4-orb": signedWorldRequestFromYourBackend,
},
});
const response = humanRequiredResponse(requirement);
// Send response.status, response.headers, and response.body.
```
Register the requirement in a shared atomic nonce store before returning it.
`InMemoryNonceStore` is for tests and local examples only.
## Accept the retried request
```ts
import {
WORLD_ID_ORB_METHOD,
defineMethodCatalog,
verifyHumanProofHeader,
} from "x424";
const result = await verifyHumanProofHeader({
humanProof: request.headers["human-proof"],
requirement,
verifier: trustedVerifierPublicKey,
catalog: defineMethodCatalog([WORLD_ID_ORB_METHOD]),
replayStore,
});
// result proves only the named dependency. Your application still authorizes.
```
For state-changing actions, atomically consume `resultId` and use the
application's normal idempotency mechanism. x424 prevents proof reuse from
becoming human-dependency reuse; it does not replace transaction idempotency.
## World ID adapter boundary
The adapter requires four relying-party decisions:
1. an `rp_...` ID and immutable action;
2. backend-generated signed World request material;
3. exact server-side validation that the IDKit proof signal is bound to the
expected wallet, agent key, request, or session; and
4. remote verification with World.
The adapter forwards the native IDKit result to World's verifier without
reshaping it. It stores the returned nullifier only long enough to derive an
audience-pairwise ID; the nullifier never enters an x424 result. World ID 4.0
uniqueness proofs are one-time. Session proofs and `session_id` continuity are a
different World semantic and are not silently substituted for the Orb method.
## Agents and humans
x424 does not label an agent as human. It binds a human result to an agent's
public-key fingerprint for one request or narrow purpose:
- an agent encounters a 424 challenge;
- its wallet/UI asks a human to satisfy the accepted method;
- the verifier issues a result for that exact request and agent key;
- the agent retries without receiving the human's provider nullifier; and
- the application applies its own agent scopes, spend controls, and policy.
A longer-lived “human owns this agent” relationship needs an explicit lifecycle
profile with consent, scopes, expiry, recovery, and revocation. It is not
inferred from one x424 result.
## x401 and x402 composition
x424 is not a replacement for x401 or x402:
- x401 asks for generic credentials/proof via HTTP 401.
- x424 asks for an exact unique-human dependency via HTTP 424.
- x402 asks for payment via HTTP 402.
A service that needs humanity and payment places x424 before x402. Once the
client presents a valid `HUMAN-PROOF`, the same request may receive a standard
x402 challenge. The final retry carries both the human result token and the
payment signature. Neither protocol reinterprets the other.
## Repository map
```text
src/ Core, World adapter, result tokens, API, and MCP
openapi/ OpenAPI 3.1 reference contract
demo/ Provider-safe dependency console
examples/ HTTP and Problee first-adopter examples
test/ Core, security, MCP, and contract tests
evals/ Ten read-only MCP evaluations
docs/PROTOCOL.md Normative x424/0.1 contract
docs/ARCHITECTURE.md Trust boundaries and deployment shapes
docs/SECURITY.md Threat model and production controls
docs/COMPOSITION.md x401/x402 and on/off-chain composition
docs/PROBLEE_ADOPTION.md First-adopter migration
docs/LANDSCAPE_AND_PRIOR_ART.md Research and pioneer-claim limits
```
## Status and naming
`424 Failed Dependency` originated in WebDAV's RFC 2518 in February 1999 and is
currently specified by RFC 4918. x424 reuses the dependency idea for an HTTP
extension; it is not an IETF standard and must not claim WebDAV conformance.
Clients detect x424 through `HUMAN-REQUIRED`, not the reason phrase alone.
The exact protocol-name search found no active x424 identity/humanity protocol
at the research date, but that is not trademark, patent, domain, or legal
clearance. See the research document for claim limits.
## Security
Pre-alpha and unaudited. Do not authorize production value with this release.
Read [`docs/SECURITY.md`](docs/SECURITY.md) and report vulnerabilities privately
as described in [`SECURITY.md`](SECURITY.md).
## License
Apache License 2.0. See [`LICENSE`](LICENSE).