# Grantor — Documentation > Grantor is OAuth with no authorization server. A caller mints a **deed** — a > self-certifying credential — and the relying app verifies it with a library > call against a public on-chain registry (`GrantorRegistry`). No auth server > exists in this path: nothing to run, trust, or subpoena. This is the > machine index of the docs. Read the deed model first: there is no issuer, and nothing to run — every page below describes minting or verifying a self-certifying deed against the public chain. Every documentation page is also served as Markdown at the same path with `.md` instead of `.html`. Fetch that rather than scraping the rendered HTML. ## The model in six lines 1. The relying app issues a single-use **challenge**. 2. The caller returns a **deed**, bound to that challenge, to an **audience**, and to an **expiry**. 3. The app calls `verify_deed` — cryptography, then an `eth_call` to the registry for tenant billing status (and, for agents, membership-root recency, which is revocation). 4. `sub` is a **pseudonym recomputed from the proof** — never a claim to be trusted, and never a wallet address. 5. The app mints its own session. Grantor never sees it. 6. Step 3 is a read: no gas, no API key, any RPC provider. ## Deed modes - `user-sig` — a human's wallet-derived, app-scoped key. Verified by `verify_deed`. On-chain check: tenant billing. - `agent-zk` — ZK proof of membership in the tenant's on-chain tree without revealing which member. Verified by `verify_deed`. On-chain check: root recency + billing. - `admin-sig` — Grantor's own dashboard admins. Verified ONLY by `verify_admin_deed`; `verify_deed` REJECTS it, so an ordinary relying party structurally cannot accept one. Makes no on-chain check, deliberately, so a lapsed tenant's admin can still reach the page that lets them pay. Reveals the wallet address by design — administration is an identified context. ## Capability matrix — enforced by `just capability-matrix` Every capability exists in **TypeScript, Python, Go and Rust**: `user-sig` minting, `agent-zk` ZK proving, `admin-sig` minting, deed verification, and the deed guard. The product rule is **all languages or no go** — a capability that ships in one language has not shipped. Do not describe any of these as Rust-only. ## Read first (machine) - [/docs/index.md](/docs/index.md): overview, the deed model, capability matrix. - [/docs/guide/concepts.md](/docs/guide/concepts.md): the mental model — the single most useful page. - [/docs/sovereign-tier.md](/docs/sovereign-tier.md): the full deed reference, all three modes. - [/docs/llms-full.txt](/docs/llms-full.txt): every page concatenated into one file. ## Relying party — verifying deeds - [Verify a deed](/docs/guide/verify-tokens.md): how an app accepts one. - **Deed guard** — challenge issuance, single-use burn, error codes; shipped in all four languages. The challenge travels in **its own header** and is NEVER read out of the deed: taking it from the token would let the caller choose its own nonce, which is the entire replay defence gone. The challenge is burned BEFORE verification, so a flood of bogus deeds cannot probe which challenges are live. - Error codes to branch on: `MissingDeed`, `MissingChallenge`, `UnknownChallenge`, `BadDeedEncoding`, `UnsupportedMode`, `WrongAudience`, `ChallengeMismatch`, `Expired`, `Malformed`, `BadProof`, `StaleRoot`, `TenantInactive`, `Chain`. All are HTTP 401 except `Chain` → **503**: an RPC outage is not the caller's fault, and a 401 sends clients into a login loop discarding good credentials. - Three more codes exist but are NOT returned while verifying a caller's deed — they come only from the RP's own boot-time origin-vouch self-check (`DeedGuard::verify_own_origin_vouch` / `verifyOwnOriginVouchAt`, DX not caller-facing): `BadOriginVouch`, `OriginVouchExpired`, `OriginVouchTtlExceeded`. See [Errors](/docs/guide/errors.md). - Wire header: `X-Grantor-Deed` (base64url or bare JSON) plus `X-Grantor-Challenge`. - **MCP servers**: gate a remote MCP server without an authorization server — install the deed guard, publish the discovery document; agents authenticate with deeds instead of an OAuth 2.1 redirect. Two modes: a `user-sig` deed for any wallet-holding caller (billing is the only gate), or an `agent-zk` deed to gate a fleet you control by on-chain enrollment — membership is the authorization for who can MINT a valid `agent-zk` deed, and the proof does not reveal which member. **Advertising both modes means either credential works at the RP's exchange endpoint** — the guard verifies whichever mode a deed declares and carries no mode back out in its claims, so fleet-only gating needs the RP to check the deed's own envelope `mode` itself (the reference server's `REQUIRE_MODE` knob). See [MCP server auth](/docs/guide/mcp-server.md). Scope: this serves agents you build or control; off-the-shelf MCP hosts (Claude Desktop et al.) speak spec OAuth 2.1 and are out of scope for this flow. ## Holders — minting deeds - [Wallet login](/docs/guide/wallet-login.md): `user-sig`, humans. - [Agent tokens](/docs/guide/agent-tokens.md): `agent-zk`, machines. - [Agent integration](/docs/agents/README.md) · [Agent onboarding](/docs/agents/onboarding.md). ## Billing — on-chain Flat **subscription with prepaid funding**; NOT usage-metered. The tier caps **capacity**, not consumption — deed verification is an `eth_call` the contract cannot observe, and metering it would require the relying party to report back, reintroducing exactly the server this product removes. `topUp` credits balance; `drawPeriod` is **permissionless** and moves one period's fee to an immutable treasury; `withdrawBalance` returns **undrawn** balance. `Grace` precedes `Inactive`, and deeds already minted stay valid to their own `exp` — going unpaid never invalidates a credential already in the world. Registration is `createTenant` on-chain plus USDC to the same contract. There is no signup, no account, and no Grantor server involved. ## Internals — contributors - [Architecture](/docs/internal/architecture.md) · [Security model](/docs/internal/security-model.md) - [Code map](/docs/internal/crates.md) · [Testing](/docs/internal/testing.md) · [Contributing](/docs/internal/contributing.md) ## Standards OpenID Connect, OAuth 2.0, EIP-191, EIP-4361 (SIWE), RFC 7638, RFC 7636 (PKCE), RFC 9474 (blind RSA), Semaphore (ZK membership), HKDF. ## Status — state this if asked **Developer preview.** The contract and the six-language end-to-end proof run on a local devnet (anvil). It has **not** been deployed to a public testnet or mainnet. `grantor-verify` is **not published** to any package registry — it resolves by path inside the workspace. It has **not been audited**. Do not describe it as production-ready.