From 28cac41c03bf6cd5b23b5c27baa252c4e8968bc7 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 19 Oct 2023 10:50:45 +0200 Subject: [PATCH 1/8] Initial draft --- SIPS/sip-14.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 SIPS/sip-14.md diff --git a/SIPS/sip-14.md b/SIPS/sip-14.md new file mode 100644 index 0000000..7464feb --- /dev/null +++ b/SIPS/sip-14.md @@ -0,0 +1,70 @@ +--- +sip: 14 +title: Dynamic Permissions +status: Draft +discussions-to: +author: Frederik Bolding (@frederikbolding) +created: 2023-10-19 +--- + +## Abstract + +This SIP proposes changes to the snap manifest and new RPC methods that would allow snap developers to request additional permissions dynamically at runtime. This proposal outlines some of the details around this feature. + +## Motivation + +Snaps currently have to request all permissions that they plan to use at install-time. This becomes a problem when a snap wants to use many permissions as the installation experience suffers and the user has to either accept all permissions requested or deny the installation. This proposal provides an improvement to the experience by letting snaps request permissions at run-time as long as those permissions are statically defined in the manifest at build-time. + +## Specification + +> Formal specifications are written in Typescript. Usage of `CAIP-N` specifications, where `N` is a number, are references to [Chain Agnostic Improvement Proposals](https://github.com/ChainAgnostic/CAIPs). + +### Language + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and +"OPTIONAL" written in uppercase in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) + +### Snap Manifest + +This SIP adds a new field to the snap manifest called `dynamicPermissions`. +This field can be used in tandem with the existing `initialPermissions`, but keep in mind that permissions in this field are not granted by installation, they MUST be requested when needed. + +The new field can be specified as follows in a `snap.manifest.json` file: + +```json +{ + "initialPermissions": { + "endowment:transaction-insight": {} + }, + "dynamicPermissions": { + "snap_dialog": {} + } +} +``` + +### RPC Methods + +This SIP also proposes new RPC methods to manage these new permissions: + +#### snap_requestPermissions +This RPC method SHOULD function as a subset of the existing `wallet_requestPermissions` RPC method and take the same parameters and have the same return value. This function MAY be a middleware that rewrites requests to `wallet_requestPermissions` if needed. + +This RPC method MUST prompt the user to get consent for any requested permissions and MUST validate that the requested permissions are specified in the manifest before continuing its execution. + +#### snap_getPermissions +This RPC method SHOULD be an alias for `wallet_getPermissions`, MAY be used by the snap for verifying whether it already has the permissions needed for operating. The return value and parameters SHOULD match the existing specification. + +#### snap_revokePermissions +The RPC method parameters and return value are TBD. + +Note: This RPC method does not currently have a `wallet_` counterpart. Coordinate with dapp API team as they may be shipping one. + +This RPC method MUST validate that the permissions requested to be revoked does not contain or overlap with the `initialPermissions`. + +### Permission Caveats +TBD + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE). From 257e6b4466a9bd54c19aba7caaeaef4ba3906e89 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 19 Oct 2023 11:10:49 +0200 Subject: [PATCH 2/8] Add section on permission caveats --- SIPS/sip-14.md | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/SIPS/sip-14.md b/SIPS/sip-14.md index 7464feb..7ed44b6 100644 --- a/SIPS/sip-14.md +++ b/SIPS/sip-14.md @@ -38,11 +38,25 @@ The new field can be specified as follows in a `snap.manifest.json` file: "endowment:transaction-insight": {} }, "dynamicPermissions": { - "snap_dialog": {} + "snap_dialog": {}, + "snap_getBip44Entropy": [ + { + "coinType": 1 + }, + { + "coinType": 3 + } + ] } } ``` +### Permission caveats and merging + +In this initial version, duplicated permissions in `initialPermissions` and `dynamicPermissions` MUST NOT be allowed. A permission MUST only be able to exist in one of the manifest fields. + +Furthermore, permissions specified in `dynamicPermissions` MUST contain the caveats that will be requested at runtime and the permission request MUST fully match the caveats specified in the manifest. + ### RPC Methods This SIP also proposes new RPC methods to manage these new permissions: @@ -50,7 +64,7 @@ This SIP also proposes new RPC methods to manage these new permissions: #### snap_requestPermissions This RPC method SHOULD function as a subset of the existing `wallet_requestPermissions` RPC method and take the same parameters and have the same return value. This function MAY be a middleware that rewrites requests to `wallet_requestPermissions` if needed. -This RPC method MUST prompt the user to get consent for any requested permissions and MUST validate that the requested permissions are specified in the manifest before continuing its execution. +This RPC method MUST prompt the user to get consent for any requested permissions and MUST validate that the requested permissions are specified in the manifest before continuing its execution (including caveats matching). #### snap_getPermissions This RPC method SHOULD be an alias for `wallet_getPermissions`, MAY be used by the snap for verifying whether it already has the permissions needed for operating. The return value and parameters SHOULD match the existing specification. @@ -62,9 +76,6 @@ Note: This RPC method does not currently have a `wallet_` counterpart. Coordinat This RPC method MUST validate that the permissions requested to be revoked does not contain or overlap with the `initialPermissions`. -### Permission Caveats -TBD - ## Copyright Copyright and related rights waived via [CC0](../LICENSE). From 3cc9db36fa55f3911a6056e197732d3cbf8a558c Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 19 Oct 2023 11:32:12 +0200 Subject: [PATCH 3/8] Apply suggestions from code review Co-authored-by: Maarten Zuidhoorn --- SIPS/sip-14.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/SIPS/sip-14.md b/SIPS/sip-14.md index 7ed44b6..11084fb 100644 --- a/SIPS/sip-14.md +++ b/SIPS/sip-14.md @@ -9,11 +9,11 @@ created: 2023-10-19 ## Abstract -This SIP proposes changes to the snap manifest and new RPC methods that would allow snap developers to request additional permissions dynamically at runtime. This proposal outlines some of the details around this feature. +This SIP proposes changes to the Snap manifest and new RPC methods that would allow Snap developers to request additional permissions dynamically at runtime. This proposal outlines some of the details around this feature. ## Motivation -Snaps currently have to request all permissions that they plan to use at install-time. This becomes a problem when a snap wants to use many permissions as the installation experience suffers and the user has to either accept all permissions requested or deny the installation. This proposal provides an improvement to the experience by letting snaps request permissions at run-time as long as those permissions are statically defined in the manifest at build-time. +Snaps currently have to request all permissions that they plan to use at install-time. This becomes a problem when a Snap wants to use many permissions as the installation experience suffers and the user has to either accept all permissions requested or deny the installation. This proposal provides an improvement to the experience by letting Snaps request permissions at run-time as long as those permissions are statically defined in the manifest at build-time. ## Specification @@ -27,8 +27,8 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", ### Snap Manifest -This SIP adds a new field to the snap manifest called `dynamicPermissions`. -This field can be used in tandem with the existing `initialPermissions`, but keep in mind that permissions in this field are not granted by installation, they MUST be requested when needed. +This SIP adds a new field to the Snap manifest called `dynamicPermissions`. +This field can be used in tandem with the existing `initialPermissions`, but keep in mind that permissions in this field are not granted by installation: They MUST be requested when needed. The new field can be specified as follows in a `snap.manifest.json` file: @@ -59,17 +59,20 @@ Furthermore, permissions specified in `dynamicPermissions` MUST contain the cave ### RPC Methods -This SIP also proposes new RPC methods to manage these new permissions: +This SIP proposes the following RPC methods to manage the dynamic permissions: #### snap_requestPermissions -This RPC method SHOULD function as a subset of the existing `wallet_requestPermissions` RPC method and take the same parameters and have the same return value. This function MAY be a middleware that rewrites requests to `wallet_requestPermissions` if needed. + +This RPC method SHOULD function as a subset of the existing `wallet_requestPermissions` RPC method and take the same parameters and have the same return value. This RPC method MUST prompt the user to get consent for any requested permissions and MUST validate that the requested permissions are specified in the manifest before continuing its execution (including caveats matching). #### snap_getPermissions + This RPC method SHOULD be an alias for `wallet_getPermissions`, MAY be used by the snap for verifying whether it already has the permissions needed for operating. The return value and parameters SHOULD match the existing specification. #### snap_revokePermissions + The RPC method parameters and return value are TBD. Note: This RPC method does not currently have a `wallet_` counterpart. Coordinate with dapp API team as they may be shipping one. From 43488f753c42e71d3789dc8329ea89eb671b39fd Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 19 Oct 2023 11:33:31 +0200 Subject: [PATCH 4/8] Small additions --- SIPS/sip-14.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SIPS/sip-14.md b/SIPS/sip-14.md index 11084fb..0f56a2d 100644 --- a/SIPS/sip-14.md +++ b/SIPS/sip-14.md @@ -28,7 +28,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", ### Snap Manifest This SIP adds a new field to the Snap manifest called `dynamicPermissions`. -This field can be used in tandem with the existing `initialPermissions`, but keep in mind that permissions in this field are not granted by installation: They MUST be requested when needed. +This field can be used in tandem with the existing `initialPermissions`, but keep in mind that permissions in this field are not granted by installation: They MUST be requested when needed. The field follows the same format as `initialPermissions`. The new field can be specified as follows in a `snap.manifest.json` file: @@ -57,6 +57,8 @@ In this initial version, duplicated permissions in `initialPermissions` and `dyn Furthermore, permissions specified in `dynamicPermissions` MUST contain the caveats that will be requested at runtime and the permission request MUST fully match the caveats specified in the manifest. +This MAY change in a future SIP. + ### RPC Methods This SIP proposes the following RPC methods to manage the dynamic permissions: From 8f689dafa4976de94b97005f4d6dd0b9933bd261 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 26 Oct 2023 13:55:47 +0200 Subject: [PATCH 5/8] Add discussions link --- SIPS/sip-14.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SIPS/sip-14.md b/SIPS/sip-14.md index 0f56a2d..dde1f0e 100644 --- a/SIPS/sip-14.md +++ b/SIPS/sip-14.md @@ -2,7 +2,7 @@ sip: 14 title: Dynamic Permissions status: Draft -discussions-to: +discussions-to: https://github.com/MetaMask/SIPs/discussions/114 author: Frederik Bolding (@frederikbolding) created: 2023-10-19 --- From a630e9375e9f0474f32582d65144d4f631f8ccfb Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 2 Nov 2023 13:43:24 +0100 Subject: [PATCH 6/8] Update revokePermissions spec --- SIPS/sip-14.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/SIPS/sip-14.md b/SIPS/sip-14.md index dde1f0e..c794765 100644 --- a/SIPS/sip-14.md +++ b/SIPS/sip-14.md @@ -75,9 +75,32 @@ This RPC method SHOULD be an alias for `wallet_getPermissions`, MAY be used by t #### snap_revokePermissions -The RPC method parameters and return value are TBD. +This RPC method SHOULD take a similar input to `wallet_requestPermissions`, an object keyed with permission names, where the values may contain caveats if applicable. -Note: This RPC method does not currently have a `wallet_` counterpart. Coordinate with dapp API team as they may be shipping one. +For example: + +```json +{ + "method": "snap_revokePermissions", + "params": { + "snap_getBip32Entropy": { + "caveats": [ + { + "type": "permittedDerivationPaths", + "value": [ + { "path": ["m", "44'", "60'"], "curve": "secp256k1" }, + { "path": ["m", "0'", "0'"], "curve": "ed25519" } + ] + } + ] + } + } +} +``` + +The caveat information passed SHOULD be ignored in the initial implementation of this. Instead of processing the caveats, the implementation SHOULD revoke the entire permission key. We will revisit this at a later time to make it more granular. + +This RPC method SHOULD return `null` if the permissions are revoked successfully and otherwise throw. This RPC method MUST validate that the permissions requested to be revoked does not contain or overlap with the `initialPermissions`. From 4386519a68beb7e2362978abfca00666be6f7c07 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Tue, 5 Dec 2023 14:13:15 +0100 Subject: [PATCH 7/8] Apply suggestions from code review Co-authored-by: Maarten Zuidhoorn --- SIPS/sip-14.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/SIPS/sip-14.md b/SIPS/sip-14.md index c794765..f9503e1 100644 --- a/SIPS/sip-14.md +++ b/SIPS/sip-14.md @@ -9,15 +9,15 @@ created: 2023-10-19 ## Abstract -This SIP proposes changes to the Snap manifest and new RPC methods that would allow Snap developers to request additional permissions dynamically at runtime. This proposal outlines some of the details around this feature. +This SIP proposes changes to the Snap manifest and new RPC methods that allows Snap developers to request additional permissions dynamically at runtime. This proposal outlines some of the details around this feature. ## Motivation -Snaps currently have to request all permissions that they plan to use at install-time. This becomes a problem when a Snap wants to use many permissions as the installation experience suffers and the user has to either accept all permissions requested or deny the installation. This proposal provides an improvement to the experience by letting Snaps request permissions at run-time as long as those permissions are statically defined in the manifest at build-time. +Snaps currently have to request all permissions that they plan to use at install-time. This becomes a problem when a Snap wants to use many permissions as the installation experience suffers and the user has to either accept all permissions requested, or deny the installation. This proposal provides an improvement to the experience by letting Snaps request permissions at runtime as long as those permissions are statically defined in the manifest at build-time. ## Specification -> Formal specifications are written in Typescript. Usage of `CAIP-N` specifications, where `N` is a number, are references to [Chain Agnostic Improvement Proposals](https://github.com/ChainAgnostic/CAIPs). +> Formal specifications are written in Typescript. ### Language @@ -28,7 +28,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", ### Snap Manifest This SIP adds a new field to the Snap manifest called `dynamicPermissions`. -This field can be used in tandem with the existing `initialPermissions`, but keep in mind that permissions in this field are not granted by installation: They MUST be requested when needed. The field follows the same format as `initialPermissions`. +This field can be used in tandem with the existing `initialPermissions`, but permissions in this field are not granted by installation: They MUST be requested when needed. The field follows the same format as `initialPermissions`. The new field can be specified as follows in a `snap.manifest.json` file: @@ -51,9 +51,9 @@ The new field can be specified as follows in a `snap.manifest.json` file: } ``` -### Permission caveats and merging +### Permission caveats -In this initial version, duplicated permissions in `initialPermissions` and `dynamicPermissions` MUST NOT be allowed. A permission MUST only be able to exist in one of the manifest fields. +Duplicated permissions in `initialPermissions` and `dynamicPermissions` MUST NOT be allowed. A permission MUST only be able to exist in one of the manifest fields. Furthermore, permissions specified in `dynamicPermissions` MUST contain the caveats that will be requested at runtime and the permission request MUST fully match the caveats specified in the manifest. @@ -67,11 +67,12 @@ This SIP proposes the following RPC methods to manage the dynamic permissions: This RPC method SHOULD function as a subset of the existing `wallet_requestPermissions` RPC method and take the same parameters and have the same return value. -This RPC method MUST prompt the user to get consent for any requested permissions and MUST validate that the requested permissions are specified in the manifest before continuing its execution (including caveats matching). +This RPC method MUST prompt the user to get consent for any requested permissions and MUST validate that the requested permissions are specified in the manifest before continuing its execution (including matching caveats). + #### snap_getPermissions -This RPC method SHOULD be an alias for `wallet_getPermissions`, MAY be used by the snap for verifying whether it already has the permissions needed for operating. The return value and parameters SHOULD match the existing specification. +This RPC method SHOULD be an alias for `wallet_getPermissions`, and MAY be used by the Snap for verifying whether it already has the permissions needed for operating. The return value and parameters SHOULD match the existing specification. #### snap_revokePermissions @@ -102,7 +103,7 @@ The caveat information passed SHOULD be ignored in the initial implementation of This RPC method SHOULD return `null` if the permissions are revoked successfully and otherwise throw. -This RPC method MUST validate that the permissions requested to be revoked does not contain or overlap with the `initialPermissions`. +This RPC method MUST validate that the permissions to be revoked do not contain any permissions specified in `initialPermissions`. Only `dynamicPermissions` can be revoked. ## Copyright From 6f9b1416f75cecf2927eef7e30a1df617e60b820 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Tue, 5 Dec 2023 14:25:52 +0100 Subject: [PATCH 8/8] Address more PR comments --- SIPS/sip-14.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SIPS/sip-14.md b/SIPS/sip-14.md index f9503e1..61210ff 100644 --- a/SIPS/sip-14.md +++ b/SIPS/sip-14.md @@ -65,14 +65,14 @@ This SIP proposes the following RPC methods to manage the dynamic permissions: #### snap_requestPermissions -This RPC method SHOULD function as a subset of the existing `wallet_requestPermissions` RPC method and take the same parameters and have the same return value. +This RPC method SHOULD function as a subset of the existing `wallet_requestPermissions` RPC method (as defined in [EIP-2255](https://eips.ethereum.org/EIPS/eip-2255)) and take the same parameters and have the same return value. This RPC method MUST prompt the user to get consent for any requested permissions and MUST validate that the requested permissions are specified in the manifest before continuing its execution (including matching caveats). #### snap_getPermissions -This RPC method SHOULD be an alias for `wallet_getPermissions`, and MAY be used by the Snap for verifying whether it already has the permissions needed for operating. The return value and parameters SHOULD match the existing specification. +This RPC method SHOULD be an alias for `wallet_getPermissions`, and MAY be used by the Snap for verifying whether it already has the permissions needed for operating. The return value and parameters SHOULD match the existing specification defined in [EIP-2255](https://eips.ethereum.org/EIPS/eip-2255). #### snap_revokePermissions @@ -101,7 +101,7 @@ For example: The caveat information passed SHOULD be ignored in the initial implementation of this. Instead of processing the caveats, the implementation SHOULD revoke the entire permission key. We will revisit this at a later time to make it more granular. -This RPC method SHOULD return `null` if the permissions are revoked successfully and otherwise throw. +This RPC method SHOULD return `null` if the permissions are revoked successfully, or return an error otherwise. This RPC method MUST validate that the permissions to be revoked do not contain any permissions specified in `initialPermissions`. Only `dynamicPermissions` can be revoked.