Skip to content

Remove the v1 (fetched-key) connect protocol - #66

Merged
aterga merged 2 commits into
mainfrom
claude/patch-pr-j6sdjk
Jul 17, 2026
Merged

Remove the v1 (fetched-key) connect protocol#66
aterga merged 2 commits into
mainfrom
claude/patch-pr-j6sdjk

Conversation

@aterga

@aterga aterga commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

What

Both II instances now run the registration-delegation handshake by default, so the legacy v1 "fetched-key" connect protocol is dead code. This removes it entirely and makes the registration-delegation flow the single, unconditional connect path. The per-instance registration_delegation flag existed only to select v1 vs. the new flow, so it and its env vars go too.

Net: 9 files changed, +340 / −1054.

Changes

src/auth.rs

  • Remove the /oauth/finish handler (finish + FinishQuery), the finishing_page poll, the v1 connect_callback POST handler (key-request + completion cases), ConnectCallback, KeyClaim, authz_known, the connect_error HTML page, and the finish_secret machinery (fresh_secret / sha256 / ct_eq, the REPEAT_KEY_REQUESTS counter + repeat_key_requests(), and AuthzPending.finish_secret_hash).
  • Collapse the registration_delegation conditionals: authorize always mints the registration key and builds the v2 link; the pinned callback page and redeem endpoint are always served (no more 404 guard).
  • Consolidate the link builders — ii_mcp_url_v2 becomes the sole ii_mcp_url.
  • Rewrite the module docs to describe the single flow.

src/identities.rs

  • Remove the IiInstance::registration_delegation field, the MCP_REGISTRATION_DELEGATION / _PROD env vars, and the now-unused env_flag.
  • Remove session_pubkey_b64 and grant_is_live (v1-only). Keep set_grant_expiration / set_permissions (the Phase-2 redemption calls them), refreshing their v1-flavored docs.

src/main.rs

  • Drop the /oauth/finish route; make /oauth/connect/callback GET-only.
  • Remove the /version repeat_key_requests and registration_delegation fields and the per-protocol startup-log branch.

Assets & docs

  • Delete the two v1-only page assets (connect-finishing.html, connect-error.html).
  • Rewrite the README Auth/connect sections and the monitoring check descriptions that referenced the v1 finish_url hand-back.
  • Drop or rework the v1-only tests.

Verification

  • cargo build — clean (only the two pre-existing warnings, tool_router / ok; no new ones).
  • cargo test115 passing, 0 failing.
  • cargo clippy — output identical to the base branch; no new lints.
  • monitoring/mcp-status node --test17 passing.
  • No dangling references to any removed symbol remain anywhere in the tree (connect-finishing, connect-error, MCP_REGISTRATION_DELEGATION, registration_delegation, oauth/finish, finish_secret, repeat_key_requests, connect_callback, bare mcp_register).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Wx6xR88QhyQCtrKUyXgiRL


Generated by Claude Code

Both II instances now run the registration-delegation handshake by default, so
the legacy v1 "fetched-key" connect protocol is dead code. Remove it entirely
and make the registration-delegation flow the single, unconditional connect
path. The per-instance `registration_delegation` flag existed only to select v1
vs the new flow, so it and its env vars go too.

auth.rs
- Remove the `/oauth/finish` handler (`finish` + `FinishQuery`), the
  `finishing_page` poll, the v1 `connect_callback` POST handler (key-request +
  completion cases), `ConnectCallback`, `KeyClaim`, `authz_known`, the
  `connect_error` HTML page, and the `finish_secret` machinery
  (`fresh_secret`/`sha256`/`ct_eq`, the `REPEAT_KEY_REQUESTS` counter +
  `repeat_key_requests()`, and `AuthzPending.finish_secret_hash`).
- Collapse the `registration_delegation` conditionals: `authorize` always mints
  the registration key and builds the v2 link; the pinned callback page and
  redeem endpoint are always served (no more 404 guard).
- Consolidate the link builders — `ii_mcp_url_v2` becomes the sole `ii_mcp_url`.
- Rewrite the module docs to describe the single flow.

identities.rs
- Remove the `IiInstance::registration_delegation` field, the
  MCP_REGISTRATION_DELEGATION / _PROD env vars, and the now-unused `env_flag`.
