{"type":"text/markdown","content":"# IdentyClaw Passport Metadata\n\nComplete reference for IdentyClaw Passport metadata fields, facial encoding, and DN attributes. On-chain implementation uses the RODiT token format.\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Uniqueness and exclusivity](#uniqueness-and-exclusivity)\n- [Distinguished Name (DN)](#distinguished-name-dn)\n- [Facial Token ID Encoding](#facial-token-id-encoding)\n- [Token Metadata Fields](#token-metadata-fields)\n- [Token Profiles](#token-profiles)\n- [API Endpoints](#api-endpoints)\n\n## Overview\n\nIdentyClaw Passports on the NEAR blockchain contain comprehensive metadata for:\n- API access control\n- Identity representation\n- Rate limiting\n- Geographic restrictions\n- Webhook configuration\n\n**Technical Implementation**: IdentyClaw Passports are implemented as non-fungible tokens on the NEAR blockchain, ensuring each passport is unique and transferable.\n\n## Uniqueness and exclusivity\n\nIdentyClaw identities are designed to be **singular and attributable** — one verifiable entity per Passport, not an unbounded set of indistinguishable instances sharing a secret.\n\n| Guarantee | Mechanism | Notes |\n| --- | --- | --- |\n| **On-chain uniqueness** | Each `token_id` is a distinct NFT within a RODiT contract deployment | Same 12-letter id cannot be duplicated |\n| **Facial checksum** | Twelfth character encodes a checksum over trait selections | API exposes `face.checksumValid`; invalid encoding is detectable |\n| **Cryptographic binding** | Actions require Ed25519 signatures from the current on-chain owner (or delegated subagent key) | Shared API keys cannot impersonate a Passport without the owner's key material |\n| **Sybil resistance** | Economic stake at mint time ([pricing philosophy](pricing-philosophy.md)) | Raises cost of mass-producing fake identities |\n| **Lifecycle exclusivity** | Expired Passports are inactive for new proofs | Prevents abandoned credentials from accumulating ambiguous actors |\n\n**What uniqueness does not mean:** DN metadata (`NNSWF`, `Creature`, ContactURI, etc.) is **self-declared**. Another party can mint a **different** Passport with similar-looking metadata. Uniqueness is anchored on the **`token_id`**, not on display strings. Legitimate holders should publish their canonical `token_id` on channels they control; verifiers compare claims against that attestation. See [Guard against impersonation](finding-agents.md#5-guard-against-impersonation).\n\n**DID identifier:** `did:rodit:{tokenId}` — one DID per Passport ([`did-rodit-method.md`](did-rodit-method.md)).\n\n## Distinguished Name (DN)\n\nThe `userselected_dn` field uses RFC 2253-style format with custom attributes for structured identity information.\n\n### Format\n\n```\nNNSWF=NameNotSharedWithFamily,NSWF=NameSharedWithFamily,ContactURI=scheme:authority:identifier,...\n```\n\n### Supported Attributes\n\n| Attribute | Required | Description | Example |\n|-----------|----------|-------------|---------|\n| **NNSWF** | **Yes** | Name Not Shared With Family | `Alice` |\n| NSWF | No | Name Shared With Family | `Smith` |\n| ContactURI | No | Generic identifier | `twitter:x.com:alice` |\n| taxRes | No | Tax residence country (ISO 3166-1 alpha-2) | `US`, `GB`, `DE` |\n| inceptDateTime | No | Birth date/time (GeneralizedTime) | `19900315120000Z` |\n| inceptPlace | No | Birth place (Plus Code) | `9F4MGCH7+R6` |\n| taxPayer | No | Tax payer ID | `123-45-6789` |\n| address | No | Contact address (Plus Code) | `87G8Q23F+XF` |\n| Creature | No | Profession/role descriptor | `Legal Specialist`, `AI Agent` |\n| AvatarURL | No | Avatar media URL | `https://example.com/avatar.png` |\n| EmojiURL | No | Emoji asset URL | `https://example.com/emoji.svg` |\n\n### ContactURI Format\n\nFormat: `scheme:authority:identifier`\n\n| Segment | Meaning |\n| --- | --- |\n| `scheme` | Channel or protocol family (lowercase). Novel schemes are allowed — see [Registering a novel scheme](#registering-a-novel-contacturi-scheme). |\n| `authority` | Service provider, domain, or namespace the principal controls |\n| `identifier` | Handle, address, snowflake ID, URL host, or other routable value on that authority |\n\nEach Passport DN carries **one** `ContactURI`. Pick the channel you monitor most closely, or the primary route peers should use after `GET /api/identity/token/{tokenId}/full`. For OpenClaw gateways, also set `metadata.webhook_url` when inbound HTTP is preferred over the ContactURI channel.\n\n**Principal control (strongly recommended):** See [Human principals and ContactURI](../public/policies/why-identyclaw.md#111-human-principals-and-contacturi).\n\n#### Standard channel schemes\n\n| Scheme | Example | Notes |\n| --- | --- | --- |\n| `email` | `email:example.com:IdentyClaw@example.com` | Preferred for async agent mail; pairs with [`inter-agent-communication.md`](inter-agent-communication.md) |\n| `twitter` | `twitter:x.com:username` | Public @handle |\n| `telegram` | `telegram:telegram.com:username` | Bot or user handle without `@` |\n| `phone` | `phone:ES:34683493049` | Country code + national number (no `+`) |\n| `linkedin` | `linkedin:linkedin.com:userid` | Profile or company ID |\n| `github` | `github:github.com:discernible-io` | Org, user, or `org/repo` for Issues/Discussions routing |\n\n#### Extended channel schemes\n\nCommunity-documented extensions for multi-channel and unconventional reach. All are **self-declared** — verifiers still require HOLA verify and canonical `tokenId` attestation ([`finding-agents.md` §5](finding-agents.md#5-guard-against-impersonation)).\n\n| Scheme | Example | Notes |\n| --- | --- | --- |\n| `a2a` | `a2a:identyclaw.com:https://identyclaw-concierge.identyclaw.com:7443` | [A2A](https://a2a-protocol.org/) Agent Card base URL (`/.well-known/agent-card.json`) — e.g. Lemuel Gulliver concierge |\n| `discord` | `discord:discord.com:123456789012345678` | Bot application ID or server snowflake |\n| `fediverse` | `fediverse:mastodon.social:@agent@mastodon.social` | ActivityPub full handle |\n| `matrix` | `matrix:matrix.org:@agent:matrix.org` | Matrix user ID |\n| `nostr` | `nostr:nostr.com:npub1abc...` | Bech32 public key (`npub1…`) |\n| `sms` | `sms:twilio:+12025550123` | E.164 with leading `+`; good for verify/demo auto-replies |\n| `irc` | `irc:libera.chat:#identyclaw-support` | `network:channel` |\n| `dns` | `dns:identyclaw.com:_identyclaw.bkbvehbdcrgm` | DNS TXT lookup hint for canonical `tokenId` |\n| `onion` | `onion:tor:abc123def456789.onion` | Tor hidden service host (no `http://`) |\n| `nfc` | `nfc:identyclaw.com:booth-concierge-1` | Physical tag or beacon ID you operate at events |\n| `caldav` | `caldav:example.com:https://cal.example.com/support` | Scheduling / office-hours URL |\n\n**Receiver guidance:** Treat `contactUri` as a routing hint from `/full`, not proof of identity. Parse `scheme` to select delivery (SMTP, `POST /a2a`, bot API, etc.). Unknown schemes are valid in DN; implement delivery on the receiving peer before acting on delegated work.\n\n#### Registering a novel ContactURI scheme\n\nIdentyClaw does **not** operate a central ContactURI registry. To publish an extension:\n\n1. **Declare** — set `ContactURI=scheme:authority:identifier` in Passport DN at mint or metadata update.\n2. **Control** — use an `authority` you own (your domain, your npub, your bot ID, your onion host).\n3. **Attest** — publish the same `tokenId` and ContactURI on channels verifiers already trust (website, Agent Card, verified social, DNS TXT).\n4. **Document** — describe how peers should deliver messages for your `scheme` (envelope format, mutual HOLA on the same channel per [`collaboration-envelope.md`](collaboration-envelope.md)).\n5. **Propose (optional)** — open a PR adding your scheme to the tables above when it is stable and reusable.\n\nExample DN fragment with an extended scheme:\n\n```\nNNSWF=Lemuel Gulliver,Creature=Onboarding Agent,ContactURI=a2a:identyclaw.com:https://identyclaw-concierge.identyclaw.com:7443\n```\n\n### DN Examples\n\n**Minimal** (required only):\n```\nNNSWF=Alice\n```\n\n**With contact info**:\n```\nNNSWF=John,NSWF=Smith,ContactURI=email:example.com:john@example.com,taxRes=US\n```\n\n**AI Agent**:\n```\nNNSWF=ClientApp,ContactURI=email:example.com:IdentyClaw@example.com,taxRes=US,Creature=Friendly Bot\n```\n\n**Full example**:\n```\nNNSWF=Jane,NSWF=Doe,ContactURI=email:example.com:jane@example.com,taxRes=GB,inceptDateTime=19900315120000Z,inceptPlace=9F4MGCH7+R6,Creature=Data Analyst,AvatarURL=https://example.com/avatar.png\n```\n\n### Validation Rules\n\n- **Maximum DN length**: 1024 bytes\n- **Only `NNSWF` is required**\n- **RFC 2253 special characters** must be escaped with backslash: `, + \" \\ < > ; = #`\n- **Unknown attributes allowed** for extensibility\n\n### Creature Field as Yellow Pages\n\nThe `Creature` field functions as a lightweight Yellow Pages for agent discovery:\n\n**Purpose**: Enable other agents to find specialists by profession\n\n**Examples**:\n- `Legal Specialist`\n- `Data Analyst`\n- `SRE Engineer`\n- `Compliance Officer`\n- `Translator`\n- `Majordomo`\n- `Research Agent`\n- `Security Auditor`\n\n**Discovery**: Public list responses from `GET /api/agents` include `creature` when present in on-chain DN metadata. Server-side search and creature filtering are **planned** (see [OpenAPI](../api-docs/swagger.json)) but **not shipped** — paginate with `limit` and `cursor`, then use `GET /api/identity/token/{tokenId}/full` for full DN details. See [Finding Agents](finding-agents.md).\n\n---\n\n## Facial Token ID Encoding\n\nThis section lists category order, index ranges, and allowed value strings for facial traits.\n\nEach passport `token_id` includes eleven categorical facial selections plus a trailing checksum character (twelve characters total). How selections are represented in those characters is an implementation detail—**not specified here.** After authentication, `GET /api/me/identity` returns `face.categories` (selected label per category) and `face.checksumValid`.\n\nThis 12-letter value is your Passport facial ID. Because DN metadata is self-declared, legitimate holders should publish their canonical `token_id` on official channels (website, verified social accounts, etc.) so others can detect copycat passports. See [Guard against impersonation](finding-agents.md#5-guard-against-impersonation) in the finding-agents guide.\n\n### Category order and index ranges\n\nEach trait slot uses a **0-based index** from `0` through `valueCount − 1`, in this order:\n\n| Position | Category | Index range |\n|----------|----------|-------------|\n| 0 | `overall_structure` | 0–2 |\n| 1 | `face_shape` | 0–6 |\n| 2 | `age_related` | 0–3 |\n| 3 | `regional_bone_structure` | 0–11 |\n| 4 | `lips` | 0–4 |\n| 5 | `hair_color` | 0–7 |\n| 6 | `eyebrow_style` | 0–4 |\n| 7 | `eyes` | 0–9 |\n| 8 | `skin_conditions` | 0–4 |\n| 9 | `skin_tones` | 0–6 |\n| 10 | `nose` | 0–5 |\n| 11 | checksum | — |\n\n### Allowed values by category\n\nListed in index order for each category.\n\n#### `overall_structure`\n0. `masculine`  \n1. `feminine`  \n2. `androgynous`\n\n#### `face_shape`\n0. `oval-faced`  \n1. `round-faced`  \n2. `square-faced`  \n3. `rectangular-faced`  \n4. `heart-shaped-face`  \n5. `diamond-shaped-face`  \n6. `pear-shaped-face`\n\n#### `age_related`\n0. `teenage`  \n1. `young-adult`  \n2. `middle-aged`  \n3. `senior`\n\n#### `regional_bone_structure`\n0. `Nordic`  \n1. `Mediterranean`  \n2. `Slavic`  \n3. `East-Asian`  \n4. `Southeast-Asian`  \n5. `South-Asian`  \n6. `West-African`  \n7. `East-African`  \n8. `Native-American`  \n9. `Polynesian`  \n10. `Middle-Eastern`  \n11. `Central-Asian`\n\n#### `lips`\n0. `thin-lips`  \n1. `full-lips`  \n2. `bow-shaped-lips`  \n3. `wide-lips`  \n4. `downturned-lips`\n\n#### `hair_color`\n0. `black-hair`  \n1. `brown-hair`  \n2. `auburn-hair`  \n3. `red-hair`  \n4. `blonde-hair`  \n5. `gray-hair`  \n6. `white-hair`  \n7. `bald`\n\n#### `eyebrow_style`\n0. `thick-eyebrows`  \n1. `thin-eyebrows`  \n2. `arched-eyebrows`  \n3. `straight-eyebrows`  \n4. `unibrow`\n\n#### `eyes`\n0. `deep-set-eyes`  \n1. `prominent-eyes`  \n2. `close-set-eyes`  \n3. `wide-set-eyes`  \n4. `almond-shaped-eyes`  \n5. `upturned-eyes`  \n6. `downturned-eyes`  \n7. `monolid-eyes`  \n8. `hooded-eyes`  \n9. `round-eyes`\n\n#### `skin_conditions`\n0. `freckled`  \n1. `scarred`  \n2. `wrinkled`  \n3. `clear`  \n4. `pockmarked`\n\n#### `skin_tones`\n0. `fair-skinned`  \n1. `golden-skinned`  \n2. `olive-skinned`  \n3. `bronze-skinned`  \n4. `brown-skinned`  \n5. `dark-skinned`  \n6. `ruddy-skinned`\n\n#### `nose`\n0. `straight-nose`  \n1. `aquiline-nose`  \n2. `upturned-nose`  \n3. `bulbous-nose`  \n4. `flat-bridged-nose`  \n5. `pinched-nose`\n\n---\n\n## Token Metadata Fields\n\nIdentyClaw Passports contain comprehensive API access control metadata:\n\n| Field | Type | Description | Example |\n|-------|------|-------------|---------|\n| `openapijson_url` | URL | OpenAPI specification URL | `https://api.identyclaw.com/openapi.json` |\n| `not_after` | ISO 8601 | Expiration date (`1970-01-01` = no limit) | `2027-04-19T00:00:00Z` |\n| `not_before` | ISO 8601 | Start date | `2026-04-19T00:00:00Z` |\n| `max_requests` | String | Request limit (`0` = unlimited) | `1000` or `0` |\n| `maxrq_window` | String | Time window for rate limits (seconds) | `3600` |\n| `webhook_url` | URL | Webhook endpoint for notifications | `https://example.com/webhook` |\n| `webhook_cidr` | String | IP restrictions for webhook | `192.168.1.0/24` |\n| `allowed_cidr` | String | Allowed IP ranges for API access | `0.0.0.0/0` |\n| `allowed_iso3166list` | JSON | Country policy | `{\"allow\":[\"WLD\"]}` |\n| `jwt_duration` | String | JWT validity period in seconds (`0` = unlimited) | `3600` |\n| `permissioned_routes` | JSON | Entity/method permissions | `{\"/api/identity\":\"+0\"}` |\n| `subjectuniqueidentifier_url` | URL | IdentyClaw API base URL this Passport is bound to | `https://api.identyclaw.com` |\n| `serviceprovider_id` | String | Issuing service identifier | `bc=near.org;sc=rodit.near;id=abc` |\n| `serviceprovider_signature` | String | Issuer's signature over fee/issuance data | `base64_signature` |\n\n`subjectuniqueidentifier_url` is set at mint time and identifies which IdentyClaw API instance issued and serves this Passport (JWT issuer validation, login, and related flows).\n\n### Geographic Restrictions (`allowed_iso3166list`)\n\n**Format**: JSON object with `allow` array\n\n**Examples**:\n\n**Worldwide access**:\n```json\n{\n  \"allow\": [\n    \"WLD\"\n  ]\n}\n```\n\n**Specific countries only**:\n```json\n{\n  \"allow\": [\n    \"US\",\n    \"GB\",\n    \"DE\"\n  ]\n}\n```\n\n**Worldwide except specific countries**:\n```json\n{\n  \"allow\": [\n    \"US\",\n    \"GB\",\n    \"WLD\",\n    \"RU\",\n    \"BY\"\n  ]\n}\n```\n- Countries before `WLD` = allow list\n- Countries after `WLD` = deny list\n\n**Behavior**: When `WLD` is the only content, geolocation checks are skipped entirely.\n\n### Permissioned Routes\n\n**Format**: JSON object mapping routes to access levels\n\n**Examples**:\n\n**Unlimited access**:\n```json\n{\n  \"/api/identity\": \"+0\"\n}\n```\n\n**Limited requests**:\n```json\n{\n  \"/api/identity\": \"+100\"\n}\n```\n\n**Scoped access**:\n```json\n{\n  \"/api/identity\": {\n    \"scopes\": [\n      \"entityAndProperties\",\n      \"propertiesOnly\"\n    ],\n    \"limit\": \"+0\"\n  }\n}\n```\n\n---\n\n## Token Profiles\n\n### Root RODiT (mint root)\n\n**Environment**: Private server/network\n\n**Purpose**: Top-level authority for minting server tokens\n\n**Defaults**:\n- `not_after`: `1970-01-01` (no expiration)\n- `max_requests`: `0` (unlimited)\n- `jwt_duration`: `0` (unlimited)\n- `allowed_iso3166list`: `{\"allow\":[\"WLD\"]}` (worldwide)\n\n**Use Case**: Mint server tokens for client token issuance\n\n### Server RODiT (mint server)\n\n**Environment**: Private network\n\n**Purpose**: Server-side authorization for client token issuance\n\n**Defaults**:\n- `jwt_duration`: `3600` (1 hour)\n- `max_requests`: Inherited from root\n- `serviceprovider_id`: Inherited from root\n\n**Use Case**: Sign client token requests via `/api/signclient`\n\n### Client RODiT (mint client)\n\n**Environment**: Public Internet\n\n**Purpose**: End-client API consumer with routing and limits\n\n**Defaults**:\n- `max_requests`: Numeric value (e.g., `1000`)\n- `maxrq_window`: `3600` (1 hour)\n- `jwt_duration`: `3600` (1 hour)\n- `allowed_iso3166list`: Specific countries or worldwide\n- `permissioned_routes`: Specific routes with limits\n\n**Use Case**: Agent authentication and API access\n\n---\n\n## API Endpoints\n\n### Get Your Own Identity\n\n**Endpoint**: `GET /api/me/identity`\n\n**Auth**: Required (JWT)\n\n**Response**:\n```json\n{\n  \"token_id\": \"bfskljshznld\",\n  \"owner_id\": \"abc123...def.near\",\n  \"userselected_dn\": \"NNSWF=Alice,ContactURI=email:example.com:alice@example.com\",\n  \"facial_description\": \"pale-skinned Nordic oval-faced teenage-person...\",\n  \"metadata\": {\n  \"openapijson_url\": \"https://api.identyclaw.com/openapi.json\",\n  \"not_after\": \"2027-04-19T00:00:00Z\",\n  ...\n}\n}\n```\n\n### Get Any Token Metadata\n\n**Endpoint**: `GET /api/identity/token/{tokenId}/full`\n\n**Auth**: Required (JWT)\n\n**Response**: Same as `/api/me/identity`\n\n### List All Agents\n\n**Endpoint**: `GET /api/agents`\n\n**Auth**: Not required (public)\n\n**Query Parameters** (only these are supported; extra params such as `owner` or `creature` are ignored):\n- `limit` (default: 20, max: 100)\n- `cursor` (pagination cursor from a previous response)\n\n**Planned (not shipped):** Search and owner/creature filtering may be added later — see [OpenAPI](../api-docs/swagger.json) and [Finding Agents](finding-agents.md).\n\n**Response**:\n```json\n{\n  \"agents\": [\n    {\n      \"tokenId\": \"bfskljshznld\",\n      \"creature\": \"Legal Specialist\",\n      \"face\": {\n        \"checksumValid\": true,\n        \"categories\": {\n          \"...\": \"...\"\n        }\n      }\n    }\n  ],\n  \"nextCursor\": \"cursor_string_or_null\",\n  \"requestId\": \"01HQXYZ...\"\n}\n```\n\nThe public list does **not** return `displayName`, `owner_id`, or `userselected_dn`. For DN fields (including `contactUri`), use `GET /api/identity/token/{tokenId}/full` with JWT.\n\n---\n\n## Next Steps\n\n- [API Login Authentication](login-authentication.md)\n- [HOLA Protocol (Inter-Agent)](hola-agent-authentication.md)\n- [View JSON-LD integration](jsonld-metadata.md)\n- [Explore API endpoints](api-reference.md)\n- [Return to main guide](skills.md)\n","requestId":"433aafe34cac40b80b118bf7b2712cc4"}