-
Notifications
You must be signed in to change notification settings - Fork 229
Decouple CAIP-27 from CAIP-25 and introduce CAIP-217 for Authorization Scopes #217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
d75e96d
4c4ae73
be1aa1c
95c5268
407691f
2e54eaa
aa9506d
ac80b88
e79a945
0ef0acc
03884a6
9300226
c1aaf10
f3cb8fc
66b56ff
859551d
d92e474
48e0e3d
01459af
555c005
7f4801b
5afcb22
0e72bb6
0fea9db
8a92f2b
5076373
1037853
96e7760
5097a2d
0de8414
e45f802
5fcdf9b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| --- | ||
| 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 namespace, | ||
| setting the `rpcDocuments` and `rpcEndpoints` values in the `scopeObject`s of a | ||
| [CAIP-25][] negotiation does not make much sense. Once those implicit values | ||
| have been set, however, the meaning of any explicit values in [CAIP-25][] | ||
| negotiations or other scope expressions can be deterministic and evolve over | ||
| time. | ||
|
|
||
| ## Motivation | ||
|
|
||
| Allowing 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 requires a flexible and layer mechanism for negotiating authorities | ||
| over routing and RPC method/notification definitions. | ||
|
|
||
| ## 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 taken literally, as dropping the implicit values rather than appending | ||
| to them. 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] | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| But the latter SHOULD be returned as response if dropping the implicit values in | ||
| favor of the requested ones is unacceptable and extending the implicit values is | ||
| preferred. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need to think about this a bit more. Points I agree with:
Points that are unclear:
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unclear # 1: by unacceptable, I meant "allowed to extend e.g. execution APIs but I neither want to allow your documents to contradict/re-define execution APIs NOR do I want to manually confirm each connection that your documents don't contradict/redefine. I can either make this more explicit in another commit... or change course if it's a faulty use-case assumption! Unclear # 2: it's extraneous if it's in every request, in the sense that it verbosely states the obvious, but I wouldn't drop it from my responses to those verbose requests if I was a provider! what a CAIP-211 profile does is give additional confidence to the providers who want to interpret no setting as equivalent to execution-apis, and let them respond without adding it. I guess I was assuming legacy verbosity would be tolerable and just peter out over time harmlessly?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unclear # a: I was assuming whole RPC document -- if machine-readable, "subsetting" that document or extracting, say, ABI signatures for function names can happen automatically, if human-readable (a permalink to a namespace's official dev docs, for example), this might be a little more onerous...
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This should just be a rejected request then.
Ok that's fair. In the scenario that a dapp is requesting some implicit methods, it should also then provide documents for those methods until as you said legacy verbosity peters out over time. We would also then naturally return said documents in the response to maintain this statefulness through the chain of events idea we spoke about.
You're right, the openRPC document is JSON, so yes we can certainly return a subset of the document.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
OK I'll push another commit aligned with this different behavior.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Cool, we should use this discussion to further explain what's going on and provide context for the code example. |
||
|
|
||
| ## 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). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| --- | ||
| 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 a string that expresses its | ||
| scope and a JSON object defining the bundle of properties 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 is as follows: | ||
|
|
||
| ```jsonc | ||
|
|
||
| scope: string | ||
|
|
||
| scopeObject: { | ||
| *scopes: [(chainId)+], | ||
| methods: [(method_name)+], | ||
| notifications: [(notification_name)+], | ||
| *accounts: [(account_id)+] | ||
| *rpcDocuments: [(rpcDocument)+], | ||
| *rpcEndpoints: [(rpcEndpoint)+] | ||
| } | ||
| ``` | ||
|
|
||
| Where: | ||
|
|
||
| - `string` (conditional) = 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. | ||
|
bumblefudge marked this conversation as resolved.
Outdated
|
||
| - `scopes` (conditional) = An array of 0 or more [CAIP-2][] `chainId`s. Setting multiple `scopes` is equivalent to making multiple copies of the `scopeObject` for each member of `scopes`, simply in compact form. | ||
|
bumblefudge marked this conversation as resolved.
Outdated
|
||
| - 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. | ||
|
bumblefudge marked this conversation as resolved.
|
||
| - `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/). | ||
Uh oh!
There was an error while loading. Please reload this page.