From 2616333d9651350ca177f636be38e30c38de8150 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 12 Jun 2026 14:02:20 +0000 Subject: [PATCH 1/2] docs: extend interface spec with delegation permissions field Specify the optional permissions field of request delegations drafted in dfinity/ic#10449: - https-interface.md: document the permissions field of the delegation map ("queries" restricts the delegation to query calls and read_state requests, "all" is the same as omitting the field, any other value makes the delegation invalid for all kinds of requests) and add permissions to the string-typed fields in the representation- independent hashing section. - abstract-behavior.md: extend SignedDelegation with permissions : Text | Unrestricted and amend verify_envelope / verify_delegations so that unsupported values fail verification for all requests and update calls fail if any delegation in the chain is restricted to queries. - changelog.md: add a 0.63.0 entry for the feature. https://claude.ai/code/session_01WBqBka57Q7xYi4btZYfPqT --- docs/references/ic-interface-spec/abstract-behavior.md | 7 +++++-- docs/references/ic-interface-spec/changelog.md | 9 +++++++++ docs/references/ic-interface-spec/https-interface.md | 10 +++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/references/ic-interface-spec/abstract-behavior.md b/docs/references/ic-interface-spec/abstract-behavior.md index 0961d2e4..387682df 100644 --- a/docs/references/ic-interface-spec/abstract-behavior.md +++ b/docs/references/ic-interface-spec/abstract-behavior.md @@ -348,7 +348,8 @@ SignedDelegation = { delegation : { pubkey : PublicKey; targets : [CanisterId] | Unrestricted; - expiration : Timestamp + expiration : Timestamp; + permissions : Text | Unrestricted }; signature : Signature } @@ -692,7 +693,7 @@ that represents Candid encoding; this is implicitly taking the method types, as #### Envelope Authentication -The following predicate describes when an envelope `E` correctly signs the enclosed request with a key belonging to a user `U`, at time `T`: It returns which canister ids this envelope may be used at (as a set of principals). +The following predicate describes when an envelope `E` correctly signs the enclosed request with a key belonging to a user `U`, at time `T`: It returns which canister ids this envelope may be used at (as a set of principals). Every delegation whose `permissions` field is set must hold a supported value (`"queries"` or `"all"`); otherwise, the predicate fails for requests of any kind. Moreover, the predicate fails for update calls (requests of type `Request`) if any delegation in the chain restricts the sender to query calls and `read_state` requests (`permissions` field set to `"queries"`). ``` verify_envelope({ content = C }, U, T) = { p : p is CanisterID } if U = anonymous_id @@ -700,6 +701,7 @@ verify_envelope({ content = C }, U, T) verify_envelope({ content = C, sender_pubkey = PK, sender_sig = Sig, sender_delegation = DS}, U, T) = TS if U = mk_self_authenticating_id PK ∧ (PK', TS) = verify_delegations(DS, PK, T, { p : p is CanisterId }) + ∧ (C is Request ⇒ ∀ D ∈ DS. D.delegation.permissions ≠ "queries") ∧ verify_signature PK' Sig ("\x0Aic-request" · hash_of_map(C)) ∧ (if PK = canister_signature_pk Signing_canister_id _: C.sender_info = null @@ -711,6 +713,7 @@ verify_delegations([D] · DS, PK, T, TS) = verify_delegations(DS, D.pubkey, T, TS ∩ delegation_targets(D)) if verify_signature PK D.signature ("\x1Aic-request-auth-delegation" · hash_of_map(D.delegation)) ∧ D.delegation.expiration ≥ T + ∧ D.delegation.permissions ∈ { Unrestricted, "all", "queries" } delegation_targets(D) = if D.targets = Unrestricted then { p : p is CanisterId } diff --git a/docs/references/ic-interface-spec/changelog.md b/docs/references/ic-interface-spec/changelog.md index 118a5c85..df85bc6f 100644 --- a/docs/references/ic-interface-spec/changelog.md +++ b/docs/references/ic-interface-spec/changelog.md @@ -8,6 +8,15 @@ sidebar: ## Changelog {#changelog} + +### 0.63.0 (2026-06-12) {$0_63_0} +* New optional `permissions` field in request delegations restricting the kinds of requests + the delegation applies for: the value `"queries"` restricts the delegation to query calls + and `read_state` requests, so update calls carrying such a delegation in their chain of + delegations are not accepted; the value `"all"` permits all kinds of requests, same as + omitting the field. Requests of any kind carrying a delegation with any other value of + the `permissions` field are not accepted. + ### 0.62.0 (2025-05-26) {$0_62_0} * Inter-canister response callback messages might still be executed after the condition for `canister_on_low_wasm_memory` is triggered and before the function `canister_on_low_wasm_memory` is executed. diff --git a/docs/references/ic-interface-spec/https-interface.md b/docs/references/ic-interface-spec/https-interface.md index 28f47d1b..3f0dd3f0 100644 --- a/docs/references/ic-interface-spec/https-interface.md +++ b/docs/references/ic-interface-spec/https-interface.md @@ -545,6 +545,14 @@ Signing transactions can be delegated from one key to another one. If delegation - `targets` (`array` of `CanisterId`, optional): If this field is set, the delegation only applies for requests sent to the canisters in the list. The list must contain no more than 1000 elements; otherwise, the request will not be accepted by the IC. + - `permissions` (`text`, optional): If this field is set, the delegation only applies for the kinds of requests permitted by its value. The following values are supported: + + - `"queries"`: the delegation only applies for query calls and `read_state` requests. Requests to `/call` endpoints (i.e., update calls, including calls to query methods submitted as update calls) are not accepted by the IC if any delegation in the chain carries this value: a subsequent delegation cannot lift the restriction imposed by a previous one. + + - `"all"`: the delegation applies for all kinds of requests; this is the same as omitting the field. + + If this field is set to any other value, then the delegation is invalid and requests of any kind whose chain of delegations contains the delegation will not be accepted by the IC. + - `signature` (`blob`): Signature on the 32-byte [representation-independent hash](#hash-of-map) of the map contained in the `delegation` field as described in [Signatures](./index.md#signatures), using the 27 bytes `\x1Aic-request-auth-delegation` as the domain separator. For the first delegation in the array, this signature is created with the key corresponding to the public key from the `sender_pubkey` field, all subsequent delegations are signed with the key corresponding to the public key contained in the preceding delegation. @@ -571,7 +579,7 @@ Field values are hashed as follows: - Binary blobs (`canister_id`, `arg`, `nonce`, `module`) are hashed as-is. -- Strings (`request_type`, `method_name`) are hashed by hashing their binary encoding in UTF-8, without a terminal `\x00`. +- Strings (`request_type`, `method_name`, `permissions`) are hashed by hashing their binary encoding in UTF-8, without a terminal `\x00`. - Natural numbers (`compute_allocation`, `memory_allocation`, `ingress_expiry`) are hashed by hashing their binary encoding using the shortest form [Unsigned LEB128](https://en.wikipedia.org/wiki/LEB128#Unsigned_LEB128) encoding. For example, `0` should be encoded as a single zero byte `[0x00]` and `624485` should be encoded as byte sequence `[0xE5, 0x8E, 0x26]`. From 52f162a05e5b3b20305dac705652dfa66bc52720 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 12 Jun 2026 20:01:03 +0000 Subject: [PATCH 2/2] docs: mark permissions changelog entry as unreleased The draft status was only visible in an HTML comment, so the rendered changelog presented a provisional version and date as a finalized release. Mark the entry visibly as unreleased and drop the date until the feature ships. https://claude.ai/code/session_01WBqBka57Q7xYi4btZYfPqT --- docs/references/ic-interface-spec/changelog.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/references/ic-interface-spec/changelog.md b/docs/references/ic-interface-spec/changelog.md index df85bc6f..cccd4583 100644 --- a/docs/references/ic-interface-spec/changelog.md +++ b/docs/references/ic-interface-spec/changelog.md @@ -8,8 +8,8 @@ sidebar: ## Changelog {#changelog} - -### 0.63.0 (2026-06-12) {$0_63_0} + +### 0.63.0 (unreleased) {$0_63_0} * New optional `permissions` field in request delegations restricting the kinds of requests the delegation applies for: the value `"queries"` restricts the delegation to query calls and `read_state` requests, so update calls carrying such a delegation in their chain of