Skip to content

Fix World ID simulator sandbox: identity selector, verifier config, staging credentials - #14

Open
juguelio wants to merge 1 commit into
p2pdevmedia:mainfrom
juguelio:fix/world-id-simulator
Open

Fix World ID simulator sandbox: identity selector, verifier config, staging credentials#14
juguelio wants to merge 1 commit into
p2pdevmedia:mainfrom
juguelio:fix/world-id-simulator

Conversation

@juguelio

Copy link
Copy Markdown
Collaborator

Debuggeando por qué no se podía completar el alta contra el simulador de World ID, encontré tres problemas independientes. Reproduje el flujo completo en local sobre a5b0b13.

Tu commit 6d38d7a (protocolo v3 para testnet) era correcto y necesario — con eso el server ya llega a policy human authorization issued (HTTP 200) con una prueba v3 Orb. Lo que sigue abajo es lo que quedaba después de eso.

1. El rewrite del link al simulador nunca corría

rewriteSimulatorLinks consulta solo document, pero el widget de IDKit renderiza su callout "Testing in staging?" dentro de un shadow root. El selector no matcheaba nada y la reescritura a /select-id no hacía nada, en silencio.

Consecuencia: el callout abre la identidad por defecto del simulador en vez del selector de identidades. Eso se manifiesta como "me devuelve otro usuario" y como errores 409 de nullifier ya usado — porque esa identidad por defecto ya abrió una póliza.

Verificado: antes el href quedaba en simulator.worldcoin.org/, ahora resuelve a simulator.worldcoin.org/select-id?connect_url=... y aparece el selector.

2. Los deployments configurados por env no exponían policyHumanVerifier

RiskaEnrollmentHome descarta la autorización si el verifier no coincide con el configurado:

const matchesCurrentAuthorization =
  configuredPolicyManager && configuredVerifier && ...
if (!matchesCurrentAuthorization || isHumanReservationExpired(reservation)) {
  setState(... humanReservation: null);
  setActiveStepId("identity");
}

readDeploymentEnv no devolvía policyHumanVerifier, y undefined es falsy → cuenta como mismatch → todo usuario verificado vuelve al paso de identidad. Ahora lee RISKA_WORLDCHAIN[_SEPOLIA]_POLICY_HUMAN_VERIFIER.

Los deployments que salen del JSON committeado no se ven afectados (ese camino ya lo exponía). Dejé la precedencia file ?? env intacta.

3. Credenciales de World ID por entorno

Los apps de World ID se registran por entorno, y el simulador solo acepta requests de un app de staging: un app id de producción produce un request de producción sin importar el environment que se le pase a IDKit.

Agregué NEXT_PUBLIC_WORLD_APP_ID_STAGING, WORLD_ID_RP_ID_STAGING y RP_SIGNING_KEY_STAGING, seleccionados por deployment, cada uno con fallback al valor único actual — así nada cambia si no se configuran. /api/identity/rp-signature ahora recibe el deployment para firmar con el RP correspondiente.


Dos cosas que no pude verificar y necesito de tu lado

  1. ¿Hay un app/RP de staging en el Developer Portal? El punto 3 está preparado pero sin credenciales no puedo confirmar que cierre el caso. Si rp_06de503e374550e8 ya cubre staging, quizá alcance con lo demás.
  2. El paso final de la UI no lo pude probar, porque no tengo el POLICY_HUMAN_SIGNING_KEY que corresponde al verifier desplegado (0xDbe839…). Firmando con una clave de prueba, la app descarta la autorización por el chequeo del punto 2 — que es el comportamiento correcto.

Fuera de este PR, a propósito

  • Cambios de seguridad (el bypass de sesión de wallet en staging) — van aparte porque tocan comportamiento de auth y merecen su propia discusión.
  • Instrumentación de diagnóstico en verify-policy-human-handler: hoy el mensaje "World ID proof of human is missing or is not bound to the connected wallet" mezcla tres fallas distintas (protocolo equivocado, signal que no coincide, identidad ya usada). Fue lo que más tiempo hizo perder acá. La tengo escrita si te sirve.

…taging credentials

Enrollment could not be completed against the World ID simulator. Reproduced
locally end to end; three independent defects:

1. The simulator-link rewrite never ran. `rewriteSimulatorLinks` queries only
   `document`, but the IDKit widget renders its "Testing in staging?" callout
   inside a shadow root, so the selector matched nothing and the rewrite to
   `/select-id` silently did nothing. The callout therefore opened the
   simulator's *default* identity instead of its identity selector, which
   surfaces as "it returns a different user" and as spurious
   nullifier-already-used (409) errors, because that default identity has
   already opened a policy. Fixed by walking open shadow roots as well.

2. Env-configured deployments omitted `policyHumanVerifier`.
   `RiskaEnrollmentHome` discards a policy-human authorization whose verifier
   does not match the configured one, and a missing verifier is falsy, so it
   counts as a mismatch: every verified user is bounced back to the identity
   step. `readDeploymentEnv` now also reads
   `RISKA_WORLDCHAIN[_SEPOLIA]_POLICY_HUMAN_VERIFIER`. Deployments configured
   from the committed JSON are unaffected.

3. World ID apps are registered per environment, and the simulator only
   accepts requests from a staging app; a production app id yields a
   production request regardless of the `environment` flag passed to IDKit.
   Allow a staging app id, RP id and RP signing key selected by deployment
   (`NEXT_PUBLIC_WORLD_APP_ID_STAGING`, `WORLD_ID_RP_ID_STAGING`,
   `RP_SIGNING_KEY_STAGING`), each falling back to the existing single value,
   so current setups are unchanged. `/api/identity/rp-signature` now receives
   the deployment so it can sign with the matching RP.

Verified: with (1) applied, the callout resolves to
`simulator.worldcoin.org/select-id?connect_url=...` and the identity selector
appears. Server-side the flow reaches `policy human authorization issued`
(HTTP 200) with a v3 Orb proof on the testnet deployment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Someone is attempting to deploy a commit to the p2pdevmedia's projects Team on Vercel.

A member of the Team first needs to authorize it.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9adb2d18ce

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +36 to +38
const env = stagingEnv
? { WORLD_ID_RP_ID: stagingEnv.WORLD_ID_RP_ID_STAGING, RP_SIGNING_KEY: stagingEnv.RP_SIGNING_KEY_STAGING }
: requiredEnvironment(["WORLD_ID_RP_ID", "RP_SIGNING_KEY"]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep staging RP ID consistent through verification

When TEST passes deployment: "testnet" and these new staging env vars are configured, this route now returns rp_context.rp_id from WORLD_ID_RP_ID_STAGING, but /api/identity/verify-policy-human still builds policyHumanEnvironment() with only WORLD_ID_RP_ID and posts the proof to https://developer.world.org/api/v4/verify/${serverEnvironment.rpId}. That means the simulator proof is issued for the staging RP but verified against the production RP, so the World ID verification step fails for the exact staging-credential setup this change introduces; the verification env needs the same staging RP selection/fallback.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant