-
Notifications
You must be signed in to change notification settings - Fork 18
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
v1.0-rc.1 #173
v1.0-rc.1 #173
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the high level it looks good and improves on some pain points we've experienced. That said, reading this:
- I'm no longer sure what the structure of the UCAN looks like any more perhaps even one example somewhere would help.
- I think imposing certain structure on commands / abilities would really simplify things yet will not prevent anyone to go with a different approach if they choose so, they'll only loose ability to leverage certain tooling that will become possible.
- Given significant changes here, I would be more comfortable calling this 0.20 or something and let it settle before we mark it 1.0 or 1.0-rc
- Document often refers to proof chains, yet leaves a lot of ambiguity what they are. I find that confusing, UCANs without proofs feel more like certificates that you can chain into authorization. I feel like it would be good to either call that out explicitly or avoid referring to proof chains
UCANs (and other forms of PKI) depend on the ambient authority of the owner of each resource. This means that the discharging agent must be able to verify the root ownership at decision time. The rest of the chain in-between is self-certifying. | ||
## Security Considerations | ||
|
||
Each UCAN includes an assertions of what it is allowed to do. "Proofs" are positive evidence (elsewhere called "witnesses") of the possession of rights. They are cryptographically verifiable chains showing that the UCAN issuer either claims to directly own a resource, or that it was delegated to them by some claimed owner. In the most common case, the root owner's ID is the only globally unique identity for the resource. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each UCAN includes an assertions of what it is allowed to do. "Proofs" are positive evidence (elsewhere called "witnesses") of the possession of rights. They are cryptographically verifiable chains showing that the UCAN issuer either claims to directly own a resource, or that it was delegated to them by some claimed owner. In the most common case, the root owner's ID is the only globally unique identity for the resource. | |
Each UCAN includes assertions of what it is allowed to do. "Proofs" are positive evidence (elsewhere called "witnesses") of the possession of rights. They are cryptographically verifiable chains showing that the UCAN issuer either claims to directly own a resource, or that it was delegated to them by some claimed owner. In the most common case, the root owner's ID is the only globally unique identity for the resource. |
"an" looks unneeded here.
|
||
Merging capability authorities MUST follow set semantics, where the result includes all capabilities from the input authorities. Since broader capabilities automatically include narrower ones, this process is always additive. Capability authorities can be combined in any order, with the result always being at least as broad as each of the original authorities. | ||
Unless explicitly stated, the Resource of a UCAN MUST be the Subject. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand where and how any other state of affairs could be explicitly stated? Do you mean
Unless explicitly stated, the Resource of a UCAN MUST be the Subject. | |
Unless all expected recipients of a UCAN will understand how the Subject of a UCAN relates to the Resource being authorized because this relationship is explicitly clarified out-of-band, it can be assumed by all parties that a UCAN's subject is coterminous with the Resource authorized by that UCAN. |
? I assume not, but if you asked me to make that sentence more verbose, this is what I would come up with, which feels like a very wrong guess.
| Issuer | The Principal of the current UCAN. Listed in the `iss` field | | ||
| Owner | A Subject that controls some external resource | | ||
| Principal | An agent identified by DID (listed in a UCAN's `iss` or `aud` field) | | ||
| Revoker | The Issuer listed in a proof chain that revokes a UCAN | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is only one revoker per UCAN, but a chain has any many possible revokers as there are links in the chain, right? This sentence makes it sound like every chain has ONE revoker, rather than one revoker per UCAN/link in a chain.
| Revoker | The Issuer listed in a proof chain that revokes a UCAN | | |
| Revoker | The Issuer of each UCAN listed in a proof chain which revokes that UCAN and subsequent chain | |
| Executor | The Agent that actually performs the action described in an invocation | | ||
| Invoker | A Principal that requests an Executor perform some action that uses the Invoker's authority | | ||
| Issuer | The Principal of the current UCAN. Listed in the `iss` field | | ||
| Owner | A Subject that controls some external resource | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Owner | A Subject that controls some external resource | | |
| Owner | A Subject that controls some external resource | |
| Agent | The general class of entities and principals that interact with a UCAN | | ||
| Audience | The Principal delegated to in the current UCAN. Listed in the `aud` field | | ||
| Executor | The Agent that actually performs the action described in an invocation | | ||
| Invoker | A Principal that requests an Executor perform some action that uses the Invoker's authority | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Invoker | A Principal that requests an Executor perform some action that uses the Invoker's authority | | |
| Invoker | A Principal that requests an Executor perform some action that uses the Invoker's authority | |
|
||
The capability authority is the total rights of the authorization space down to the relevant volume of authorizations. Individual capabilities MAY overlap; the authority is the union. Except for [rights amplification], every unique delegation MUST have equal or narrower capabilities from their delegator. Inside this content space, you can draw a boundary around some resource(s) (their type, identifiers, and paths or children) and their capabilities. | ||
The Issuer (`iss`) and Audience (`aud`) can be conceptualized as the sender and receiver (respectively) of a postal letter. Every UCAN MUST be signed with the private key associated with the DID in the `iss` field. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Issuer (`iss`) and Audience (`aud`) can be conceptualized as the sender and receiver (respectively) of a postal letter. Every UCAN MUST be signed with the private key associated with the DID in the `iss` field. | |
The Issuer (`iss`) and Audience (`aud`) can be conceptualized as the sender and receiver (respectively) of a postal letter. Every UCAN MUST be signed with the private key associated with the DID in the `iss` field. | |
Note that the UCAN system assumes a 1:1 relationship between DID URLs and public keys, and all examples are given using `did:key`, where bare DIDs are resolvable directly and deterministically to single keys. For DID methods that support multiple keys for a given DID, verification-specific [DID URLs using fragment identifiers](https://www.w3.org/TR/did-core/#fragment) MUST be used for `iss` and `aud` values to preserve interoperability; non-key-based `verificationMethod`s MUST NOT be used, for the same reason. |
I think I promised this as a PR over a year ago, I'm realizing as I write this up now 🙈
|
||
In an ideal world, a single algorithm (Ed25519) would be available everywhere. For many historical reasons, P-256 and `secp256k1` are the only practical options for many applications, such as the [WebCrypto API] and many cryptocurrency wallets. A design goal of UCAN is to leverage existing public key infrastructure (PKI), and supporting these three algorithms achieves that goal. Requiring multiple signature types for broad interoperability is not an unusual design choice; for example, [JWT] supports multiple signature algorithms for a similar reason. | ||
|
||
The NIST report on post-quantum computing will also be released in the next few months, so we anticipate a shift to new algorithms in the medium-term. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which report do you mean? "The" report came out in 2016, but I assume you mean a more definitive one?
https://csrc.nist.gov/Projects/post-quantum-cryptography/publications
|
||
For more on this representation, please refer to [canonical collections]. | ||
The Subject and Command fields are REQUIRED. Any non-normative extensions are OPTIONAL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are all policies "non-normative extensions"? are any other fields? OPTIONAL for implementations to handle? Dropped if unknown? I know this is all stated in the delegation spec, but just speaking as a reader, a tiny bit more detail, although redundant, might be helpful here for high-level readers!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, are they "Arguments" now? I am seeing links elsewhere in this document to [Arguments]
but there is no ### Arguments
section (or for that matter a ### Policy
or ### Extensions
section, either!), so probably time to add one.
|
||
The "top" (or "super user") ability MUST be denoted `*`. The top ability grants access to all other capabilities for the specified resource, across all possible namespaces. Top corresponds to an "all" matcher, whereas [delegation] corresponds to "any" in the UCAN chain. The top ability is useful when "linking" agents by delegating all access to resource(s). This is the most powerful ability, and as such it SHOULD be handled with care. | ||
The wildcard ability grants access to all other capabilities for the specified resource, across all possible namespaces. The wildcard ability is useful when "linking" agents by delegating all access to another device controlled by the same user, and that should behave as the same agent. It is extremely powerful, and should be used with care. Among other things, it permits the delegate to update a Subject's mutable DID document (change their private keys), revoke UCAN delegations, and use any resources delegated to the Subject by others. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm sorry what's this about a DID Document? that is an implementation detail (there's nothing about DID documents inherent to the UCAN spec, is there?), yet it is stated as a generality... i'd remove, or at least phrase as a possible example...
|
||
# 6. Validation | ||
The `/ucan` Command namespace MUST be reserved. This MUST include any ability string matching the regex `^ucan\/.*`. This is important for keeping a space for community-blessed Commands in the future, such as standard library Commands, such as [Revocation]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The `/ucan` Command namespace MUST be reserved. This MUST include any ability string matching the regex `^ucan\/.*`. This is important for keeping a space for community-blessed Commands in the future, such as standard library Commands, such as [Revocation]. | |
The `/ucan` Command namespace MUST be reserved. This MUST include any ability string matching the regex `^ucan(\/(^\m\/)+)+`. This is important for keeping a space for community-blessed Commands in the future, such as standard library Commands, such as [Revocation]. |
I'm no regex wizard but I'm guessing this regex is older than the prohibition on trailing /
s, which this newer, uglier regex bans.
Also, I couldn't tell if /ucan
was supposed to be a valid command (or a valid blank-check for future stdlib commands), but if so, that last +
(1 or more) should be a *
(0 or more).
rootAud(aud: Bob) | ||
rootCap("cap: (Storage, crud/*)") | ||
end | ||
This field SHOULD NOT be used to sign arbitrary data, such as signature challenges. See the [`meta`][Metadata] field for more. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This field SHOULD NOT be used to sign arbitrary data, such as signature challenges. See the [`meta`][Metadata] field for more. | |
This field SHOULD NOT be used to sign arbitrary data, such as signature challenges. See the [`meta`][#metadata] field for more. |
|
||
If any of the following criteria are not met, the UCAN MUST be considered invalid. | ||
Attenuation is the process of constraining the capabilities in a delegation chain. Each direct delegation MUST either directly restate or attenuate (diminish) its capabilities. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attenuation is the process of constraining the capabilities in a delegation chain. Each direct delegation MUST either directly restate or attenuate (diminish) its capabilities. | |
Attenuation is the process of constraining the capabilities in a delegation chain. Each direct delegation MUST either explicitly restate or attenuate (diminish) its capabilities. |
|
||
A UCAN is valid inclusive from the `nbf` time and until the `exp` field. If the current time is outside of these bounds, the UCAN MUST be considered invalid. When setting these bounds, a delegator or invoker SHOULD account for expected clock drift. Use of time bounds this way is called "timely invocation." | ||
Note that if an instance cannot dereference a CID at runtime, the UCAN MUST fail validation. This is consistent with the [constructive semantics] of UCAN. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this is the first mention of a CID in the entire high-level spec, without a preceding normref or definition.
Editorial nitpicking aside, I think it might be clearer to refer to them as link
s in this and other section (which, in IPLD, are effectively just IPFS CIDs) rather than refer to them as CIDs, because what matters is that they are identifiers they can't be defererenced, not anything about their nature as content identifiers or multiformats, etc etc. (I.e., I can imagine an RDF/JSON-LD version of this where the same link-dereferenceability rule applies to DID URLs, or HTTPS URLS, or some other kinds of dereferenceable URIs...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example:
Note that if an instance cannot dereference a CID at runtime, the UCAN MUST fail validation. This is consistent with the [constructive semantics] of UCAN. | |
Note that if a UCAN includes links in the form of [IPFS CIDs][CID] to subgraphs, and a parsing implementation cannot expand the full graph because one or more of these links cannot be dereferenced at runtime, then the UCAN MUST fail validation. This is consistent with the [constructive semantics] of UCAN. |
README.md
Outdated
[capabilities]: https://en.wikipedia.org/wiki/Object-capability_model | ||
[caps as keys]: http://www.erights.org/elib/capability/duals/myths.html#caps-as-keys | ||
[certificate capability model]: http://wiki.erights.org/wiki/Capability-based_Active_Invocation_Certificates |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[certificate capability model]: http://wiki.erights.org/wiki/Capability-based_Active_Invocation_Certificates | |
[certificate capability model]: http://wiki.erights.org/wiki/Capability-based_Active_Invocation_Certificates | |
[CID]: https://docs.ipfs.tech/concepts/content-addressing/ |
Unless the uglier, raw github definition seems more appropriate or canonical for whatever reason?
https://github.com/multiformats/cid
|
||
Alice delegates access to Bob. Bob then redelegates to Carol. Carol invokes the UCAN as part of a REST request to a compute service. To do this, she MUST both provide proof that she has access (the UCAN chain), and MUST delegate access to the discharging compute service. The discharging service MUST check that the root issuer (Alice) is in fact the owner (typically the creator) of the resource. This MAY be listed directly on the resource, as it is here. Once the UCAN chain and root ownership are validated, the storage service performs the write. | ||
The OPTIONAL `meta` field contains a map of arbitrary metadata, facts, and proofs of knowledge. The enclosed data MUST be self-evident and externally verifiable. It MAY include information such as hash preimages, server challenges, a Merkle proof, dictionary data, etc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The OPTIONAL `meta` field contains a map of arbitrary metadata, facts, and proofs of knowledge. The enclosed data MUST be self-evident and externally verifiable. It MAY include information such as hash preimages, server challenges, a Merkle proof, dictionary data, etc. | |
The OPTIONAL `meta` field contains a map of arbitrary metadata, facts, and proofs of knowledge. The enclosed data SHOULD be self-evident and externally verifiable. It MAY include information such as hash preimages, server challenges, a Merkle proof, dictionary data, etc. |
It feels like this MUST is untestable, and is more like an instruction to [the intentions of users of] UCAN-generating/encoding implementations than anything that could be included in a conformance test? It might be better phrased as a consuming behavior, i.e., "Validators MUST NOT consider the contents when proofing UCAN invocation".
corner-case: do CIDs in metadata have to be dereferenceable at runtime as well? or does their being unmeaningful trump their being IPLD 😄
## 2.8 Attenuation | ||
|
||
Attenuation is the process of constraining the capabilities in a delegation chain. | ||
Please see the [Cryptosuite] section for more detail on DIDs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Narrator: but there was no more detail on DIDs there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see the [Cryptosuite] section for more detail on DIDs. | |
Please see the [Cryptosuite](#cryptosuite) section for more detail on DIDs. |
"example.com": "abcdef", | ||
"another.example.net": "12345" | ||
}, | ||
"sha3_256": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not SHA-256
, i.e. SHA-2? or is that deliberate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an example of putting in arbitrary data. It literally doesn't matter
|
||
A UCAN token MUST be referenced as a [base32] [CIDv1]. [SHA2-256] is the RECOMMENDED hash algorithm. | ||
> [!NOTE] | ||
> All CIDs encoded as above start with the characters `zdpu`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If they're canonically DAG-CBOR why is the multibase needed, as opposed to staying in binary? Maybe I've been talking to the wrong people but I thought CIDv1 was canonically binary and optionally multibased, so it feels like an extra roundtrip to multibase it and then drop back down to CBOR...
|
||
Except for rights amplification (below), each capability delegation MUST have equal or narrower capabilities from its proofs. The time bounds MUST also be equal to or contained inside the time bounds of the proof's time bounds. This lowering of rights at each delegation is called "attenuation." | ||
All UCANs MUST be canonically encoded with [DAG-CBOR] for signing. A UCAN MAY be presented or stored in other [IPLD] formats (such as [DAG-JSON]), but converted to DAG-CBOR for signature validation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like the { "/" : { "bytes": "...
notation needs to be explained a little here, rather than assuming the reader both wants to and can reasonably click that "DAG-CBOR" link and come back 10 minutes later knowing what IPLD is, if they don't already... because if I am confused, who is your target reader 😏
|
||
The [`0x55` raw data][raw data multicodec] codec MUST be supported. If other codecs are used (such as [`0x0129` `dag-json` multicodec][dag-json multicodec]), the UCAN MUST be able to be interpreted as a valid JWT (including the signature). | ||
The resolution of these addresses is left to the implementation and end-user, and MAY (non-exclusively) include the following: local store, a distributed hash table (DHT), gossip network, or RESTful service. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant, sure, but here might be a good place to remind the reader that a validator MUST fail verification of a UCAN with subgraphs linked by CID that do not dereference at time of consumption of invocations.
|
||
Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid via its proactive mechanisms. | ||
Aside from revocation, capability validation is idempotent. Marking a CID (or capability index inside that CID) as valid acts as memoization, obviating the need to check the entire structure on every validation. This extends to distinct UCANs that share a proof: if the proof was previously reviewed and is not revoked, it is RECOMMENDED to consider it valid immediately. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should that by "Aside from revocation and expiration,..." ?
I am also confused by the corner case mentioned here by Gozala:
Let's say Alice delegates to Bob a capability /crud/
over a hard disk, then Bob sends Carol (me) a capability /crud/write/
. Before I go to invoke it at Alice's hard disk, Alice's original parent cap expired or was revoked. Bob sends me a new sub-delegation identical except for having a fresher parent. That's a different token, right? This idempotency stuff doesn't apply because if it's a different chain, it's a different token?
|
||
### 6.6.1 Example | ||
Revocation is irreversible. Suppose the validator learns of revocation by UCAN CID. In that case, the UCAN and all of its derivatives in such a cache MUST be marked as invalid, and all validations immediately fail without needing to walk the entire structure. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love for "Suppose the validator learns of revocation by UCAN CID" to be expanded a bit, I'm having trouble supposing from that very high-level summary 😅
Forgive the billion little comments, few of them are worth discussing in further detail, mostly just idle suggestions. Is merging this blocked by anything? Just waiting for invocation to go to v1rc1? |
| `cmd` | `String` | Yes | The [Command] to eventually invoke | | ||
| `args` | `{String : Any}` | Yes | Any [Arguments] that MUST be present in the Invocation | | ||
| `nonce` | `Bytes` | Yes | Nonce | | ||
| `meta` | `{String : Any}` | No | [Meta] (asserted, signed data) — is not delegated authority | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe break out the non-required fields into a separate table below, since all of this is under MUST CONTAIN?
And throw iat
in there, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rationale is that iat
is not in the delegation spec since it's not particularly helpful for delegation. Invocation does have an iat
, so it's not a common field across all UCAN formats
Preview 📚