diff --git a/docs.json b/docs.json index bbe40f2..9b5b359 100644 --- a/docs.json +++ b/docs.json @@ -160,7 +160,7 @@ }, { "group": "Credentials", - "pages": ["world-id/credentials/legacy-presets"] + "pages": ["world-id/credentials/index", "world-id/credentials/9303"] }, { "group": "Migration", @@ -201,10 +201,6 @@ "GET /is-valid-root", "GET /status/{id}" ] - }, - { - "group": "Issuers", - "pages": ["world-id/reference/poh-issuer"] } ] }, @@ -720,7 +716,7 @@ }, { "source": "/world-id/credentials/presets", - "destination": "/world-id/credentials/legacy-presets" + "destination": "/world-id/credentials#legacy-presets" }, { "source": "/world-id/face-check/overview", @@ -728,11 +724,11 @@ }, { "source": "/world-id/face-check/web-integration", - "destination": "/world-id/credentials/legacy-presets" + "destination": "/world-id/credentials#legacy-presets" }, { "source": "/world-id/face-check/testing", - "destination": "/world-id/credentials/legacy-presets" + "destination": "/world-id/credentials#legacy-presets" } ], "api": { diff --git a/images/docs/id/issuers/9303/thumbnail.png b/images/docs/id/issuers/9303/thumbnail.png new file mode 100644 index 0000000..2e34942 Binary files /dev/null and b/images/docs/id/issuers/9303/thumbnail.png differ diff --git a/snippets/credential-hero.jsx b/snippets/credential-hero.jsx new file mode 100644 index 0000000..7918e37 --- /dev/null +++ b/snippets/credential-hero.jsx @@ -0,0 +1,223 @@ +import React from "react"; + +/** + * Hero card for credential issuer documentation pages. + * Mintlify-safe: no hooks, no client-side state. + * + * IMPORTANT: Tailwind classes MUST be string literals in className + * props — Mintlify only prefixes classes it can statically analyze. + * Never use variables for className values. + * + * Props: + * - title: string — credential display name + * - description: string — one-sentence summary + * - image: string — path to thumbnail image + * - bgColor: string — hex color for the banner background + * - issuerName: string — who issues this credential + * - issuerHref: string — link to issuer (optional) + * - issuerVerified: boolean — show verified badge (optional) + * - status: "active" | "beta" | "deprecated" + * - id: number — credential schema ID + * - sybilResistance: boolean — whether uniqueness is enforced + * - sybilResistanceDescription: string — tooltip on the Yes tag + * - validityPeriod: string — e.g. "10 years or document expiry" + * - sourceCodeHref: string — GitHub URL, or "coming-soon" + */ +export const CredentialHero = ({ + title, + description, + image, + bgColor = "#1a1a2e", + issuerName, + issuerHref, + issuerVerified, + status, + id, + sybilResistance, + sybilResistanceDescription, + validityPeriod, + sourceCodeHref, +}) => { + return ( +
+ {/* Banner */} +
+
+
+

+ {title} +

+ {description && ( +

+ {description} +

+ )} +
+ {image && ( + {title} + )} +
+
+ + {/* Metadata table */} +
+ {issuerName && ( +
+ + + + + Issued by + + + {issuerVerified && ( + + + + + + )} + {issuerHref ? ( + + {issuerName} + + ) : ( + + {issuerName} + + )} + +
+ )} + {status && ( +
+ + + + + Status + + {status === "active" && ( + + Active + + )} + {status === "beta" && ( + + Beta + + )} + {status === "deprecated" && ( + + Deprecated + + )} +
+ )} + {id != null && ( +
+ + + + + ID + + + {id} + +
+ )} + {sybilResistance != null && ( +
+ + + + + Sybil resistance + + {sybilResistance ? ( + + + Yes + + {sybilResistanceDescription && ( + + + + + + )} + + ) : ( + + No + + )} +
+ )} + {validityPeriod && ( +
+ + + + + + Validity period + + + + + + + + + {validityPeriod} + +
+ )} + {sourceCodeHref && ( +
+ + + + + SDK Reference + + {sourceCodeHref === "coming-soon" ? ( + + + Coming soon + + ) : ( + + {sourceCodeHref.split("/").pop()} + + )} +
+ )} +
+ + {/* Bottom spacer */} +
+
+ ); +}; + +export default CredentialHero; diff --git a/world-id/credentials/9303.mdx b/world-id/credentials/9303.mdx new file mode 100644 index 0000000..8c9d4a2 --- /dev/null +++ b/world-id/credentials/9303.mdx @@ -0,0 +1,188 @@ +--- +title: "NFC Credential" +icon: "passport" +iconType: "duotone" +description: "Unique government-issued document (eID) or passports." +"og:image": "https://docs.world.org/images/docs/docs-meta.png" +"twitter:image": "https://docs.world.org/images/docs/docs-meta.png" +--- + +{/* cspell:ignore uniqueness NFC PCP eIDs */} + +import { CredentialHero } from "/snippets/credential-hero.jsx"; + + + +## Introduction + +The NFC Credential represents a uniquely issued government document. It supports passports and eIDs. The availability generally varies by country and continues to be extended over time. An NFC Credential is **guaranteed to be issued to a single World ID per unique document**. In addition to ICAO-9303 compliant documents (such as passports or eIDs), the Japanese [My Number Card](https://en.wikipedia.org/wiki/My_Number_Card) is also supported. This MNC card has different handling internally for enrollment, but the same credential is issued. + +## Use Cases + +Use the NFC Credential when you need proof of a unique document. This is useful for example for situations where you want to have some sybil resistance but you don't need a strong guarantee of a unique human. + +## Credential Structure + +This credential implements the following attributes beyond the defaults in the [Credential](https://docs.rs/world-id-primitives/latest/world_id_primitives/credential/struct.Credential.html). + +| Attribute | Description | +| ---------------------------- | ------------------------------------------------------------------------------------- | +| `genesis_issued_at` | The timestamp of when the unique document was first verified. | +| `expires_at` | The expiration of the document with a maximum of 10 years. | +| `associated_data_commitment` | A commitment to the user's Associated Data (see [Associated Data](#associated-data)). | + +In addition, the credential implements the following claims: + +### Claim 0 - Authentication Claim + +Identifies the type of authentication performed when enrolling a document. This helps determine the state of the document at enrollment time. For example, documents that only undergo Passive Authentication have no guarantee that the data isn't cloned from an original document. Please note that not all authentications are supported for all documents, and it usually varies per country. The strongest authentication available is always selected. + +| Value | Claim | Description | +| ----- | --------------------- | -------------------------------------------------------------------------------------------------- | +| `1` | None | Passive authentication only (document signature verification). | +| `2` | Chip Authentication | Document passed Chip Authentication (CA) per ICAO 9303. Proves the chip is genuine and not cloned. | +| `3` | Active Authentication | Document passed Active Authentication (AA) per ICAO 9303. Proves the chip holds a private key. | +| `4` | MNC Authentication | Document was verified via the MNC (My Number Card) SD-JWT flow. | + +### Claim 1 - SOD Signature + +Contains a hash of the document's signature from the issuing authority. For passports and other ICAO-9303 compliant documents, the signature is retrieved from `SignedData.SignerInfos[0].Signature` in the `EF.SOD` (Security Object Document) (see [Section 4.6.2.1 from ICAO-9303 Part 10](https://www.icao.int/sites/default/files/publications/DocSeries/9303_p10_cons_en.pdf)). The raw signature bytes are then hashed with blake3 and converted to a field element with modulo reduction. Please note that this claim is not set for credentials from My Number Cards. + +## Credential Renewal + +Renewal is not supported for this credential. A document can only be enrolled once. From a user standpoint, they will generally obtain a new document from their issuing authority (e.g. a new passport) and register it as a new credential. + +## API Reference + +The API Reference here is only relevant for Authenticators and internal development of the credential. + +### Enrollment Coming soon + +Details coming soon. + +### Re-issuance Coming soon + +Details coming soon. + +### Migration + + + This endpoint is intended for World ID v3 holders to obtain v4 NFC + credentials. It is not a general re-issuance endpoint for v4 holders. + + + + /v2/refresh + + +**Content-Type:** `application/json` + +#### Headers + +| Header | Type | Required | Description | +| --------------------------- | -------- | -------- | --------------------------------------------------------------------- | +| `x-zkp-proof` | `string` | yes | Base64-encoded JSON containing the ZKP proof and identity commitment. | +| `attestation-gateway-token` | `string` | yes | Attestation gateway token for device integrity verification. | + +#### Body fields (common) + +| Field | Type | Required | Description | +| -------------------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------- | +| `identityCommitment` | `string` | yes | The holder's identity commitment (decimal or hex with `0x` prefix). Must match the ZKP header. | +| `sub` | `string` | yes | World ID 4.0 blinded subject identifier (hex with `0x` prefix, 256-bit). Must match previous refreshes for this identity. | +| `credential` | `object` | yes | Flow-specific credential data (see below). The client decrypts PCP data locally before submission. | + +#### Credential fields + + + + The `credential` object contains data extracted and decrypted from the user's Personal Custody Package (PCP) by the client. + + | Field | Type | Description | + | ---------------------------------- | -------- | --------------------------------------------------------------------------------------- | + | `credential.sod` | `string` | Base64-encoded SOD (Security Object Document) in DER format from the identity document. | + | `credential.verification_metadata` | `string` | Base64-encoded verification metadata from the original document check. | + + ```json + { + "identityCommitment": "0x000000000000000000000000000000000000000000000000000000000000000c", + "sub": "0x000000000000000000000000000000000000000000000000000000000000002a", + "credential": { + "sod": "", + "verification_metadata": "" + } + } + ``` + + + + | Field | Type | Description | + | ------------------- | -------- | ----------------------------------------------------------------- | + | `credential.sd_jwt` | `string` | SD-JWT (Selective Disclosure JWT) from the MNC verification flow. | + + ```json + { + "identityCommitment": "0x000000000000000000000000000000000000000000000000000000000000000c", + "sub": "0x000000000000000000000000000000000000000000000000000000000000002a", + "credential": { + "sd_jwt": "" + } + } + ``` + + + + +#### Success response + +```json +{ + "result": { + "credential": "" + } +} +``` + +#### Error responses + +| Status | Error | Description | +| ------ | ------------------ | -------------------------------------------------------------------------- | +| 400 | `invalid_data` | Request payload is malformed or missing required fields. | +| 400 | `sub_mismatch` | `sub` does not match the one used in previous refreshes for this identity. | +| 400 | `document_expired` | The identity document has expired and cannot be used for refresh. | +| 401 | `unauthorized` | Authentication failed. | +| 404 | `not_found` | No matching enrollment record found for this credential. | + +# Internal Documentation + + + This is advanced documentation about the internal workings of the NFC + Credential and is not relevant for RP integration. + + +## Associated Data + +The associated data of this credential contains different data groups found in the original document. More information coming soon. + +{/* TODO: Add details on the PCP */} + +### Associated Data Commitment + +To ensure the associated data has guaranteed integrity and can be re-used in the future for credential re-issuance, the commitment is computed as follows: + +1. For ICAO-9303 documents, the message digest of the `EF.SOD` signature is used. The message digest is obtained from `SignedData.SignerInfos[0].SignedAttrs` where the signed attribute for the digest is identified by the Object Identifier `1.2.840.113549.1.9.4`. This digest is then hashed with the `blake3` hashing function from the raw bytes. Finally, the `blake3` hash is converted to a field element with modulo reduction. +2. Information on MNC documents coming soon. diff --git a/world-id/credentials/legacy-presets.mdx b/world-id/credentials/index.mdx similarity index 90% rename from world-id/credentials/legacy-presets.mdx rename to world-id/credentials/index.mdx index c5a0fbf..6840d20 100644 --- a/world-id/credentials/legacy-presets.mdx +++ b/world-id/credentials/index.mdx @@ -1,9 +1,15 @@ --- -title: "Legacy Presets" +title: "About Credentials" +sidebarTitle: "About" "og:image": "https://raw.githubusercontent.com/worldcoin/developer-docs/main/images/docs/docs-meta.png" "twitter:image": "https://raw.githubusercontent.com/worldcoin/developer-docs/main/images/docs/docs-meta.png" --- +A [Credential](https://docs.rs/world-id-primitives/latest/world_id_primitives/credential/struct.Credential.html) is a statement an issuer makes about a World ID holder. Fundamentally, when you as an RP request a proof, the choice of Credential matters significantly to fulfill your use case. For example, if you want to protect an action that should only be done once per human, you probably want to use the Proof of Human credential. + + +# Legacy Presets + Legacy presets only return World ID 3.0 proofs. These function the same as `VerificationLevel` from previous IDKit versions. ## `orbLegacy` diff --git a/world-id/reference/contracts.mdx b/world-id/reference/contracts.mdx index ed2655c..97af716 100644 --- a/world-id/reference/contracts.mdx +++ b/world-id/reference/contracts.mdx @@ -1,8 +1,9 @@ --- -title: "Smart Contracts (Legacy)" +title: "Contracts 3.0" description: "World ID 3.0 smart contracts overview: supported chains, architecture, World ID Router verifyProof, and sybil resistance." "og:image": "https://raw.githubusercontent.com/worldcoin/developer-docs/main/images/docs/docs-meta.png" "twitter:image": "https://raw.githubusercontent.com/worldcoin/developer-docs/main/images/docs/docs-meta.png" +deprecated: true --- diff --git a/world-id/selfie-check/overview.mdx b/world-id/selfie-check/overview.mdx index ebbfb7d..ff7f98f 100644 --- a/world-id/selfie-check/overview.mdx +++ b/world-id/selfie-check/overview.mdx @@ -41,4 +41,4 @@ You will need to use IDKit to integrate Selfie Check (Beta) into your applicatio ## Next steps -See [Web Integration Guide](/world-id/credentials/legacy-presets). +See [Web Integration Guide](/world-id/credentials#legacy-presets).