diff --git a/CAIPs/caip-171.md b/CAIPs/caip-171.md index ac5df954..98dce12a 100644 --- a/CAIPs/caip-171.md +++ b/CAIPs/caip-171.md @@ -50,12 +50,13 @@ type SessionIdentifier = string; Properties of the `SessionIdentifier` are as follows: 1. It MUST uniquely identify an open and stateful session. -2. It MUST identify a closeable session, and it MUST become invalid - after a session is closed. +2. It MUST identify a closeable session, and it MUST become invalid after a + session is closed. 3. It MUST remain the same as the identified session's state changes. -4. It MUST be serializable into JSON. Serialization and later deserialization using -JSON MUST result in the same value. -5. It MUST be generated from a cryptographically random source and MUST include at least 96 bits of entropy for security. +4. It MUST be serializable into JSON. Serialization and later deserialization +using JSON MUST result in the same value. +5. It MUST be generated from a cryptographically random source and include at + least 96 bits of entropy for security. ## Copyright diff --git a/CAIPs/caip-211.md b/CAIPs/caip-211.md new file mode 100644 index 00000000..e1120403 --- /dev/null +++ b/CAIPs/caip-211.md @@ -0,0 +1,263 @@ +--- +caip: 211 +title: JSON-RPC Authority Negotiation +author: Hassan Malik (@hmalik88), Juan Caballero (@bumblefudge) +discussions-to: ["https://github.com/ChainAgnostic/CAIPs/pull/207", "https://github.com/ChainAgnostic/CAIPs/pull/211"] +status: Draft +type: Informational +created: 2023-02-02 +updated: 2023-02-02 +requires: [2, 10, 25, 171] +--- + +## Simple Summary + +CAIP-211 defines the behavior and semantics for both implicit and explicit RPC +documents (which define methods and notifications for a given namespace or scope +within one) and RPC endpoints (i.e. preferential routing for specific nodes). + +## Abstract + +Without a profile of this CAIP which defines implicit values for a given +namespace, setting the `rpcDocuments` and `rpcEndpoints` values in the +`scopeObject`s of a [CAIP-25][] negotiation could be seen as a security risk +within that namespace, since either a custom endpoint or a custom re-definition +of a common method or event syntax or semantics would be harder for the +respondent to detect. Once those implicit values have been profiled and +published, however, the meaning of any explicit values in [CAIP-25][] +negotiations or other scope expressions have an explicit baseline making RPC +security postures more deterministic. + +## Motivation + +This deterministic expression of variations in RPC routing and behavior is a +precondition for explicit and informed user consent to be gotten about these +variations, in addition to supporting clarity between the multiple agents +connecting that consenting user to a network. This enables flexible and layered mechanism for +negotiating authorities over routing and RPC method/notification definitions. In +turn, this allows experimentation and extension within certain local contexts +(like a specific network within a namespace, or a specific community of usage of +a network) without compromising the integrity and security of the broader +community. + +## Specification + +### Implicit values + +Many namespaces have a single, authoritative RPC definition (whether +human-readable, machine-readable, or both) and a set of endpoints which can be +considered definitive. Where these can be referred to by a static URI and this +URI is described in a [namespace profile][namespaces] of this CAIP, these static +URIs are the "implicit" endpoint and document values for those namespaces. + +For a given namespace `X`, if the implicit RPC endpoints are `Y1`, `Y2` and +`Y3`, and the implicit RPC document is `Z`, then the scope object + +```jsonc +{ + "X": { + methods: [A, B, C], + notifications: [D, E, F] + } +} +``` + +SHOULD be interpreted as equivalent to the scope object: + +```jsonc +{ + "X": { + methods: [A, B, C], + notifications: [D, E, F], + rpcEndpoints: [Y1, Y2, Y3], + rpcDocuments: [Z] + } +} +``` + +### Explicit values + +Additional values may be set for a given `scopeObject`. + +### Ordering + +In the case of `rpcEndpoints`, priority is contextual and not defined +universally. In the case of `rpcDocuments`, priority is more definitive: each +document after the first MUST only add (and MUST NOT re-define) any terms +already defined, iteratively through the array. + +For this reason, if a namespace has defined stable URIs for default +`rpcDocuments` and `rpcEndpoints`, these SHOULD be defined in a namespace +profile. These implicit values allow extensions and variations from those +defaults to be negotiated, such as by [CAIP-25][] or other discovery protocols. + +In the context of a CAIP-25 negotiation, a requesting party may define explicit +values for `rpcEndpoints` or `rpcDocuments` without including the implicit +values. Extending the example above, we could say that the request: + +```jsonc +{ + "X": { + methods: [A, B, C], + notifications: [D, E, F], + rpcEndpoints: [U1, U2, U3], + rpcDocuments: [V] + } +} +``` +MUST be interpreted as replacing rather than appending to the implicit values. +It MUST NOT be interpreted as equivalent to: + +```jsonc +{ + "X": { + methods: [A, B, C], + notifications: [D, E, F], + rpcEndpoints: [Y1, Y2, Y3, U1, U2, U3], + rpcDocuments: [Z, V] + } +} +``` + +## Security Considerations + +The main security risk in accepting multiple authorities (expressed as URIs, +which may be mutable) is that ambiguity and undesired behavior can arise from +multiple RPC documents defining the same term, or different endpoints producing +different outcomes. The solution to this is to assign priority by array ordering +in the context of negotiation. In a protocol like [CAIP-25][], this means +achieving consensus between parties on the exact priority before initiating a +session. + +### CAIP-25 Example + +Since [CAIP-25][] obligates both parties in an authorization negotiation to +persist and honor whatever `scopeObject`s they agree to, including the ordering +of arrays, it is important to resolve all implicit and explicit members at the +same negotiation step where `requiredScopes` and `optionalScopes` get merged +into the `sessionScopes` both parties will persist. We can illustrate this +resolution and all the possibilities open to a respondent by extending the +examples above, in which a request omits implicit values Y1, Y2, Y3, and Z: + +```jsonc +{ + "requiredScopes": { + "X": { + methods: [A, B, C], + notifications: [D, E, F], + } + }, + "optionalScopes": { + "X": { + methods: [A, B, C], + notifications: [D, E, F], + rpcEndpoints: [U1, U2, U3], + rpcDocuments: [V] + } + }, +} +``` + +Since the ordering of arrays expresses authority or priority in case of +conflicts, we can illustrate three different security postures, explained below: + +```jsonc + +// Security Posture 1: Implicit value prioritized, requested values treated as extensions +{ + ... + "sessionScopes": { + "X": { + methods: [A, B, C], + notifications: [D, E, F], + rpcEndpoints: [Y1, Y2, Y3, U1, U2, U3], + rpcDocuments: [Z, V] + } + } + ... +} + +// Security Posture 2: Explicit prioritized, but implicit values preserved +{ + ... + "sessionScopes": { + "X": { + methods: [A, B, C], + notifications: [D, E, F], + rpcEndpoints: [U1, U2, U3, Y1, Y2, Y3], + rpcDocuments: [V, Z] + } + } + ... +} + +//Security Posture 3: Requested values only, explicit deauthorization of implicit values. +{ + ... + "sessionScopes": { + "X": { + methods: [A, B, C], + notifications: [D, E, F], + rpcEndpoints: [Y1, Y2, Y3], + rpcDocuments: [Z] + } + } + ... +} + +``` + +Option 1 would be the overwhelmingly most common, since implicit values are +essentially the baseline consensus of an entire namespace (i.e. its network-wide +basic RPC vocabulary), and any possible conflict between this and an extension +should be sandboxed by not allowing an extension to override baseline. + +Option 2 would likely be quite rare, as a respondent and/or its controlling +end-user would have to have a lot of out-of-band trust in an extension or local +authority to allow it to override systemwide defaults. This could be thought of +as "advanced mode" or "high-trust mode", and likely only enabled for a subset of +end-users, perhaps negotiated by progressive re-authorization over time. + +Similarly, Option 3 would only make sense in special cases with meaningful +consent of an end-user that knows they are entering a special-case and familiar +UX and security assumptions. It could be thought of as "developer mode" or +"alternate network configuration", and would getting meaningful consent from +the end-user. + +Note that these three options are not exhaustive, just illustrative, and many +combinations are also possible, i.e. combining the `rpcDocuments` in Option 1 +with the `rpcEndpoints` value in Option 2. + +## Privacy Considerations + +The trust model of custom RPC endpoints and/or definition documents is complex +and reputation/discovery systems are still emerging on a per-chain basis in many +ecosystems. For this reason, negotiation protocols like [CAIP-25][] are best +constructive iteratively and progressively to avoid malicious dapps partially +deanonymizing wallets by profiling their support for custom RPCs (e.g., by +"overasking" upfront). For this reason, as with the initial CAIP-25 exchange, +discovery requests rejected due to user input, due to security policy, and due +to non-support at the wallet software level should not be distinguished at the +RPC level. + +## References + +- [CAIP-2][] - Chain ID Specification +- [CAIP-10][] - Account ID Specification +- [CAIP-25][] - JSON-RPC Provider Request +- [CAIP-75][] - Blockchain Reference for the Hedera namespace +- [CAIP-171][] - Session Identifier Specification + +[CAIP-2]: https://chainagnostic.org/CAIPs/caip-2 +[CAIP-10]: https://chainagnostic.org/CAIPs/caip-10 +[CAIP-25]: https://chainagnostic.org/CAIPs/caip-25 +[CAIP-75]: https://chainagnostic.org/CAIPs/caip-75 +[CAIP-104]: https://chainagnostic.org/CAIPs/caip-104 +[CAIP-171]: https://chainagnostic.org/CAIPs/caip-171 +[namespaces]: https://namespaces.chainagnostic.org +[RFC3339]: https://datatracker.ietf.org/doc/html/rfc3339#section-5.6 +[CAIP-170]: https://chainagnostic.org/CAIPs/caip-170 + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE). diff --git a/CAIPs/caip-217.md b/CAIPs/caip-217.md new file mode 100644 index 00000000..62c63521 --- /dev/null +++ b/CAIPs/caip-217.md @@ -0,0 +1,104 @@ +--- +caip: 217 +title: Authorization Scopes +author: Pedro Gomes (@pedrouid), Hassan Malik (@hmalik88), Juan Caballero (@bumblefudge) +discussions-to: ["https://github.com/ChainAgnostic/CAIPs/discussions/217","https://github.com/ChainAgnostic/CAIPs/discussions/211"] +status: Draft +type: Standard +created: 2022-11-09 +--- + +## Simple Summary + +This CAIP defines a simple syntax for scopes of authorization between +applications (e.g. dapps) and user-agents (e.g. "wallets" or signers). These are +expressed as JSON objects as a building block across multiple protocols and +mechanisms, for example: +- A JSON-RPC protocol for persisting and synchronizing authorized sessions + ([CAIP-25][]) +- Routing individual RPC commands to an authorized network ([CAIP-27][]) + +## Motivation + +The layering of today's cryptographic and decentralized systems favors +loosely-coupled combinations of protocols (representated in the CAIPs model as +[namespaces][]), instances or consensus-communities within those protocols +(addressed in the CAIPs model as [CAIP-2][] URNs), and sets of supported RPC +methods and notifications used in those namespaces. Bundling all of these into +an object facilitates unambiguous authorization schemes, including progressive +authorization patterns, feature discovery, authority negotiation (See +[CAIP-211][]) and delegations. + +## Specification + +An authorization scope is represented in JSON as an object which is keyed to a +string that expresses its target network and contains arrays of strings +expressing the various capabilities authorized there. When embedded in any other +JSON context (including the `params` of a JSON-RPC message), the object MUST be +expressed as the value of a property named by the scope string. + +### 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) + +### Definition + +The syntax of a `scopeObject` is as follows: + +```jsonc + + +[scopeString]: { + *scopes: [(chainId)+], + methods: [(method_name)+], + notifications: [(notification_name)+], + *accounts: [(account_id)+] + *rpcDocuments: [(rpcDocument)+], + *rpcEndpoints: [(rpcEndpoint)+] +} +``` + +Where: + +- {`scopeString`} (conditional) = EITHER a namespace identifier string registered in the CASA [namespaces][] registry to authorize multiple chains with identical properties OR a single, valid [CAIP-2][] identifier, i.e., a specific `chain_id` within a namespace. +- `scopes` (conditional) = An array of 0 or more [CAIP-2][] `chainId`s. For each + entry in `scopes`, all the other properties of the `scopeObject` apply, but in + some cases, such as when members of `accounts` are specific to 1 or more + chains in `scopes`, they may be ignored or filtered where inapplicable; + namespace-specific rules for organizing or interpreting properties in + multi-scope MAY be specified in a [namespace-specific profile][namespaces] of + this specification. + - This property MUST NOT be present if the object is already scoped to a single `chainId` in the string value above. + - This property MUST NOT be present if the scope is an entire [namespace][namespaces] in which `chainId`s are not defined. + - This property MAY be present if the scope is an entire [namespace][namespaces] in which `chainId`s are defined. +- `methods` = An array of 0 or more JSON-RPC methods that an application can call on the agent and/or an agent can call on an application. +- `notifications` = An array of 0 or more JSON-RPC notifications that an application send to or expect from the agent. +- `accounts` (optional) = An array of 0 or more [CAIP-10][] identifiers, each valid within the scope of authorization. +- `rpcDocuments` (optional) = An array of URIs that each dereference to an RPC document specifying methods and notifications applicable in this scope. + - These are ordered from most authoritative to least, i.e. methods defined more than once by the union of entries should be defined by their earliest definition only. +- `rpcEndpoints` (optional) = An array of URLs that each dereference to an RPC endpoints for routing requests within this scope. + - These are ordered from most authoritative to least, i.e. priority SHOULD be given to endpoints in the order given, as per the CAIP-211 profile for that [namespace][namespaces], if one has been specified. + +Additional constraints MAY be imposed by the usage of `scopeObject`s in +protocols such as [CAIP-25][], and specific [namespaces][] may have +implicit values or validity constraints for these properties. + +Whenever another CAIP uses the name `scopeObject` and has this CAIP in the +`required` front-matter property, it SHALL be interpreted as reference to this +specification. + +## References + +[CAIP-10]: https://chainAgnostic.org/CAIPs/CAIP-10 +[CAIP-25]: https://chainAgnostic.org/CAIPs/CAIP-25 +[CAIP-27]: https://chainAgnostic.org/CAIPs/CAIP-27 +[CAIP-211]: https://chainAgnostic.org/CAIPs/CAIP-211 +[namespaces]: https://namespaces.chainAgnostic.org/ + +## Copyright + +Copyright and related rights waived via +[CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index 45b5ba38..14dad59e 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -19,68 +19,65 @@ protocol. ## Abstract This proposal has the goal to define a standard procedure for decentralized -applications to interface with cryptocurrency wallets which govern accounts on -multiple chains and defining a set of rules to be followed during a session -managed by a provider construct. +applications to interface with chain agnostic cryptocurrency wallets and other +user agents which govern identities (including accounts) in multiple +cryptographic systems. It defines a lightweight protocol for negotiating and +persisting authorizations during a session managed by a provider construct. ## Motivation The motivation comes from the lack of standardization across blockchains to expose accounts and define the expected JSON-RPC methods to be used by an -application through a provider connecting to a wallet. +application through a provider connecting to a signer or other user agent. ## Specification -The session is defined by a wallet's response to a provider's request, and -updated, extended, closed, etc by successive calls and notifications. The exact -parameters and assumptions of that session abstraction are defined in -[CAIP-171][], but note that a string identifier referring to it is absent from -the initial call (if authorization is granted) and present in both the initial -response and all future responses. - -Given the session model of [CAIP-171][], this interface outlines the -authorization of a provider to handle a set of interfaces grouped into -namespaces, as well as to interact with a session abstraction used by both -caller and respondent to manage the authorization over time. The -`sessionIdentifier` defined in [CAIP-171][] enables this mutual management and -alignment across calls that are idempotent if identical. If a respondent (e.g. a -wallet) needs to initiate a new session, whether due to user input, security -policy, or session expiry reasons, it can simply generate a new session -identifier to signal this notification to the calling provider; if a caller -needs to initiate a new session, it can do so by sending a new request without -`sessionIdentifier`. In such cases, a respondent (e.g. wallet) may choose to -explicitly close all sessions upon generation of a new one from the same origin, -or leave it to time-out; maintaining concurrent sessions is discouraged (see -Security Considerations). - -In the initial call, the application interfaces with a provider to populate a -session with a base state describing authorized chains, methods, notification, -and accounts. This negotation takes place by sending the application's REQUIRED -and REQUESTED authorizations of the session, grouped into objects scoping those -authorizations which in turn are grouped into two top-level objects (named -`requiredScopes` and `optionalScopes` respectively). These two objects are not -mutually exclusive (i.e., additional properties of a required scope may be -requested under the same keyed scope object key in the requested object). Note -that scopes can be keyed to an entire [CAIP-104][] "namespace", meaning -applicable to *any* current or future [CAIP-2][] chainID within that namespace, -or keyed to a specific [CAIP-2][] within that namespace. - -If any properties in the required scope(s) are not authorized by the -respondent (e.g. wallet), a failure response expressive of one or more specific -failure states will be sent (see [#### failure states](#failure-states) below), -with the exception of user denying consent. For privacy reasons, an `undefined` -response (or no response, depending on implementation) should be sent to prevent -incentivizing unwanted requests and to minimize the surface for fingerprinting -of public web traffic (See Privacy Considerations below). +The session is proposed by a caller and the response by the respondent is used +as the baseline for an ongoing session that both parties will persist. The +properties and authorization scopes that make up the session are expected to be +persisted and tracked over time by both parties in a discrete data store, +identified by an entropic [identifier][CAIP-171] assigned in the initial +response. This object gets updated, extended, closed, etc. by successive calls +and notifications, each tagged by this identifier. + +If a respondent (e.g. a wallet) needs to initiate a new session, whether due to +user input, security policy, or session expiry reasons, it can simply generate a +new session identifier to signal this notification to the calling provider; if a +caller needs to initiate a new session, it can do so by sending a new request +without a `sessionIdentifier`. In such cases, a respondent (e.g. wallet) may +choose to explicitly close all sessions upon generation of a new one from the +same origin or identity, or leave it to time-out; maintaining concurrent +sessions is discouraged (see Security Considerations). + +Initial and ongoing authorization requests are grouped into two top-level arrays +of [scopeObjects][CAIP-217], named `requiredScopes` and `optionalScopes` +respectively. These two objects are not mutually exclusive (i.e., additional +properties of a required scope may be requested in a separate `scopeObject` in +the optional array, keyed to the same scope string). Note that `scopeObject`s +can be keyed to a specific [CAIP-2][], or to a [CAIP-104][] namespace; if the +latter defines a [CAIP-2][] profile, a `scopes` array MAY be set within it +containing multiple [CAIP-2][] strings; this is functionally equivalent to +defining multiple identical `scopeObjects`, each keyed to one of the [CAIP-2][]s +listed in the `scopes` array. See [CAIP-217][] for more details on the structure +of the typed objects included in these arrays. + +If any properties in the required scope(s) are not authorized by the respondent, +a failure response expressive of one or more specific failure states will be +sent (see [#### failure states](#failure-states) below), with the exception of +user denying consent. For privacy reasons, an `undefined` response (or no +response, depending on implementation) should be sent to prevent incentivizing +unwanted requests and to minimize the surface for fingerprinting of public web +traffic (See Privacy Considerations below). Conversely, a succesful response will contain all the required properties *and -the provider's choice of the optional properties* expressed as a unified set of -parameters. In the case of identically-keyed scopes appearing in both arrays in -the request where properties from both are returned as authorized, the two -scopes MUST be merged in the response (see examples below). However, respondents -MUST NOT restructure scopes (e.g., by folding properties from a [CAIP2][]-keyed, -chain-specific scope object into a [CAIP-104][]-keyed, namespace-wide scope -object) as this may introduce ambiguities (See Security Considerations below). +the provider's choice of the optional properties* expressed in a single unified +`scopeObject`. In the case of identically-keyed `scopeObject`s appearing in both +arrays in the request where properties from both are returned as authorized, the +two scopes MUST be merged in the response (see examples below). However, +respondents MUST NOT restructure scopes (e.g., by folding properties from a +[CAIP2][]-keyed, chain-specific scope object into a [CAIP-104][]-keyed, +namespace-wide scope object) as this may introduce ambiguities (See Security +Considerations below). ### Request @@ -97,7 +94,7 @@ Example: "params": { "requiredScopes": { "eip155": { - "chains": ["eip155:1", "eip155:137"], + "scopes": ["eip155:1", "eip155:137"], "methods": ["eth_sendTransaction", "eth_signTransaction", "eth_sign", "get_balance", "personal_sign"], "notifications": ["accountsChanged", "chainChanged"] }, @@ -105,6 +102,10 @@ Example: "methods": ["get_balance"], "notifications": ["accountsChanged", "chainChanged"] }, + "wallet": { + "methods": ["wallet_getPermissions", "wallet_switchEthereumChain", "wallet_creds_store", "wallet_creds_verify", "wallet_creds_issue", "wallet_creds_present"], + "notifications": [] + }, "cosmos": { ... } @@ -122,34 +123,29 @@ Example: } ``` -The JSON-RPC method is labelled as `provider_authorize` and its `params` object -contains "requiredScopes" and/or "optionalScopes" objects populated with "scope -objects" each named after the scope of authorization requested: -1. EITHER an entire [CAIP-104][] [namespace][] -2. OR a specific [CAIP-2][]-identified chain in a specific namespace. - -Each scope object contains the following parameters: -- chains - array of [CAIP-2][]-compliant `chainId`'s. This parameter MAY be - omitted if a single-chain scope is already declared in the index of the object. -- methods - array of JSON-RPC methods expected to be used during the session -- notifications - array of JSON-RPC message/notifications expected to be emitted - during the session - -The `requiredScopes` array MUST contain 1 or more of these objects, if present; -the `optionalScopes` array MUST contain 1 or more of them, if present. - -A third object is the `sessionProperties` object, all of whose properties MUST -be in the interpreted as optional, since requesting applications cannot mandate -session variables to providers. Because they are optional, providers MAY respond -with all of the requested properties, or a subset of the session properties, or no -`sessionProperties` object at all; they MAY even replace the values of the -optional session properties with their own values. The `sessionProperties` -object MUST contain 1 or more properties if present. +The JSON-RPC method is labeled as `provider_authorize` and its `params` object +contains "requiredScopes" and/or "optionalScopes" objects populated with +[CAIP-217][] "scope objects" keyed to [CAIP-217][] scope strings. +- The `requiredScopes` array MUST contain 1 or more `scopeObjects`, if present. +- The `optionalScopes` array MUST contain 1 or more `scopeObjects`, if present. -Requesting applications are expected to track all of these returned properties in -the session object identified by the `sessionId`. All properties and their values -MUST conform to definitions in [CAIP-170][], and MUST be ignored (rather than -tracked) if they do not. +A third object is the `sessionProperties` object, all of whose properties MUST +be interpreted as optional, since requesting applications cannot mandate session +variables to providers. Because they are optional, providers MAY respond with +all of the requested properties, or a subset of the session properties, or no +`sessionProperties` object at all; they MAY even replace the values of the +optional session properties with their own values. Wallets may also interpret +values of sessionProperties in how it assigns values (for example, which +`accounts` to expose) based on flags or properties defined here. The +`sessionProperties` object MUST contain 1 or more properties if present. + +Requesting applications are expected to persisted all of these returned +properties in the session object identified by the `sessionId`. All properties +in `sessionProperties` and their values MUST conform to definitions in +[CAIP-170][], and MUST be ignored (rather than persisted) if they do not; +similarly, nothing except valid [CAIP-217][] objects may be present in +`requiredScopes`, `optionalScopes`, and `sessionScopes` arrays; all other +array members should be dropped. ### Response @@ -160,22 +156,19 @@ The wallet can respond to this method with either a success result or an error m The successful result contains one mandatory string (keyed as `sessionId` with a value conformant to [CAIP-171][]) and two session objects, both mandatory and non-empty. -The first is called `sessionScopes` and contains 1 or more scope objects. -* All required scope objects and all, none, or some of the optional scope object -(at the discretion of the provider) MUST be included if successful. -* As in the request, each scope object object MUST contain `methods` and -`notifications` objects, and a `chains` object if a specific chain is not -specified in the object's index. +The first is called `sessionScopes` and contains 1 or more `scopeObjects`. +* All required `scopeObjects` and all, none, or some of the optional +`scopeObject`s (at the discretion of the provider) MUST be included if +successful. * Unlike the request, each scope object MUST also contain an `accounts` array, -containing 0 or more [CAIP-10][] conformant accounts authorized for the session -and valid in the namespace and chain(s) authorized by the scope object they are -in. Additional constraints on the accounts authorized for a given session MAY be -specified in the corresponding [CAIP-104][] namespaces specification. +containing 0 or more [CAIP-10][]-conformant accounts authorized for the session +and valid in that scope. Additional constraints on the accounts authorized for a +given session MUST be applied conformant to the namespace's [CAIP-10][] profile, +if one has been specified. A `sessionProperties` object MAY also be present, and its contents MAY correspond to the properties requested in the response or not (at the discretion -of the provider) but MUST conform to the property names and value constraints -described in [CAIP-170][]; any other MUST be dropped by the requester. +of the provider). An example of a successful response follows: @@ -201,6 +194,11 @@ An example of a successful response follows: "methods": ["personal_sign"], "notifications": ["accountsChanged", "chainChanged"], "accounts":["eip155:42161:0x0910e12C68d02B561a34569E1367c9AAb42bd810"] + }, + "wallet": { + "methods": ["wallet_getPermissions", "wallet_switchEthereumChain", "wallet_creds_store", "wallet_creds_verify", "wallet_creds_issue", "wallet_creds_present"], + "notifications": [] + }, "cosmos": { ... } @@ -294,9 +292,10 @@ friction and user experience problems in the case of malformed requests. * code = 5301 * message = "Session Properties can only be optional and global" -Note: respondents are RECOMMENDED to implement support for core RPC Documents -per each supported namespace to avoid sending error messages 5201 and 5202 in -cases where 0, 5101 or 5102 would be more appropriate. +Note: respondents SHOULD to implement support for core RPC Documents per each +supported namespace to avoid sending error messages 5201 and 5202 in cases where +0, 5101 or 5102 would be more appropriate. Failure to do so may leak versioning +or feature-completeness information to a malicious or fingerprinting caller. ## Security Considerations @@ -319,9 +318,9 @@ deanonymize browsers and/or wallets deductively based on response times, error codes, etc. To minimize this risk, and to minimize the data (including behavioral data) leaked by responses to potentially malicious CAIP-25 calls, respondents are recommended to ignore calls -1. which the respondent does not authorize, -2. which are rejected by policy, or -3. requests which are rejected for unknown reasons. +1. which the respondent explicitly does not authorize, +2. which are rejected automatically or by policy, or +3. which are rejected for unknown reasons. "Ignoring" these calls means responding to all three in a way that is *indistinguishable* to a malicious caller or observer which might deduce @@ -354,6 +353,7 @@ was in violation of policy). ## Changelog +- 2023-03-29: refactored out scopeObject syntax as separate CAIP-217, simplified - 2022-11-26: add mandatory indexing by session identifier (i.e. CAIP-171 requirement) - 2022-10-26: Addressed Berlin Gathering semantics issues and params syntax; consolidated variants across issues and forks post-Amsterdam Gathering @@ -363,18 +363,18 @@ was in violation of policy). - [CAIP-2][] - Chain ID Specification - [CAIP-10][] - Account ID Specification - [CAIP-25][] - JSON-RPC Provider Request -- [CAIP-75][] - Blockchain Reference for the Hedera namespace -- [CAIP-171][] - Session Identifier Specification +- [CAIP-171][] - Session Identifier, i.e. syntax and usage of `sessionId`s +- [CAIP-217][] - Authorization Scopes, i.e. syntax for `scopeObject`s [CAIP-2]: https://chainagnostic.org/CAIPs/caip-2 [CAIP-10]: https://chainagnostic.org/CAIPs/caip-10 [CAIP-25]: https://chainagnostic.org/CAIPs/caip-25 -[CAIP-75]: https://chainagnostic.org/CAIPs/caip-75 [CAIP-104]: https://chainagnostic.org/CAIPs/caip-104 +[CAIP-170]: https://chainagnostic.org/CAIPs/caip-170 [CAIP-171]: https://chainagnostic.org/CAIPs/caip-171 +[CAIP-217]: https://chainagnostic.org/CAIPs/caip-217 [namespaces]: https://namespaces.chainagnostic.org [RFC3339]: https://datatracker.ietf.org/doc/html/rfc3339#section-5.6 -[CAIP-170]: https://chainagnostic.org/CAIPs/caip-170 ## Copyright diff --git a/CAIPs/caip-27.md b/CAIPs/caip-27.md index 76a5db12..265ae83b 100644 --- a/CAIPs/caip-27.md +++ b/CAIPs/caip-27.md @@ -1,51 +1,66 @@ --- caip: 27 title: JSON-RPC Provider Request -author: Pedro Gomes (@pedrouid) +author: Pedro Gomes (@pedrouid), Hassan Malik (@hmalik88) discussions-to: https://github.com/ChainAgnostic/CAIPs/pull/27 status: Draft type: Standard created: 2020-12-12 -updated: 2022-11-16 -requires: ["2", "25", "171"] +updated: 2023-03-02 +requires: ["2", "25", "171", "217"] --- ## Simple Summary -CAIP-27 defines a standard JSON-RPC method for requesting methods mapped to a -target chain. +CAIP-27 defines a generic JSON-RPC method for routing method calls to a context +defined by a valid [scopeObject][CAIP-217] and a tagged with a +[sessionId][CAIP-171] for maintaining session continuity. ## Abstract This proposal has the goal to define a standard method for decentralization -applications to request JSON-RPC methods from cryptocurrency wallets directed to -a given target chain. +applications to request JSON-RPC methods from user agents (such as +cryptocurrency wallets) directed to a given previously-authorized target network +(such as a specific blockchain or consensus community within a protocol). It +requires a valid [scopeObject][CAIP-217] and a valid [sessionId][CAIP-171] for +interoperability and composability. These two properties MAY be inherited from a +persistent session created by [CAIP-25][], but could also be used as part of +session management mechanisms. ## Motivation -The motivation comes from the ambiguity that comes from interfacing with -multi-chain cryptocurrency wallets which may support the same methods for -different chains and there is no indication of the chain that is being targeted -by the decentralized application. +The motivation comes from the ambiguity that comes from interfacing with a +multi-network agent (e.g. a cryptocurrency wallets which supports the same +method on multiple chains in a namespace, or supports methods with the same name +on multiple namespaces). ## Specification +### 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][] + +### Definition + The JSON-RPC provider is able to make one or more JSON-RPC requests accompanied -by a [CAIP-2][] compatible `chainId` and a keyed to a specific [CAIP-171][] -session. +by a [CAIP-2][] compatible `chainId` and a keyed to the [sessionId][CAIP-171] of +a pre-existing session. ### Request -The application would interface with a provider to make request as follows: +The application would interface with an RPC provider to make request as follows: ```jsonc { "id": 1, "jsonrpc": "2.0", - "method": "caip_request", + "method": "provider_request", "params": { - "chainId": "eip155:1", - "session": "0xdeadbeef", + "sessionId": "0xdeadbeef", + "scope": "eip155:1", "request": { "method": "personal_sign", "params": [ @@ -57,26 +72,47 @@ The application would interface with a provider to make request as follows: } ``` -The JSON-RPC method is labelled as `caip_request` and expects three parameters: - -- chainId - [CAIP-2][]-defined `chainId` to identify both a namespace and a - specific chain or network within it -- session - [CAIP-171][] `SessionToken` to identify the session opened or - updated by a [CAIP-25][] interaction. -- request - an object containing the fields: - - method - JSON-RPC method to request - - params - JSON-RPC parameters to request +The JSON-RPC method is labeled as `provider_request` and expects +three **required parameters**: + +- **sessionId** - [CAIP-171][] `SessionId` referencing a known, open session +- **scope** - a valid `scopeObject` previously authorized to the caller and persisted in + the session identified by `sessionId` +- **request** - an object containing the fields: + - **method** - JSON-RPC method to request + - **params** - JSON-RPC parameters to request (may be empty but must be set) + +### Validation + +1. A respondent MUST check the `scope` against the identified session object + before executing or responding to such a request, and invalidate a request + for a scope not already authorized and persisted. +2. The respondent SHOULD check that `request.method` is authorized in the + session object for that specific scope. +3. The respondent MAY check that the `params` are valid for that method, if its + syntax is known to it. +4. The respondent MAY apply other logic or validation. +5. The respondent MAY chose to drop invalid requests or return an error message, + but it MUST NOT route or submit them. ### Response -The wallet will respond to the requested with the targeted chain connection and -it will return a response with a success result or error message. +Upon succesful validation, the respondent will submit or route the request to +the targeted network. If the targeted network returns a response to the +respondent, the respondent MAY forward this response to the caller. Constraints +on, metadata about, or envelopes for response-forwarding MAY be set by namespace +profiles of this CAIP. + +Similarly, error messages depend on the design of a given namespace, and MAY be +defined by a namespace profile of this CAIP. ## Links [CAIP-2]: https://chainagnostic.org/CAIPs/caip-2 [CAIP-25]: https://chainagnostic.org/CAIPs/caip-25 [CAIP-171]: https://chainagnostic.org/CAIPs/caip-171 +[CAIP-217]: https://chainagnostic.org/CAIPs/caip-217 +[RFC 2119]: https://www.ietf.org/rfc/rfc2119.txt ## Copyright