- Remove `session_pubkey_b64` and `grant_is_live` (v1-only). Keep
  `set_grant_expiration`/`set_permissions` (the Phase-2 redemption calls them),
  refreshing their v1-flavored docs.

main.rs
- Drop the `/oauth/finish` route; make `/oauth/connect/callback` GET-only.
- Remove the `/version` `repeat_key_requests` and `registration_delegation`
  fields and the per-protocol startup-log branch.

Also removed the two v1-only page assets (connect-finishing.html,
connect-error.html), rewrote the README Auth/connect sections and the monitoring
check descriptions that referenced the v1 `finish_url` hand-back, and dropped or
reworked the v1-only tests.

Verified: cargo build/test (120 passing) + clippy clean (no new warnings);
monitoring node --test 17 passing. Smoke test confirms /oauth/finish now 404s,
POST /oauth/connect/callback 405s, the pinned page GET serves 200, and /version
no longer reports the removed fields.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wx6xR88QhyQCtrKUyXgiRL
@aterga
aterga marked this pull request as ready for review July 17, 2026 14:13
Copilot AI review requested due to automatic review settings July 17, 2026 14:13

Copilot AI 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.

Pull request overview

This PR removes the legacy v1 “fetched-key” Internet Identity MCP connect protocol and makes the registration-delegation handshake the single, unconditional connect flow across both II instances. It simplifies the auth/connect surface area by deleting v1-only handlers, flags/env vars, assets, and operational signals, while updating docs and monitoring to describe/validate only the v2 flow.

Changes:

  • Remove v1 connect endpoints and supporting machinery (/oauth/finish, POST /oauth/connect/callback, finish-secret + repeat-key-requests observability) and make the pinned callback page + redeem endpoint the only connect path.
  • Remove the per-instance registration_delegation toggle (and related env vars) so both instances always run the same flow.
  • Update README and monitoring checks/docs to reflect the pinned-callback + redeem-based handshake and new /version payload.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/main.rs Removes v1 routes and per-protocol logging/version fields; makes connect callback GET-only.
src/identities.rs Deletes per-instance protocol flag/env handling and v1-only session helpers; refreshes docs around v2 registration.
src/auth.rs Removes v1 finish/callback POST flow and consolidates to pinned callback page + redeem with mcp_register_v2.
src/assets/connect-finishing.html Deletes v1 finishing/polling interstitial asset.
src/assets/connect-error.html Deletes v1 connect error page asset.
README.md Rewrites auth/connect documentation to describe only registration-delegation and updated /version fields.
monitoring/mcp-status/README.md Updates monitoring doc text to match the pinned callback + fetch redemption flow.
monitoring/mcp-status/checks.test.js Updates test expectations/comments for the new connect flow (no finish_url).
monitoring/mcp-status/checks.js Updates health-check descriptions/comments to reflect the pinned callback + redeem fetch model.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/auth.rs
The comment's 'it' was ambiguous — a reader could take it to mean the whole
connect flow works without JS, when only the outbound 302 redirect to II does
(the pinned callback page still needs JS to read the fragment and POST the
delegation). Scope the statement to that hop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wx6xR88QhyQCtrKUyXgiRL
Copilot AI review requested due to automatic review settings July 17, 2026 14:17

Copilot AI 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.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

@aterga
aterga merged commit 88984cb into main Jul 17, 2026
2 checks passed
aterga pushed a commit that referenced this pull request Jul 20, 2026
Rebased onto main after #64 (identity tools take derivation_origin only),
reconciliation is now carried by #66, so this narrows to the non-auth
improvements that main still lacks:

- call_canister: document the candid? arg; state the OQL query-call
  rejection accurately (fires when get_canister_candid reports oql: true,
  not on any OQL canister).
- discover: reframe open_app as the one-call entry point; note the domain
  argument accepts a domain or URL.
- App Connect: add the SSRF-hardening note (CWE-918), scoped precisely
  (user-supplied fetches are address-pinned; dashboard/registry enrichment
  uses the redirect guard only).
- OQL: define the CWE-674 guard (1 MiB / 128-depth pre-parse check over
  textual Candid; the OQL query path is JSON and only shares the size cap).
