From 2afcbbbee4ff6e6c3b28e5ea116ba4bfa1968186 Mon Sep 17 00:00:00 2001 From: "pr-automation-bot-public[bot]" Date: Tue, 7 Jul 2026 10:12:42 +0000 Subject: [PATCH] chore: sync II spec to dfinity/internet-identity release-2026-07-06 --- .sources/VERSIONS | 2 +- .sources/internetidentity | 2 +- public/references/internet-identity.did | 113 ++++++++++++++++-------- 3 files changed, 76 insertions(+), 41 deletions(-) diff --git a/.sources/VERSIONS b/.sources/VERSIONS index 395ba50..4fb0717 100644 --- a/.sources/VERSIONS +++ b/.sources/VERSIONS @@ -62,4 +62,4 @@ motoko-core v2.4.0 cdk-rs ic-cdk v0.20.1 / ic-cdk-timers v1.0.0 / ic-cdk-executor v2.0.0 317f55c candid 2025-12-18 # candid v0.10.20, didc v0.5.4 2e4a2cf response-verification v3.1.0 18c5a37 -internetidentity release-2026-06-29 5fe49cfd +internetidentity release-2026-07-06 37670ecf diff --git a/.sources/internetidentity b/.sources/internetidentity index 5fe49cf..37670ec 160000 --- a/.sources/internetidentity +++ b/.sources/internetidentity @@ -1 +1 @@ -Subproject commit 5fe49cfd5070e763d5d70c2160cca2568a459303 +Subproject commit 37670ecf4ac0600a9ff596ebc8a5e885e31249cd diff --git a/public/references/internet-identity.did b/public/references/internet-identity.did index 6f08665..5574be5 100644 --- a/public/references/internet-identity.did +++ b/public/references/internet-identity.did @@ -157,8 +157,21 @@ type Delegation = record { pubkey : PublicKey; expiration : Timestamp; targets : opt vec principal; + // Restricts the kinds of calls the delegation permits: `"queries"` + // restricts the sender to query calls (the IC rejects update calls + // authenticated through such a delegation). Absent means unrestricted. + permissions : opt text; }; +// The delegation permissions a caller requests, mirroring the ICP protocol's +// request-delegation `permissions` values. `queries` yields a queries-only +// delegation (the issued `Delegation` carries `permissions = "queries"`); +// `all` yields an unrestricted, update-capable delegation. Passed as an +// optional argument; an absent argument means `all`, preserving the +// pre-feature behavior and matching the interface spec's default for an +// absent `permissions` field. +type Permissions = variant { queries; all }; + type SignedDelegation = record { delegation : Delegation; signature : blob; @@ -1078,11 +1091,11 @@ type PrepareAccountDelegation = record { expiration : Timestamp; }; -// Result of mcp_prepare_account_delegation. Carries the account_number the -// canister used (the one named in the request, or the anchor's default account -// at target_origin when none was named) so the MCP server can thread the same -// account into mcp_get_account_delegation — the default is mutable, so -// re-resolving it in `get` could otherwise diverge and yield NoSuchDelegation. +// Result of mcp_prepare_delegation. Carries the account_number the canister +// used (the one named in the request, or the anchor's default account at +// target_origin when none was named) so the MCP server can thread the same +// account into mcp_get_delegation — the default is mutable, so re-resolving +// it in `get` could otherwise diverge and yield NoSuchDelegation. type McpPrepareDelegation = record { user_key : UserKey; expiration : Timestamp; @@ -1111,6 +1124,13 @@ type McpConfig = record { url : opt text; }; +// Result of mcp_register: the expiration (ns since epoch) of the MCP session +// grant just registered. Every server-facing mcp_* call returns Unauthorized +// once it passes; the server reconnects through a new consent flow. +type McpRegistration = record { + expiration : Timestamp; +}; + type GetAccountsError = variant { InternalCanisterError : text; Unauthorized : principal; @@ -1779,35 +1799,47 @@ service : (opt InternetIdentityInit) -> { origin : FrontendHostname, account_number : opt AccountNumber, // Null is unreserved default account session_key : SessionKey, - max_ttl : opt nat64 + max_ttl : opt nat64, + // `opt (queries)` restricts the prepared delegation to query calls: it + // carries `permissions = "queries"`, which makes the IC reject update + // calls authenticated through it. Omitted (`null`) or `opt (all)` + // yields an unrestricted delegation — the original behavior, preserved + // for existing callers and matching the interface spec. + permissions : opt Permissions ) -> (variant { Ok : PrepareAccountDelegation; Err : AccountDelegationError }); - + get_account_delegation : ( anchor_number : UserNumber, origin : FrontendHostname, account_number : opt AccountNumber, // Null is unreserved default account session_key : SessionKey, - expiration : Timestamp + expiration : Timestamp, + // Must match the value passed to `prepare_account_delegation` (including + // the omitted/`null` case, which means unrestricted). + permissions : opt Permissions ) -> (variant { Ok : SignedDelegation; Err : AccountDelegationError }) query; - // Enable/disable the backend /mcp delegation path for an anchor at a given - // MCP server origin. Enabling binds the principal II derives for the anchor - // at that origin; disabling unbinds exactly that principal. No account is - // chosen here (accounts are per-origin and the connector isn't an app) — the - // app account is selected per call on mcp_prepare_account_delegation. The - // origin comes from the connect request, so each user trusts the MCP server - // they choose. - mcp_set_access : ( - anchor_number : UserNumber, - mcp_server_origin : FrontendHostname, - enabled : bool - ) -> (variant { Ok; Err : text }); - - // Whether the anchor has MCP access enabled at mcp_server_origin. - mcp_access_enabled : ( + // Register the trusted MCP server's session key for the anchor: grant the + // key's self-authenticating principal access to the server-facing mcp_* + // methods until the grant expires (grant_ttl_ns clamped to [10 min, 30 + // days]). Called by the /mcp connect flow after user consent, with a key + // the frontend fetched from the *trusted* server's callback — never taken + // from the unauthenticated connect link. No account is chosen here + // (accounts are per-origin and the connector isn't an app) — the app + // account is selected per call on mcp_prepare_delegation. + // + // At most one session per identity: registering replaces any previous + // grant. Requires the identity's MCP config to be enabled with a trusted + // server set, so every session stays revocable via mcp_set_config. + mcp_register : ( anchor_number : UserNumber, - mcp_server_origin : FrontendHostname - ) -> (bool) query; + session_key : SessionKey, + grant_ttl_ns : nat64, + // `opt (queries)` makes every per-app delegation this session later + // mints queries-only (read-only, chosen once for the whole session). + // Omitted (`null`) or `opt (all)` means full, update-capable access. + permissions : opt Permissions + ) -> (variant { Ok : McpRegistration; Err : text }); // Read the identity's synced trusted-MCP-server config (master toggle + the // trusted server URL). Persisted on-chain, so it follows the identity across @@ -1819,41 +1851,44 @@ service : (opt InternetIdentityInit) -> { // Persist the identity's trusted-MCP-server config so it syncs across the // identity's devices. Authenticated as the identity, so only the user — never // a page that initiates a connect request — can change what it trusts. + // Disabling MCP or changing the trusted server URL revokes the identity's + // active MCP session in the same message. mcp_set_config : ( anchor_number : UserNumber, config : McpConfig ) -> (variant { Ok; Err : text }); - // Called by the MCP server, authorized by caller() == the principal bound for - // its anchor at the connect-time mcp_server_origin; the anchor is recovered - // from the caller. Mints a per-app delegation at target_origin. account_number + // Called by the MCP server, signed with its registered session key and + // authorized by caller()'s unexpired grant; the anchor is recovered from + // the caller. Mints a per-app delegation at target_origin. account_number // names one of the anchor's accounts there to act as (discover them with // mcp_get_accounts), and null uses the anchor's default account there; an // account_number that isn't the anchor's at target_origin is rejected as // Unauthorized. max_ttl is the requested lifetime in ns, defaulting to and - // capped at 5 minutes. The resolved account_number is returned in - // McpPrepareDelegation so it can be threaded into mcp_get_account_delegation - // (the default account at an origin is mutable). - mcp_prepare_account_delegation : ( + // capped at 1 hour, and never outliving the session grant. The resolved + // account_number is returned in McpPrepareDelegation so it can be threaded + // into mcp_get_delegation (the default account at an origin is mutable). + mcp_prepare_delegation : ( target_origin : FrontendHostname, account_number : opt AccountNumber, session_key : SessionKey, max_ttl : opt nat64 ) -> (variant { Ok : McpPrepareDelegation; Err : AccountDelegationError }); - // Fetch the delegation prepared above; the anchor is recovered from caller(). - // account_number and expiration must be the values returned by the matching - // mcp_prepare_account_delegation, else this returns NoSuchDelegation. - mcp_get_account_delegation : ( + // Fetch the delegation prepared above; the anchor is recovered from + // caller()'s grant. account_number and expiration must be the values + // returned by the matching mcp_prepare_delegation, else this returns + // NoSuchDelegation. + mcp_get_delegation : ( target_origin : FrontendHostname, account_number : opt AccountNumber, session_key : SessionKey, expiration : Timestamp ) -> (variant { Ok : SignedDelegation; Err : AccountDelegationError }) query; - // Called by the MCP server (anchor recovered from caller()): list the anchor's - // accounts at target_origin so the agent can pick which account_number to - // request a delegation for via mcp_prepare_account_delegation. + // Called by the MCP server (anchor recovered from caller()'s grant): list + // the anchor's accounts at target_origin so the agent can pick which + // account_number to request a delegation for via mcp_prepare_delegation. mcp_get_accounts : ( target_origin : FrontendHostname ) -> (variant { Ok : vec AccountInfo; Err : AccountDelegationError }) query;