diff --git a/README.md b/README.md index 0e27624..d3ab4e9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Source for the official World developer documentation, published at **[docs.worl ## What's documented here -- **World ID** (`world-id/`) — IDKit SDKs (JS, React, Swift, Kotlin, Go), Sign in with World ID, credentials, Selfie Check, on-chain verification, API reference. +- **World ID** (`world-id/`) — IDKit SDKs (JS, React, Swift, Kotlin, Go), Credentials, Selfie Check, on-chain verification, API reference. - **Mini Apps** (`mini-apps/`) — building applications that run inside World App, including commands, sharing, growth, and the MiniKit reference. - **World Chain** (`world-chain/`) — quick start, provider integrations, tokens, and developer reference for the chain. - **AgentKit and agents** (`agents/`) — distinguishing human-backed agents from bots, plus Hats and human-in-the-loop flows. diff --git a/docs.json b/docs.json index eebbb89..be72217 100644 --- a/docs.json +++ b/docs.json @@ -447,10 +447,6 @@ "source": "/id", "destination": "/world-id/overview" }, - { - "source": "/id/sign-in", - "destination": "/world-id/overview" - }, { "source": "/protocol", "destination": "https://whitepaper.world.org/#protocol" @@ -619,10 +615,6 @@ "source": "/reference/idkit", "destination": "/world-id/reference/idkit" }, - { - "source": "/reference/sign-in", - "destination": "/world-id/reference/sign-in" - }, { "source": "/poh-issuer", "destination": "/world-id/reference/poh-issuer" @@ -635,10 +627,6 @@ "source": "/reference/world-id-2-migration-guide", "destination": "/world-id/reference/world-id-2-migration-guide" }, - { - "source": "/sign-in", - "destination": "/world-id/overview" - }, { "source": "/try", "destination": "/world-id/try" @@ -687,18 +675,6 @@ "source": "/world-id/id/incognito-actions", "destination": "/world-id/idkit/integrate" }, - { - "source": "/world-id/id/sign-in", - "destination": "/world-id/overview" - }, - { - "source": "/world-id/sign-in", - "destination": "/world-id/overview" - }, - { - "source": "/world-id/sign-in/pitfalls", - "destination": "/world-id/idkit/integrate" - }, { "source": "/world-id/quick-start/testing", "destination": "/world-id/idkit/integrate" diff --git a/images/docs/id/sign-in.svg b/images/docs/id/sign-in.svg deleted file mode 100644 index 2e2bc1f..0000000 --- a/images/docs/id/sign-in.svg +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mini-apps/guidelines/app-guidelines.mdx b/mini-apps/guidelines/app-guidelines.mdx index e1a8798..33bae64 100644 --- a/mini-apps/guidelines/app-guidelines.mdx +++ b/mini-apps/guidelines/app-guidelines.mdx @@ -155,9 +155,7 @@ These languages are particularly important given our users: ## Usernames -You should never display the user's wallet address, always use their username. -If you use Sign in with World ID you should not be doing any transactions with the user's wallet address, instead you should be using the username. -Sign in with World ID and Verify offer the same World ID guarantees, but Verify is more reliable. +You should avoid displaying the user's wallet address, use their username instead. ## Using the Address Book diff --git a/openapi/developer-portal.json b/openapi/developer-portal.json index b1fbca8..7113d22 100644 --- a/openapi/developer-portal.json +++ b/openapi/developer-portal.json @@ -510,7 +510,7 @@ "properties": { "action": { "type": "string", - "description": "Action identifier passed to IDKit. Optional for Sign in with World ID flows." + "description": "Action identifier passed to IDKit." }, "nullifier_hash": { "type": "string", diff --git a/world-id/reference/sign-in.mdx b/world-id/reference/sign-in.mdx deleted file mode 100644 index b9aeeda..0000000 --- a/world-id/reference/sign-in.mdx +++ /dev/null @@ -1,278 +0,0 @@ ---- -title: "Sign In Reference" -description: "OIDC-based Sign in with World ID: discovery, authorize, token exchange, OAuth2 endpoints, introspect, and userinfo." -"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" ---- - - - **Deprecation Notice**: Sign in with World ID v1 has been deprecated and will - be shut down on **January 31, 2026**. Read more in the - [announcement](/world-id/sign-in/deprecation). - - - - Sign in with World ID uses a different base API endpoint than the Developer - Portal. - - -**Base domain** - -``` -https://id.worldcoin.org -``` - - - This page primarily describes options that are OIDC-compliant. We additionally - support using access tokens as described in the OAuth2 standards. No actions - can be taken on behalf of a user with OAuth2 access tokens, but you may - retrieve the same information about a user as would be contained in an - `id_token`. [See below for details.](#oauth2) - - -## OpenID Connect discovery - -**GET** `/.well-known/openid-configuration` - -Fetches the OpenID Connect discovery document. - -### Common Errors - -- `method_not_allowed`: HTTP method is not allowed. Only GET and OPTIONS may be used - -```bash title="cURL" -curl https://id.worldcoin.org/.well-known/openid-configuration -``` - -```json title="Response" -{ - "issuer": "https://id.worldcoin.org", - "authorization_endpoint": "https://id.worldcoin.org/authorize", - "token_endpoint": "https://id.worldcoin.org/token", - "userinfo_endpoint": "https://id.worldcoin.org/userinfo", - "jwks_uri": "https://id.worldcoin.org/jwks", - "scopes_supported": ["openid", "email", "profile"], - "response_types_supported": [ - "code", - "id_token", - "id_token token", - "code id_token" - ], - "grant_types_supported": ["authorization_code", "implicit"], - "subject_types_supported": ["pairwise"], - "id_token_signing_alg_values_supported": ["RSA"] -} -``` - -## Authorize - -**GET** `/authorize` - -Redirect your users to this page to begin the sign-in flow. - -### Required attributes - -All attributes are formatted as URL query parameters. - -| Parameter | Type | Description | -| --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `response_type` | `string` | Must be `code` for authorization code flow, `id_token` for implicit flow, or a space-separated combination of `code`, `id_token`, and `token` for hybrid flow. We generally recommend using the authorization code or implicit flows. | -| `scope` | `string` | Space-separated list of the requested OIDC scopes. Must include `openid`, and may optionally include `email` and `profile`. | -| `client_id` | `string` | The Client ID of your app. Get this from the Developer Portal. | -| `redirect_uri` | `string` | URL the user will be redirected to after authentication. Must match one of your app's configured `redirect_uris`. | - -### Optional attributes - -| Parameter | Type | Description | -| --------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `state` | `string` | An opaque value used to maintain state between the request and the callback. | -| `nonce` | `string` | **Required when using the implicit flow.** Used to prevent replay attacks. Should be randomly generated for each sign-in, and checked to ensure it's unchanged after the callback. | -| `response_mode` | `string` | Determines how the authorization code, ID token, and/or access token are returned. Must be one of `query`, `fragment`, or `form_post`. `query` is only supported for the authorization code flow. Defaults to `query` for authorization code flow, and `fragment` for all others. | - -### Common Errors - -- `required`: A necessary attribute was not set. Required attributes are: `response_type scope client_id redirect_uri` -- `invalid_redirect_uri`: The provided redirect URI is invalid. Ensure you've set the correct `redirect_uri` in the Developer Portal. - -```http title="Request" -https://id.worldcoin.org/authorize?redirect_uri=https%3A%2F%2Fdocs.worldcoin.org%2Fworld-id%2Ftry-callback&response_type=code&scope=openid+profile+email&client_id=app_ce4cb73cb75fc3b73b71ffb4de178410 -``` - -```http title="Response - Authorization Code" -https://example.app/api/auth/callback/worldcoin?code=e777d780f437330bbd79535b -``` - -```http title="Response - ID Token" -https://example.app/api/auth/callback/worldcoin#id_token=eyJhbGciOiJSUzI1NiIsInR5cCI6I... -``` - -## Exchange Code - -**POST** `/token` - -Exchanges an authorization code for an `id_token` for the given user. - -### Required attributes - -| Parameter | Type | Description | -| -------------- | -------- | ------------------------------------------------------------ | -| `code` | `string` | The authorization code to exchange. | -| `grant_type` | `string` | The type of grant to exchange. Must be `authorization_code`. | -| `redirect_uri` | `string` | The same redirect URI used in the `/authorize` request. | - -### Common Errors - -- `method_not_allowed`: HTTP method is not allowed. Only POST and OPTIONS may be used -- `invalid_content_type`: The provided content type is invalid, only `application/x-www-form-urlencoded` is supported -- `unauthenticated`: The provided authorization token is invalid, try checking your credentials -- `invalid_grant_type`: The provided grant type is invalid, only `authorization_code` is supported -- `required`: A necessary attribute was not set. Required attributes are: `code` -- `invalid_grant`: The authorization code was invalid, and may be expired. Try generating a new code via `/authorize` - -```shell title="cURL" -curl -X POST https://id.worldcoin.org/token \ - -H "Authorization: Basic YXBwXzU1MGU4MjkwODJmYzU1OGUxMTJlMDYyMGMxYzdhNT..." \ - -H "Content-Type: application/x-www-form-urlencoded" \ - -d "code=23e5edda0f731dfdddace390&grant_type=authorization_code&redirect_uri=https%3A%2F%2Fdocs.worldcoin.org%2Fapi%2Fauth" -``` - -```js -const data = new URLSearchParams(); -data.append("code", "23e5edda0f731dfdddace390"); -data.append("grant_type", "authorization_code"); -data.append("redirect_uri", "https://docs.worldcoin.org/api/auth"); - -fetch("https://id.worldcoin.org/token", { - method: "POST", - headers: { - Authorization: `Basic ${btoa(`${client_id}:${client_secret}`)}`, - "Content-Type": "application/x-www-form-urlencoded", - }, - body: data, -}); -``` - -```json title="Response" -{ - "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Imp3a1.ey8yZmVi.ZjY3MDc3N2UyY2NlNzY5YzUxOG...", - "token_type": "Bearer", - "expires_in": 3600, - "scope": "openid", - "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Imp3a1.ey8yZmVi.ZjY3MDc3N2UyY2NlNzY5YzUxOG..." -} -``` - -## OAuth2 - -If you selected `token` as one of your `response_types` for the `/authorize` endpoint, you'll receive an OAuth2 access token. Typically an access token would allow you to perform certain actions on a user's behalf, but there are no actions to perform for a user in this case. -You can retrieve the same information about a user with an access token as you'd receive in an ID token. While we support this functionality for broader compatibility, we generally recommend using the authorization code or implicit flows, rather than the hybrid flow. - -The endpoints below are only used with an OAuth2 access token. - -## Introspect - -**POST** `/introspect` - -Validates the given access token is active for the user. - - - For introspect, [Basic - Authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme) - is used. The `Authorization` header contains the word "Basic ", followed by a - base64 encoding of the "client_id:client_secret" values. You obtain your - client_id (also called app_id) and client_secret from the Developer Portal. - - -### Required attributes - -| Parameter | Type | Description | -| --------- | -------- | ----------------------------- | -| `token` | `string` | The access token to validate. | - -### Common Errors - -- `method_not_allowed`: HTTP method is not allowed. Only POST may be used -- `invalid_content_type`: The provided content type is invalid, only `application/x-www-form-urlencoded` is supported -- `required`: A necessary attribute was not set. Required attributes are: `token` -- `unauthenticated`: The authorization header is missing, please pass the Bearer authorization token -- `invalid_token`: The authorization token was invalid, and may be expired. Try generating a new token via `/token` - -```shell title="cURL" -curl -X POST https://id.worldcoin.org/introspect \ - -H "Authorization: Basic YXBwXzU1MGU4MjkwODJmYzU1OGUxMTJlMDYyMGMxYzdhNT..." \ - -H "Content-Type: application/x-www-form-urlencoded" \ - --data-urlencode "token=eyJhbGciOiJSUzI1NiIsImtpZCI6Imp3a18yZmViZjY3MDc3N2UyY2NlNzY5YzUxOGM3MDNkNTNjMStN..." -``` - -```js -fetch("https://id.worldcoin.org/introspect", { - method: "POST", - headers: { - Authorization: `Basic ${btoa(`${client_id}:${client_secret}`)}`, - "Content-Type": "application/x-www-form-urlencoded", - }, - body: new URLSearchParams({ token }), -}); -``` - -```json title="Response" -{ - "active": true, - "client_id": "app_staging_7550e829082fc558e112e0620c1c7a59", - "exp": 1678330528, - "sub": "0x2ae86d6d747702b3b2c81811cd2b39875e8fa6b780ee4a207bdc203a7860b535" -} -``` - -## Get User Info - -**POST** `/userinfo` - -Retrieves all user information, based on the approved scopes, with the given access token. - - - For userinfo, [Bearer - Authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#bearer_authentication_scheme) - is used. The `Authorization` header contains the word "Bearer ", followed by - the access token returned from the `/token` endpoint. - - -### Common Errors - -- `method_not_allowed`: HTTP method is not allowed. Only GET, POST, and OPTIONS may be used -- `unauthenticated`: The authorization header is missing, please pass the Bearer authorization token -- `invalid_token`: The authorization token was invalid, and may be expired. Try generating a new token via `/token` - -```shell title="cURL" -curl -X POST https://id.worldcoin.org/userinfo \ --H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZ.eyCI6I.mp3a18yZmViZjY3MDc3N2UyY2NlN..." -``` - -```js -fetch("https://id.worldcoin.org/userinfo", { - method: "POST", - headers: { - Authorization: `Bearer ${access_token}`, - }, -}); -``` - -```json title="Response" -{ - "sub": "0x2ae86d6d747702b3b2c81811cd2b39875e8fa6b780ee4a207bdc203a7860b535", - "https://id.worldcoin.org/beta": { - // deprecated, will be removed in the future - "likely_human": "strong", - "credential_type": "orb" - }, - "https://id.worldcoin.org/v1": { - "verification_level": "orb" // "orb" or "device" - }, - // if `email` scope is included: - "email": "0x2ae86d6d747702b3b2c81811cd2b39875e8fa6b780ee4a207bdc203a7860b535@id.worldcoin.org", - // if `profile` scope is included: - "name": "World ID User", - "given_name": "World ID", - "family_name": "User" -} -``` diff --git a/world-id/sign-in/deprecation.mdx b/world-id/sign-in/deprecation.mdx deleted file mode 100644 index e241487..0000000 --- a/world-id/sign-in/deprecation.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: "Sunsetting Sign in with World ID" ---- - -**Deprecation Notice**: Sign in with World ID v1 has been deprecated and will be shut down on **January 31, 2026**. - -The shut down date has been extended from December 12, 2025 to **January 31, 2026** to allow developers and users to finalize their migration. - -As the World ID Protocol evolves, and with the introduction of World ID v25 in 2025, the existing version of Sign in with World ID will no longer be supported. The updated Protocol will provide new functionality and improved privacy guarantees which are no longer compatible with the existing version of Sign in with World ID. The current usage of this feature was taken into consideration. - - -A new version of Sign in with World ID is planned in the future with enhanced functionality and compatibility with existing standards. - -## What are the changes? - -- Starting September 29, 2025, no new apps will be able to enable Sign in with World ID. -- The Sign in with World ID API will be shut down (`id.worldcoin.org`) on January 31, 2026. -- The Sign in with World ID functionality in the Developer Portal will be removed. - -## What should I do? - -- If you are using Sign in with World ID, you should migrate to [IDKit](/world-id/reference/idkit). -- If you are solely using Sign in with World ID for authentication, we recommend migrating your users to different authentication providers. For example, if you are a Mini App, you can migrate to [Wallet Authentication](/mini-apps/commands/wallet-auth). Your users will be able to log in until **January 31, 2026** to add different authentication providers. -- Naturally if you have any questions, please reach out on [Telegram](https://t.me/worlddevelopersupport). - - -Stay tuned for more updates on the World ID v25 Protocol release. diff --git a/world-id/sign-in/oidc.mdx b/world-id/sign-in/oidc.mdx deleted file mode 100644 index 3166a12..0000000 --- a/world-id/sign-in/oidc.mdx +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "OIDC Explainer" -"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" ---- - -**Deprecation Notice**: Sign in with World ID v1 has been deprecated and will be shut down on **January 31, 2026**. Read more in the [announcement](/world-id/sign-in/deprecation). - -The following diagram outlines the general authentication flow for an integrating app: - -![A diagram showcasing the main authentication flow](/images/docs/id/sign-in.svg) - -## Registration - -Before OIDC authentication can take place, developers must register their applications with Worldcoin. This is a one-time action. You can create a new application on the [Developer Portal](https://developer.worldcoin.org). - -During registration, you will need to provide the following values: - -- Redirect URIs: **Required**, list of approved websites the user can be redirected to after successful authentication. -- App name (also called client name): **Optional**, the name of the application that's displayed to users - - -All redirect URIs must be over HTTPS, and contain no port numbers or URL fragments. For example, `https://app.example.com/login` is valid, but `https://app.example.com:3000/login` is not. Similarly, `https://app.example.com/login#foo` is not valid, but `https://app.example.com/login?foo=bar` is. - - -After registration is complete, you will have a valid `app_id` that will be needed for every other step in the authentication process. This value is equivalent to `client_id` from the [OIDC specification](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest) - -## Flows - -World ID supports the [authorization code](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth), [implicit](https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth), and [hybrid](https://openid.net/specs/openid-connect-core-1_0.html#HybridFlowAuth) flows from the OIDC spec. Applications can use any one of these flows to authenticate users. - -_Generally_, applications should implement the authorization code flow, as it is more secure than the implicit flow. Applications without backend servers (that may be running purely client-side) are more suited to implicit authentication. - -## Authentication - -Authentication begins with a request to the `/authorize` endpoint. - -When using the native Sign in with World ID page, most of the OIDC process is handled for you. You can begin the authentication cycle by redirecting your users to: - -``` -https://id.worldcoin.org/authorize?client_id={app_id}&response_type={code|token|id_token}&redirect_uri={encoded_redirect_url}&scope={scope}&state={state_value}&nonce={nonce_value} -``` - -Example values could be: - -- `client_id`: obtained from the Developer Portal (example: `app_lshSNnaJfdt6Sohu6YAA`). -- `response_type`: response type as specified in OIDC spec, remember to URL encode (example: `code%20id_token`). -- `redirect_uri`: where the user is redirected upon successful authentication. Must be on the approved redirect URI list which can always be updated in the Developer Portal (example: `https%3A%2F%2Fapp.example.com%2Flogin`). -- `scope`: space-separated list of scopes to request. Defaults to `openid` if not provided. (example: `openid%20profile%20email`). -- `state`: unique value used to track a user's session (example: `session_102030405060708090`). -- `nonce`: random value to prevent replay attacks (example: `z-dkEmoy_ujfk7B8uTiQpp`). Required when using the `id_token` response type. - -The user will then authenticate with their World ID via the World app. Once successfully authorized, the user is redirected back to your application. The redirect URL will contain a number of values, depending on the flow you are using. - -### Redirect Responses - -If using the default authorization code flow, the redirect URL will contain the following params: - -- `code`: An authorization code that can be exchanged for an ID token -- `state`: The optional state value passed to the `/authorize` endpoint - -If you received a response containing an _authorization code_, you must exchange it for an ID token on the `/token` endpoint. Request details can be [seen here](/world-id/reference/sign-in#exchange-code). - -If using implicit flow, the redirect URL will contain the following params: - -- `id_token`: A signed JWT identifying the user, and any requested scope information - -ID tokens must always be verified, and should not be blindly accepted! Additionally, you must validate that the `nonce` within the ID token matches the nonce you provided. - -To verify an ID token, fetch the public key from the `/jwks` endpoint. You can read more about this process at the [Auth0 blog](https://auth0.com/blog/navigating-rs256-and-jwks/) or [JWT.io](https://jwt.io/), but one example method could be: - -```ts -import * as jose from 'jose' - -const verifyJwt = (token: string) => { - const JWKS = jose.createRemoteJWKSet(new URL('https://id.worldcoin.org/jwks.json')) - - const { payload, header } = await jose.jwtVerify(token, JWKS, { - issuer: 'https://id.worldcoin.org', - aud: 'app_lshSNnaJfdt6Sohu6YAA', - }) - - return payload -} - -verifyJwt('eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp.eyAs.XVCJ9...') -```