- Creating canisters: correct the CMC recovery hint (re-notify with the
  same arguments; the block index alone is not enough).
- Run/Deploy: self-contained binary via include_str!; OAUTH_CLIENTS_FILE is
  always used (default oauth-clients.json, read on startup, best-effort
  write), needs a writable path; graceful SIGTERM/SIGINT drain; landing page.
- Try it: fix the stateless plain-JSON example (drop the SSE parsing and
  session-id dance, show the bearer token, label the read anonymous).
- Domain identities: correct the stale custom-derivation-origin note (the
  app_url path resolves declared/known origins via resolve_app; only a raw
  derivation_origin is used verbatim).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014T9N8USDfNK5yzznPGg7Ym
aterga pushed a commit that referenced this pull request Jul 21, 2026
Rebased onto main after #64 (identity tools take derivation_origin only),
reconciliation is now carried by #66, so this narrows to the non-auth
improvements that main still lacks:

- call_canister: document the candid? arg; state the OQL query-call
  rejection accurately (fires when get_canister_candid reports oql: true,
  not on any OQL canister).
- discover: reframe open_app as the one-call entry point; note the domain
  argument accepts a domain or URL.
- App Connect: add the SSRF-hardening note (CWE-918), scoped precisely
  (user-supplied fetches are address-pinned; dashboard/registry enrichment
  uses the redirect guard only).
- OQL: define the CWE-674 guard (1 MiB / 128-depth pre-parse check over
  textual Candid; the OQL query path is JSON and only shares the size cap).
- Creating canisters: correct the CMC recovery hint (re-notify with the
  same arguments; the block index alone is not enough).
- Run/Deploy: self-contained binary via include_str!; OAUTH_CLIENTS_FILE is
  always used (default oauth-clients.json, read on startup, best-effort
  write), needs a writable path; graceful SIGTERM/SIGINT drain; landing page.
- Try it: fix the stateless plain-JSON example (drop the SSE parsing and
  session-id dance, show the bearer token, label the read anonymous).
- Domain identities: correct the stale custom-derivation-origin note (the
  app_url path resolves declared/known origins via resolve_app; only a raw
  derivation_origin is used verbatim).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014T9N8USDfNK5yzznPGg7Ym
aterga pushed a commit that referenced this pull request Jul 21, 2026
Rebased onto main after #64 (identity tools take derivation_origin only),
reconciliation is now carried by #66, so this narrows to the non-auth
improvements that main still lacks:

- call_canister: document the candid? arg; state the OQL query-call
  rejection accurately (fires when get_canister_candid reports oql: true,
  not on any OQL canister).
- discover: reframe open_app as the one-call entry point; note the domain
  argument accepts a domain or URL.
- App Connect: add the SSRF-hardening note (CWE-918), scoped precisely
  (user-supplied fetches are address-pinned; dashboard/registry enrichment
  uses the redirect guard only).
- OQL: define the CWE-674 guard (1 MiB / 128-depth pre-parse check over
  textual Candid; the OQL query path is JSON and only shares the size cap).
- Creating canisters: correct the CMC recovery hint (re-notify with the
  same arguments; the block index alone is not enough).
- Run/Deploy: self-contained binary via include_str!; OAUTH_CLIENTS_FILE is
  always used (default oauth-clients.json, read on startup, best-effort
  write), needs a writable path; graceful SIGTERM/SIGINT drain; landing page.
- Try it: fix the stateless plain-JSON example (drop the SSE parsing and
  session-id dance, show the bearer token, label the read anonymous).
- Domain identities: correct the stale custom-derivation-origin note (the
  app_url path resolves declared/known origins via resolve_app; only a raw
  derivation_origin is used verbatim).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014T9N8USDfNK5yzznPGg7Ym
aterga pushed a commit that referenced this pull request Jul 22, 2026
Rebased onto main after #64 (identity tools take derivation_origin only),
reconciliation is now carried by #66, so this narrows to the non-auth
improvements that main still lacks:

- call_canister: document the candid? arg; state the OQL query-call
  rejection accurately (fires when get_canister_candid reports oql: true,
  not on any OQL canister).
