Skip to content

Commit

Permalink
ICRC-28/34: Clarify confusing sections (#204)
Browse files Browse the repository at this point in the history
* ICRC-28/34: Clarify confusing sections

This PR resolves the findings with regards to confusing wording that were
found in the prod sec review.

It also adds a recommendation for approval flows for
tradable assets in ICRC-28 in order to guide developers looking to get
rid of approvals when interacting with ledgers.

* Clarify wording on recommendation for ICRC-2 and ICRC-37

* Add suggested note

* Reword recommendation to use approval flows

* ICRC-34: Align permission check with ICRC-25

* Update permission check to be consistent with ICRC-27/49
  • Loading branch information
frederikrothenberger authored Aug 28, 2024
1 parent c45464d commit bbcc651
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 26 deletions.
35 changes: 25 additions & 10 deletions topics/icrc_28_trusted_origins.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
This standard describes how a canister can indicate that a relying party (an entity that relies on the canister for certain functions or services) is trusted.

Canisters that manage tradable assets or are otherwise meant to be composed upon by distinct parties in the ecosystem (e.g. ICRC-1 or ICRC-7 canisters),
**MUST** not implement ICRC-28: ICRC-28 privileges the listed entities to potentially act independently on behalf of the signer, which is a security risk in the context of tradable assets and shared infrastructure.
**MUST NOT** implement ICRC-28: ICRC-28 privileges the listed entities to potentially act independently on behalf of the signer, which is a security risk in the context of tradable assets and shared infrastructure.

> **Note:** If an entity is required to act independently on behalf of the signer in the context of tradable assets it is recommended to use an approval flow as specified in [ICRC-2](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md) or https://github.com/dfinity/ICRC/blob/main/ICRCs/ICRC-37/ICRC-37.md.
A trusted relying party carries certain privileges, like for example the ability to request Account Delegations as per [ICRC-34](./icrc_34_delegation.md).

Expand Down Expand Up @@ -70,16 +72,23 @@ relying party:

1. The relying party connects to the signer and requests a delegation with a list of target canisters.
2. For every target canister the signer:
1. Gets the list of trusted origins using the `icrc28_trusted_origins` method.
2. The trusted origins response must be certified and valid:
* The responses must be provided in a valid certificate (
see [Certification](https://internetcomputer.org/docs/current/references/ic-interface-spec#certification))
* The decoded response must not be `null` and match `vec text`.
1. Verifies that the target canister trusts the relying party origin.
1. Gets the list of trusted origins using the `icrc28_trusted_origins` method.
2. The trusted origins response must be certified and valid:
* The responses must be provided in a valid certificate (
see [Certification](https://internetcomputer.org/docs/current/references/ic-interface-spec#certification))
* The decoded response must not be `null` and match `vec text`.
2. Verifies that the target canister does _not_ support standards supporting tradable assets or shared infrastructure.
1. Gets the list of supported standards using the `icrc10_supported_standards` method (and executing it in a replicated fashion).
2. The supported standards response must be certified and valid:
* The responses must be provided in a valid certificate (
see [Certification](https://internetcomputer.org/docs/current/references/ic-interface-spec#certification))
* The listed standards must not include standards supporting tradable assets. In particular, it must not include [ICRC-1](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-1/README.md), [ICRC-2](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md), [ICRC-7](https://github.com/dfinity/ICRC/blob/main/ICRCs/ICRC-7/ICRC-7.md) and [ICRC-37](https://github.com/dfinity/ICRC/blob/main/ICRCs/ICRC-37/ICRC-37.md).
3. The signer verifies that relying party origin is within the trusted origin list of all targets.
* If the origin is trusted by all targets, continue with step 4a.
* If the origin is not trusted by all targets, continue with step 4b.
4a. The signed account delegation is returned to the relying party.
4b. The signed relying party delegation is returned to the relying party.
4. * a) The signed account or relying party delegation (may depend on user choice) is returned to the relying party.
* b) The signed relying party delegation is returned to the relying party.

```mermaid
sequenceDiagram
Expand All @@ -89,12 +98,18 @@ sequenceDiagram
Note over RP, S: Interactions follow ICRC-34 standard
RP ->> S: Request delegation with targets
loop For every target canister
S ->> C: Retrieve supported standards (ICRC-10)
C ->> S: Supported standards
S ->> S: Verify supported standards
S ->> C: Get trusted origins
C ->> S: List of trusted origins
S ->> S: Verify trusted origins
end
alt Origin is trusted by all targets canisters
S ->> RP: Signed account delegation
Note over RP, S: Signer allows Account Delegation<br>or Relying Party Delegation selection
S ->> RP: Signed delegation (Account or RP)
else
S ->> RP: Signed relying party delegation
Note over RP, S: Signer allows only Relying Party Delegation selection
S ->> RP: Signed Relying Party Delegation
end
```
41 changes: 25 additions & 16 deletions topics/icrc_34_delegation.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
<!-- TOC -->
* [ICRC-34: Delegation](#icrc-34-delegation)
* [Summary](#summary)
* [Use-Cases for Account Delegation:](#use-cases-for-account-delegation)
* [Use-Cases for Relying Party Delegation:](#use-cases-for-relying-party-delegation)
* [Method](#method)
* [Scope (according to the ICRC-25 standard)](#scope-according-to-the-icrc-25-standard)
* [Example RPC Permission Request](#example-rpc-permission-request)
Expand All @@ -30,20 +32,26 @@ The delegation chain's stable identifier can be either:
stable across many relying parties but cannot be used to operate on tradable assets and shared infrastructure.
2. **Relying Party Delegation**: an identity created exclusively for the relying party (Relying Party Delegation).

Example use cases of a Relying Party Delegation:
- Signer could give the user a choice to stay anonymous with a service.
- Differentiate between calls made with user approval (Account identifier) and without user approval (Relying Party Delegation identifier), allowing for fine grained security levels per identifier.
- Exclusive identifier within the Relying Party platform to stay isolated from identifiers of other Relying Party platforms.
Relying Party Delegations **MUST** be for identities exclusive to each individual relying party. This property **MUST** be enforced by the signer.
Signers **MAY** give users the choice to authenticate with their relying party specific identifier instead of accounts (if available).

If a relying party wants to receive an Account Delegation, the `icrc34_delegation` request **MUST** include canisters it
controls as `targets` where each canister **MUST** implement the `icrc28_trusted_origins` endpoint as per the
controls as `targets` where each canister **MUST** implement the `icrc28_trusted_origins` endpoint as per the
[ICRC-28](./icrc_28_trusted_origins.md) standard.
Relying parties must not include `targets` in the request if they want to be guaranteed to receive a Relying Party delegation.

Relying Party Delegations **MUST** be for identities exclusive to each individual relying party. This property **MUST** be enforced by the signer.
### Use-Cases for Account Delegation:
- Single identifier for the user that is the same for all relying parties and shared infrastructure, which leads to the following benefits:
- application specific user data can be directly tied to the users global identity without the need for a mapping to an application specific identifier
- easier integration and composition of applications that handle user data

Signers **MAY** give users the choice to authenticate with their relying party specific identifier instead of accounts (if available).
> **Note:** Using the same identifier globally may be detrimental to privacy as user activity can be tracked across applications.
Relying parties must not include `targets` in the request if they want to be guaranteed to receive a Relying Party delegation.
### Use-Cases for Relying Party Delegation:
- Differentiate between calls made with user approval (Account identifier) and without user approval (Relying Party Delegation identifier), allowing for fine grained security levels per identifier.
- Exclusive identifier within the Relying Party platform to stay isolated from identifiers of other Relying Party platforms. Depending on the signer implementation, this may offer privacy benefits.

> **Note:** Using exclusive identifiers within the Relying Party platform may be detrimental to data portability, dapp integration, and composition of applications as user data can not be easily queried across the ecosystem of dapps and services.
## Method

Expand Down Expand Up @@ -154,12 +162,11 @@ the [IC interface specification, authentication section](https://internetcompute

1. The relying party sends a `icrc34_delegation` request to the signer.
2. Upon receiving the request, the signer validates whether it can process the message.
* If the relying party has not been granted the permission to request the action, the signer sends a response with
an error back to the relying party.
* The relying party must make sure that the request complies with scope targets restriction.
- If the relying party has been denied the permission to invoke the method,
the signer sends a response with an error back to the relying party.
If the permission state is `ask_on_use`, the signer must prompt the user to either accept or deny this invocation. See [permission states](icrc_25_signer_interaction_standard.md#permissions-states) for more details.
3. If the request includes targets, the signer **MAY** offer issuing an account delegation. If it does, it **MUST** retrieve and verify the trusted origins according to the [ICRC-28](icrc_28_trusted_origins.md) specification.
* If the trusted origins cannot be retrieved for any of the given delegations targets or the relying party origin is
not within any of the trusted origin lists, the signer does not give users the ability to continue with the Account Delegation.
* If the trusted origins cannot be retrieved for any of the given delegations targets or the relying party origin is not within any of the trusted origin lists, the signer does not give users the ability to continue with the Account Delegation.
4. The signer **MAY** display all the available delegations the user can continue with, in which case a user would select one.
5. The signer returns the signed delegation to the relying party.

Expand All @@ -169,12 +176,14 @@ the [IC interface specification, authentication section](https://internetcompute
participant S as Signer
participant C as Target Canister
RP ->> S: Request delegation
alt Relying party has not been granted <br>the `icrc34_delegation` permission scope<br>or the request does not comply with scope restrictions
alt Relying party has not been granted <br>the `icrc34_delegation` permission scope
S ->> RP: Error response: Permission not granted (3000)
else Requests includes targets and signer supports account delegations
loop For every target canister
S ->> C: Get trusted origins
C ->> S: List of trusted origins
Note over S, C: Interactions follow ICRC-28 standard
S ->> C: Get trusted origins / supported standards
C ->> S: Trusted origins / supported standards
S ->> S: Verify trusted origins / supported standards
end
alt Origin is trusted by all target canisters
Note over RP, S: Signer allows Account Delegation<br>or Relying Party Delegation selection
Expand Down

0 comments on commit bbcc651

Please sign in to comment.