- discover: reframe open_app as the one-call entry point; note the domain
  argument accepts a domain or URL.
- App Connect: add the SSRF-hardening note (CWE-918), scoped precisely
  (user-supplied fetches are address-pinned; dashboard/registry enrichment
  uses the redirect guard only).
- OQL: define the CWE-674 guard (1 MiB / 128-depth pre-parse check over
  textual Candid; the OQL query path is JSON and only shares the size cap).
- Creating canisters: correct the CMC recovery hint (re-notify with the
  same arguments; the block index alone is not enough).
- Run/Deploy: self-contained binary via include_str!; OAUTH_CLIENTS_FILE is
  always used (default oauth-clients.json, read on startup, best-effort
  write), needs a writable path; graceful SIGTERM/SIGINT drain; landing page.
- Try it: fix the stateless plain-JSON example (drop the SSE parsing and
  session-id dance, show the bearer token, label the read anonymous).
- Domain identities: correct the stale custom-derivation-origin note (the
  app_url path resolves declared/known origins via resolve_app; only a raw
  derivation_origin is used verbatim).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014T9N8USDfNK5yzznPGg7Ym
aterga pushed a commit that referenced this pull request Jul 23, 2026
Rebased onto main after #64 (identity tools take derivation_origin only),
reconciliation is now carried by #66, so this narrows to the non-auth
improvements that main still lacks:

- call_canister: document the candid? arg; state the OQL query-call
  rejection accurately (fires when get_canister_candid reports oql: true,
  not on any OQL canister).
- discover: reframe open_app as the one-call entry point; note the domain
  argument accepts a domain or URL.
- App Connect: add the SSRF-hardening note (CWE-918), scoped precisely
  (user-supplied fetches are address-pinned; dashboard/registry enrichment
  uses the redirect guard only).
- OQL: define the CWE-674 guard (1 MiB / 128-depth pre-parse check over
  textual Candid; the OQL query path is JSON and only shares the size cap).
- Creating canisters: correct the CMC recovery hint (re-notify with the
  same arguments; the block index alone is not enough).
- Run/Deploy: self-contained binary via include_str!; OAUTH_CLIENTS_FILE is
  always used (default oauth-clients.json, read on startup, best-effort
  write), needs a writable path; graceful SIGTERM/SIGINT drain; landing page.
- Try it: fix the stateless plain-JSON example (drop the SSE parsing and
  session-id dance, show the bearer token, label the read anonymous).
- Domain identities: correct the stale custom-derivation-origin note (the
  app_url path resolves declared/known origins via resolve_app; only a raw
  derivation_origin is used verbatim).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014T9N8USDfNK5yzznPGg7Ym
aterga pushed a commit that referenced this pull request Jul 28, 2026
Rebased onto main after #64 (identity tools take derivation_origin only),
reconciliation is now carried by #66, so this narrows to the non-auth
improvements that main still lacks:

- call_canister: document the candid? arg; state the OQL query-call
  rejection accurately (fires when get_canister_candid reports oql: true,
  not on any OQL canister).
- discover: reframe open_app as the one-call entry point; note the domain
  argument accepts a domain or URL.
- App Connect: add the SSRF-hardening note (CWE-918), scoped precisely
  (user-supplied fetches are address-pinned; dashboard/registry enrichment
  uses the redirect guard only).
- OQL: define the CWE-674 guard (1 MiB / 128-depth pre-parse check over
  textual Candid; the OQL query path is JSON and only shares the size cap).
- Creating canisters: correct the CMC recovery hint (re-notify with the
  same arguments; the block index alone is not enough).
- Run/Deploy: self-contained binary via include_str!; OAUTH_CLIENTS_FILE is
  always used (default oauth-clients.json, read on startup, best-effort
  write), needs a writable path; graceful SIGTERM/SIGINT drain; landing page.
- Try it: fix the stateless plain-JSON example (drop the SSE parsing and
  session-id dance, show the bearer token, label the read anonymous).
- Domain identities: correct the stale custom-derivation-origin note (the
  app_url path resolves declared/known origins via resolve_app; only a raw
  derivation_origin is used verbatim).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014T9N8USDfNK5yzznPGg7Ym
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.

3 participants