From 6744d980654ccf31a491c4ef0ff6420f98757f21 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Sun, 13 Aug 2023 22:43:25 -0700 Subject: [PATCH 01/53] Basic template --- CODE_OF_CONDUCT.md | 133 ++++++++++++++++ CONTRIBUTING.md | 13 ++ Community_Specification_License-v1.md | 99 ++++++++++++ Governance.md | 51 ++++++ LICENSE | 13 ++ Notices.md | 57 +++++++ README.md | 216 ++++++++++++++++++++++++++ Scope.md | 5 + 8 files changed, 587 insertions(+) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 Community_Specification_License-v1.md create mode 100644 Governance.md create mode 100644 LICENSE create mode 100644 Notices.md create mode 100644 README.md create mode 100644 Scope.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..a94f38d --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,133 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +hello@brooklynzelenka.com, philipp@fission.codes, or hello@fission.codes. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..30dfdd6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Contributing + +When contributing to this repository, please first discuss the change you wish to make via issue, +discussion, or any other method with the owners of this repository before making a change. + +Please note we have a code of conduct, please follow it in all your interactions with the project. + +## Pull Request Process + +1. Ensure that you have signed the CLA: in a separate PR, add your information to + the [Notices](./Notices.md), and [CLA Bot](./.clabot). +2. Increase the version numbers in any examples files and the README.md to the new version that this + Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). diff --git a/Community_Specification_License-v1.md b/Community_Specification_License-v1.md new file mode 100644 index 0000000..e49e871 --- /dev/null +++ b/Community_Specification_License-v1.md @@ -0,0 +1,99 @@ +# Community Specification License 1.0 + +**The Purpose of this License.** This License sets forth the terms under which 1) Contributor will participate in and contribute to the development of specifications, standards, best practices, guidelines, and other similar materials under this Working Group, and 2) how the materials developed under this License may be used. It is not intended for source code. Capitalized terms are defined in the License’s last section. + +**1. Copyright.** + +**1.1. Copyright License.** Contributor grants everyone a non-sublicensable, perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as expressly stated in this License) copyright license, without any obligation for accounting, to reproduce, prepare derivative works of, publicly display, publicly perform, and distribute any materials it submits to the full extent of its copyright interest in those materials. Contributor also acknowledges that the Working Group may exercise copyright rights in the Specification, including the rights to submit the Specification to another standards organization. + +**1.2. Copyright Attribution.** As a condition, anyone exercising this copyright license must include attribution to the Working Group in any derivative work based on materials developed by the Working Group. That attribution must include, at minimum, the material’s name, version number, and source from where the materials were retrieved. Attribution is not required for implementations of the Specification. + +**2. Patents.** + +**2.1. Patent License.** + +**2.1.1. As a Result of Contributions.** + +**2.1.1.1. As a Result of Contributions to Draft Specifications.** Contributor grants Licensee a non-sublicensable, perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as expressly stated in this License) license to its Necessary Claims in 1) Contributor’s Contributions and 2) to the Draft Specification that is within Scope as of the date of that Contribution, in both cases for Licensee’s Implementation of the Draft Specification, except for those patent claims excluded by Contributor under Section 3. + +**2.1.1.2. For Approved Specifications.** Contributor grants Licensee a non-sublicensable, perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as expressly stated in this License) license to its Necessary Claims included the Approved Specification that are within Scope for Licensee’s Implementation of the Approved Specification, except for those patent claims excluded by Contributor under Section 3. + +**2.1.2. Patent Grant from Licensee.** Licensee grants each other Licensee a non-sublicensable, perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as expressly stated in this License) license to its Necessary Claims for its Implementation, except for those patent claims excluded under Section 3. + +**2.1.3. Licensee Acceptance.** The patent grants set forth in Section 2.1 extend only to Licensees that have indicated their agreement to this License as follows: + +**2.1.3.1. Source Code Distributions.** For distribution in source code, by including this License in the root directory of the source code with the Implementation; + +**2.1.3.2. Non-Source Code Distributions.** For distribution in any form other than source code, by including this License in the documentation, legal notices, via notice in the software, and/or other written materials provided with the Implementation; or + +**2.1.3.3. Via Notices.md.** By issuing pull request or commit to the Specification’s repository’s Notices.md file by the Implementer’s authorized representative, including the Implementer’s name, authorized individual and system identifier, and Specification version. + +**2.1.4. Defensive Termination.** If any Licensee files or maintains a claim in a court asserting that a Necessary Claim is infringed by an Implementation, any licenses granted under this License to the Licensee are immediately terminated unless 1) that claim is directly in response to a claim against Licensee regarding an Implementation, or 2) that claim was brought to enforce the terms of this License, including intervention in a third-party action by a Licensee. + +**2.1.5. Additional Conditions.** This License is not an assurance (i) that any of Contributor’s copyrights or issued patent claims cover an Implementation of the Specification or are enforceable or (ii) that an Implementation of the Specification would not infringe intellectual property rights of any third party. + +**2.2. Patent Licensing Commitment.** In addition to the rights granted in Section 2.1, Contributor agrees to grant everyone a no charge, royalty-free license on reasonable and non-discriminatory terms to Contributor’s Necessary Claims that are within Scope for: +1) Implementations of a Draft Specification, where such license applies only to those Necessary Claims infringed by implementing Contributor's Contribution(s) included in that Draft Specification, and +2) Implementations of the Approved Specification. + +This patent licensing commitment does not apply to those claims subject to Contributor’s Exclusion Notice under Section 3. + +**2.3. Effect of Withdrawal.** Contributor may withdraw from the Working Group by issuing a pull request or commit providing notice of withdrawal to the Working Group repository’s Notices.md file. All of Contributor’s existing commitments and obligations with respect to the Working Group up to the date of that withdrawal notice will remain in effect, but no new obligations will be incurred. + +**2.4. Binding Encumbrance.** This License is binding on any future owner, assignee, or party who has been given the right to enforce any Necessary Claims against third parties. + +**3. Patent Exclusion.** + +**3.1. As a Result of Contributions.** Contributor may exclude Necessary Claims from its licensing commitments incurred under Section 2.1.1 by issuing an Exclusion Notice within 45 days of the date of that Contribution. Contributor may not issue an Exclusion Notice for any material that has been included in a Draft Deliverable for more than 45 days prior to the date of that Contribution. + +**3.2. As a Result of a Draft Specification Becoming an Approved Specification.** Prior to the adoption of a Draft Specification as an Approved Specification, Contributor may exclude Necessary Claims from its licensing commitments under this Agreement by issuing an Exclusion Notice. Contributor may not issue an Exclusion Notice for patents that were eligible to have been excluded pursuant to Section 3.1. + +**4. Source Code License.** Any source code developed by the Working Group is solely subject the source code license included in the Working Group’s repository for that code. If no source code license is included, the source code will be subject to the MIT License. + +**5. No Other Rights.** Except as specifically set forth in this License, no other express or implied patent, trademark, copyright, or other rights are granted under this License, including by implication, waiver, or estoppel. + +**6. Antitrust Compliance.** Contributor acknowledge that it may compete with other participants in various lines of business and that it is therefore imperative that they and their respective representatives act in a manner that does not violate any applicable antitrust laws and regulations. This License does not restrict any Contributor from engaging in similar specification development projects. Each Contributor may design, develop, manufacture, acquire or market competitive deliverables, products, and services, and conduct its business, in whatever way it chooses. No Contributor is obligated to announce or market any products or services. Without limiting the generality of the foregoing, the Contributors agree not to have any discussion relating to any product pricing, methods or channels of product distribution, division of markets, allocation of customers or any other topic that should not be discussed among competitors under the auspices of the Working Group. + +**7. Non-Circumvention.** Contributor agrees that it will not intentionally take or willfully assist any third party to take any action for the purpose of circumventing any obligations under this License. + +**8. Representations, Warranties and Disclaimers.** + +**8.1. Representations, Warranties and Disclaimers.** Contributor and Licensee represents and warrants that 1) it is legally entitled to grant the rights set forth in this License and 2) it will not intentionally include any third party materials in any Contribution unless those materials are available under terms that do not conflict with this License. IN ALL OTHER RESPECTS ITS CONTRIBUTIONS ARE PROVIDED "AS IS." The entire risk as to implementing or otherwise using the Contribution or the Specification is assumed by the implementer and user. Except as stated herein, CONTRIBUTOR AND LICENSEE EXPRESSLY DISCLAIM ANY WARRANTIES (EXPRESS, IMPLIED, OR OTHERWISE), INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, CONDITIONS OF QUALITY, OR TITLE, RELATED TO THE CONTRIBUTION OR THE SPECIFICATION. IN NO EVENT WILL ANY PARTY BE LIABLE TO ANY OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND WITH RESPECT TO THIS AGREEMENT, WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR NOT THE OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Any obligations regarding the transfer, successors in interest, or assignment of Necessary Claims will be satisfied if Contributor or Licensee notifies the transferee or assignee of any patent that it knows contains Necessary Claims or necessary claims under this License. Nothing in this License requires Contributor to undertake a patent search. If Contributor is 1) employed by or acting on behalf of an employer, 2) is making a Contribution under the direction or control of a third party, or 3) is making the Contribution as a consultant, contractor, or under another similar relationship with a third party, Contributor represents that they have been authorized by that party to enter into this License on its behalf. + +**8.2. Distribution Disclaimer.** Any distributions of technical information to third parties must include a notice materially similar to the following: “THESE MATERIALS ARE PROVIDED “AS IS.” The Contributors and Licensees expressly disclaim any warranties (express, implied, or otherwise), including implied warranties of merchantability, non-infringement, fitness for a particular purpose, or title, related to the materials. The entire risk as to implementing or otherwise using the materials is assumed by the implementer and user. IN NO EVENT WILL THE CONTRIBUTORS OR LICENSEES BE LIABLE TO ANY OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING AGREEMENT, WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.” + +**9. Definitions.** + +**9.1. Affiliate.** “Affiliate” means an entity that directly or indirectly Controls, is Controlled by, or is under common Control of that party. + +**9.2. Approved Specification.** “Approved Specification” means the final version and contents of any Draft Specification designated as an Approved Specification as set forth in the accompanying Governance.md file. + +**9.3. Contribution.** “Contribution” means any original work of authorship, including any modifications or additions to an existing work, that Contributor submits for inclusion in a Draft Specification, which is included in a Draft Specification or Approved Specification. + +**9.4. Contributor.** “Contributor” means any person or entity that has indicated its acceptance of the License 1) by making a Contribution to the Specification, or 2) by entering into the Community Specification Contributor License Agreement for the Specification. Contributor includes its Affiliates, assigns, agents, and successors in interest. + +**9.5. Control.** “Control” means direct or indirect control of more than 50% of the voting power to elect directors of that corporation, or for any other entity, the power to direct management of such entity. + +**9.6. Draft Specification.** “Draft Specification” means all versions of the material (except an Approved Specification) developed by this Working Group for the purpose of creating, commenting on, revising, updating, modifying, or adding to any document that is to be considered for inclusion in the Approved Specification. + +**9.7. Exclusion Notice.** “Exclusion Notice” means a written notice made by making a pull request or commit to the repository’s Notices.md file that identifies patents that Contributor is excluding from its patent licensing commitments under this License. The Exclusion Notice for issued patents and published applications must include the Draft Specification’s name, patent number(s) or title and application number(s), as the case may be, for each of the issued patent(s) or pending patent application(s) that the Contributor is excluding from the royalty-free licensing commitment set forth in this License. If an issued patent or pending patent application that may contain Necessary Claims is not set forth in the Exclusion Notice, those Necessary Claims shall continue to be subject to the licensing commitments under this License. The Exclusion Notice for unpublished patent applications must provide either: (i) the text of the filed application; or (ii) identification of the specific part(s) of the Draft Specification whose implementation makes the excluded claim a Necessary Claim. If (ii) is chosen, the effect of the exclusion will be limited to the identified part(s) of the Draft Specification. + +**9.8. Implementation.** “Implementation” means making, using, selling, offering for sale, importing or distributing any implementation of the Specification 1) only to the extent it implements the Specification and 2) so long as all required portions of the Specification are implemented. + +**9.9. License.** “License” means this Community Specification License. + +**9.10. Licensee.** “Licensee” means any person or entity that has indicated its acceptance of the License as set forth in Section 2.1.3. Licensee includes its Affiliates, assigns, agents, and successors in interest. + +**9.11. Necessary Claims.** “Necessary Claims” are those patent claims, if any, that a party owns or controls, including those claims later acquired, that are necessary to implement the required portions (including the required elements of optional portions) of the Specification that are described in detail and not merely referenced in the Specification. + +**9.12. Specification.** “Specification” means a Draft Specification or Approved Specification included in the Working Group’s repository subject to this License, and the version of the Specification implemented by the Licensee. + +**9.13. Scope.** “Scope” has the meaning as set forth in the accompanying Scope.md file included in this Specification’s repository. Changes to Scope do not apply retroactively. If no Scope is provided, each Contributor’s Necessary Claims are limited to that Contributor’s Contributions. + +**9.14. Working Group.** “Working Group” means this project to develop specifications, standards, best practices, guidelines, and other similar materials under this License. + + + +*The text of this Community Specification License is Copyright 2020 Joint Development Foundation and is licensed under the Creative Commons Attribution 4.0 International License available at https://creativecommons.org/licenses/by/4.0/.* + +SPDX-License-Identifier: CC-BY-4.0 diff --git a/Governance.md b/Governance.md new file mode 100644 index 0000000..b36de21 --- /dev/null +++ b/Governance.md @@ -0,0 +1,51 @@ +# Community Specification Governance Policy 1.0 + +This document provides the governance policy for specifications and other documents developed using the Community Specification process in a repository (each a “Working Group”). Each Working Group and must adhere to the requirements in this document. + +## 1. Roles. + +Each Working Group may include the following roles. Additional roles may be adopted and documented by the Working Group. + +**1.1. Maintainer.** “Maintainers” are responsible for organizing activities around developing, maintaining, and updating the specification(s) developed by the Working Group. Maintainers are also responsible for determining consensus and coordinating appeals. Each Working Group will designate one or more Maintainer for that Working Group. A Working Group may select a new or additional Maintainer(s) upon Approval of the Working Group Participants. + +**1.2. Editor.** “Editors” are responsible for ensuring that the contents of the document accurately reflect the decisions that have been made by the group, and that the specification adheres to formatting and content guidelines. Each Working Group will designate an Editor for that Working Group. A Working Group may select a new Editor upon Approval of the Working Group Participants. + +**1.3. Participants.** “Participants” are those that have made Contributions to the Working Group subject to the Community Specification License. + +## 2. Decision Making. + +**2.1. Consensus-Based Decision Making.** Working Groups make decisions through a consensus process (“Approval” or “Approved”). While the agreement of all Participants is preferred, it is not required for consensus. Rather, the Maintainer will determine consensus based on their good faith consideration of a number of factors, including the dominant view of the Working Group Participants and nature of support and objections. The Maintainer will document evidence of consensus in accordance with these requirements. + +**2.2. Appeal Process.** Decisions may be appealed be via a pull request or an issue, and that appeal will be considered by the Maintainer in good faith, who will respond in writing within a reasonable time. + +## 3. Ways of Working. + +Inspired by [ANSI’s Essential Requirements for Due Process](https://share.ansi.org/Shared%20Documents/Standards%20Activities/American%20National%20Standards/Procedures,%20Guides,%20and%20Forms/2020_ANSI_Essential_Requirements.pdf), Community Specification Working Groups must adhere to consensus-based due process requirements. These requirements apply to activities related to the development of consensus for approval, revision, reaffirmation, and withdrawal of Community Specifications. Due process means that any person (organization, company, government agency, individual, etc.) with a direct and material interest has a right to participate by: a) expressing a position and its basis, b) having that position considered, and c) having the right to appeal. Due process allows for equity and fair play. The following constitute the minimum acceptable due process requirements for the development of consensus. + +**3.1. Openness.** Participation shall be open to all persons who are directly and materially affected by the activity in question. There shall be no undue financial barriers to participation. Voting membership on the consensus body shall not be conditional upon membership in any organization, nor unreasonably restricted on the basis of technical qualifications or other such requirements. Membership in a Working Group’s parent organization, if any, may be required. + +**3.2. Lack of Dominance.** The development process shall not be dominated by any single interest category, individual or organization. Dominance means a position or exercise of dominant authority, leadership, or influence by reason of superior leverage, strength, or representation to the exclusion of fair and equitable consideration of other viewpoints. + +**3.3. Balance.** The development process should have a balance of interests. Participants from diverse interest categories shall be sought with the objective of achieving balance. + +**3.4. Coordination and Harmonization.** Good faith efforts shall be made to resolve potential conflicts between and among deliverables developed under this Working Group and existing industry standards. + +**3.5. Consideration of Views and Objections.** Prompt consideration shall be given to the written views and objections of all Participants. + +**3.6. Written procedures.** This governance document and other materials documenting the Community Specification development process shall be available to any interested person. + +## 4. Specification Development Process. + +**4.1. Pre-Draft.** Any Participant may submit a proposed initial draft document as a candidate Draft Specification of that Working Group. The Maintainer will designate each submission as a “Pre-Draft” document. + +**4.2. Draft.** Each Pre-Draft document of a Working Group must first be Approved to become a” Draft Specification”. Once the Working Group approves a document as a Draft Specification, the Draft Specification becomes the basis for all going forward work on that specification. + +**4.3. Working Group Approval.** Once a Working Group believes it has achieved the objectives for its specification as described in the Scope, it will Approve that Draft Specification and progress it to “Approved Specification” status. + +**4.4. Publication and Submission.** Upon the designation of a Draft Specification as an Approved Specification, the Maintainer will publish the Approved Specification in a manner agreed upon by the Working Group Participants (i.e., Working Group Participant only location, publicly available location, Working Group maintained website, Working Group member website, etc.). The publication of an Approved Specification in a publicly accessible manner must include the terms under which the Approved Specification is being made available under. + +**4.5. Submissions to Standards Bodies.** No Draft Specification or Approved Specification may be submitted to another standards development organization without Working group Approval. Upon reaching Approval, the Maintainer will coordinate the submission of the applicable Draft Specification or Approved Specification to another standards development organization. Working Group Participants that developed that Draft Specification or Approved Specification agree to grant the copyright rights necessary to make those submissions. + +## 5. Non-Confidential, Restricted Disclosure. + +Information disclosed in connection with any Working Group activity, including but not limited to meetings, Contributions, and submissions, is not confidential, regardless of any markings or statements to the contrary. Notwithstanding the foregoing, if the Working Group is collaborating via a private repository, the Participants will not make any public disclosures of that information contained in that private repository without the Approval of the Working Group. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c7d1e9f --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +# Licenses + +## Specification License + +Specifications in the repository are subject to the **Community Specification License 1.0** available at [https://github.com/CommunitySpecification/1.0](https://github.com/CommunitySpecification/1.0). + +## Source Code License + +If source code is included in this repository, or for sample or reference code included in the specification itself, that code is subject to the MIT license unless otherwise designated. In the case of any conflict or confusion within this specification repository between the Community Specification License and the MIT or other designated license, the terms of the Community Specification License shall apply. + +If source code is included in this repository, or for sample or reference code included in the specification itself, that code is subject to the MIT license unless otherwise marked. + +In the case of any conflict or confusion within this specification repository between the Community Specification License and the designated source code license, the terms of the Community Specification License shall apply. diff --git a/Notices.md b/Notices.md new file mode 100644 index 0000000..e33e12a --- /dev/null +++ b/Notices.md @@ -0,0 +1,57 @@ +# Notices + +## Code of Conduct + +The Code of Conduct is available in the repository in [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md). + +Contact for Code of Conduct issues or inquires: hello@brooklynzelenka.com, hello@fission.codes + +## License Acceptance + +Per Community Specification License 1.0 Section 2.1.3.3, Licensees may indicate their acceptance of the Community Specification License by issuing a pull request to the Specification’s repository’s Notice.md file, including the Licensee’s name, authorized individuals' names, and repository system identifier (e.g. GitHub ID), and specification version. + +A Licensee may consent to accepting the current Community Specification License version or any future version of the Community Specification License by indicating "or later" after their specification version. + +--------------------------------------------------------------------------------- + +Licensee’s name: Brooklyn Zelenka + +Authorized individual and system identifier: expede + +Specification version: 1.0.0 or later + +--------------------------------------------------------------------------------- + +## Withdrawals + +Name of party withdrawing: + +Date of withdrawal: + +--------------------------------------------------------------------------------- + +## Exclusions + +This section includes any Exclusion Notices made against a Draft Deliverable or Approved Deliverable as set forth in the Community Specification Development License. Each Exclusion Notice must include the following information: + +- Name of party making the Exclusion Notice: + +- Name of patent owner: + +- Specification: + +- Version number: + +**For issued patents and published patent applications:** + + (i) patent number(s) or title and application number(s), as the case may be: + + (ii) identification of the specific part(s) of the Specification whose implementation makes the excluded claim a Necessary Claim. + +**For unpublished patent applications must provide either:** + + (i) the text of the filed application; or + + (ii) identification of the specific part(s) of the Specification whose implementation makes the excluded claim a Necessary Claim. + +----------------------------------------------------------------------------------------- diff --git a/README.md b/README.md new file mode 100644 index 0000000..98a9d5c --- /dev/null +++ b/README.md @@ -0,0 +1,216 @@ +# UCAN Revocation Specification v1.0.0 + +## Editors + +* [Brooklyn Zelenka], [Fission] + +## Authors + +* [Brooklyn Zelenka], [Fission] + +# 0. Abstract + +## Language + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119]. + +# 1. Introduction + +## 1.1 Motivation + +## 2.9 Revocation + +Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). + +In the case of UCAN, this MUST be done by a proof's issuer DID. For more on the exact mechanism, see the revocation validation section. + +## 6.6 Revocation + +Any issuer of a UCAN MAY later revoke that UCAN or the capabilities that have been derived from it further downstream in a proof chain. + +This mechanism is eventually consistent and SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. + +While some resources are centralized (e.g. access to a server), others are unbound from specific locations (e.g. a CRDT), in which case it will take longer for the revocation to propagate. + +Every resource type SHOULD have a canonical location where its revocations are kept. This list is non-exclusive, and revocation messages MAY be gossiped between peers in a network to share this information more quickly. + +It is RECOMMENDED that the canonical revocation store be kept as close to (or inside) the resource it is about as possible. For example, the WebNative File System maintains a Merkle tree of revoked CIDs at a well-known path. Another example is that a centralized server could have an endpoint that lists the revoked UCANs by [canonical CID]. + +Revocations MUST be irreversible. If the revocation was issued in error, a unique UCAN MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. + +A revocation message MUST conform to the following JSON format: + +``` js +{ + "iss": did, + "revoke": canonicalUcanCid, + "challenge": base64Unpadded(sign(did.privateKey, `REVOKE:${canonicalUcanCid}`)) +} +``` + +This format makes it easy to select the relevant UCAN, confirm that the issuer is in the proof chain for some or all capabilities, and validate that the revocation was signed by the same issuer. + +Any other proofs in the selected UCAN not issued by the same DID as the revocation issuer MUST be treated as valid. + +Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid via its proactive mechanisms. + +### 6.6.1 Example + +``` + Root + ┌────────────────┐ ─┐ + │ │ │ + │ iss: Alice │ │ + │ aud: Bob │ ├─ Alice can revoke + │ │ │ + └───┬────────┬───┘ │ + │ │ │ + │ │ │ + ▼ ▼ │ +┌──────────────┐ ┌──────────────┐ │ ─┐ +│ │ │ │ │ │ +│ iss: Bob │ │ iss: Bob │ │ │ +│ aud: Carol │ │ aud: Dan │ │ ├─ Bob can revoke +│ cap: [X,Y] │ │ cap: [Y,Z] │ │ │ +│ │ │ │ │ │ +└───────┬──────┘ └──┬───────────┘ │ │ + │ │ │ │ + │ │ │ │ + ▼ │ │ │ +┌──────────────┐ │ │ │ ─┐ +│ │ │ │ │ │ +│ iss: Carol │ │ │ │ │ +│ aud: Dan │ │ │ │ ├─ Carol can revoke +│ cap: [X,Y] │ │ │ │ │ +│ │ │ │ │ │ +└───────────┬──┘ │ │ │ │ + │ │ │ │ │ + │ │ │ │ │ + ▼ ▼ │ │ │ + ┌────────────────┐ │ │ │ ─┐ + │ │ │ │ │ │ + │ iss: Dan │ │ │ │ │ + │ aud: Erin │ │ │ │ ├─ Dan can revoke + │ cap: [X,Y,Z] │ │ │ │ │ + │ │ │ │ │ │ + └────────────────┘ ─┘ ─┘ ─┘ ─┘ +``` + +In this example, Alice MAY revoke any of the UCANs in the chain, Carol MAY revoke the bottom two, and so on. If the UCAN `Carol → Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for `X` since its proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice → Bob → Dan → Erin` includes them. Note that despite `Y` being in the revoked `Carol → Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. + +## 6.7 Backwards Compatibility + +A UCAN validator MAY implement backward compatibility with previous versions of UCAN. Delegated UCANs MUST be of an equal or higher version than their proofs. For example, a v0.9.0 UCAN that includes proofs that are separately v0.9.0, v0.8.1, v0.7.0, and v0.5.0 MAY be considered valid. A v0.5.0 UCAN that has a UCAN v0.9.0 proof MUST NOT be considered valid. + +# 7. Collections + +UCANs are indexed by their hash — often called their ["content address"][content addressable storage]. UCANs MUST be addressable as [CIDv1]. Use of a [canonical CID] is RECOMMENDED. + +Content addressing the proofs has multiple advantages over inlining tokens, including: +* Avoids re-encoding deeply nested proofs as Base64 many times (and the associated size increase) +* Canonical signature +* Enables only transmitting the relevant proofs + +Multiple UCANs in a single request MAY be collected into one table. It is RECOMMENDED that these be indexed by CID. The [canonical JSON representation][canonical collections] (below) MUST be supported. Implementations MAY include more formats, for example to optimize for a particular transport. Transports MAY map their collection to this collection format. + +### 7.1 Canonical JSON Collection + +The canonical JSON representation is an key-value object, mapping UCAN content identifiers to their fully-encoded base64url strings. A root "entry point" (if one exists) MUST be indexed by the slash `/` character. + +#### 7.1.1 Example + +``` json +{ + "/": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsInVjdiI6IjAuOC4xIn0.eyJhdWQiOiJkaWQ6a2V5Ono2TWtmUWhMSEJTRk11UjdiUVhUUWVxZTVrWVVXNTFIcGZaZWF5bWd5MXprUDJqTSIsImF0dCI6W3sid2l0aCI6eyJzY2hlbWUiOiJ3bmZzIiwiaGllclBhcnQiOiIvL2RlbW91c2VyLmZpc3Npb24ubmFtZS9wdWJsaWMvcGhvdG9zLyJ9LCJjYW4iOnsibmFtZXNwYWNlIjoid25mcyIsInNlZ21lbnRzIjpbIk9WRVJXUklURSJdfX0seyJ3aXRoIjp7InNjaGVtZSI6InduZnMiLCJoaWVyUGFydCI6Ii8vZGVtb3VzZXIuZmlzc2lvbi5uYW1lL3B1YmxpYy9ub3Rlcy8ifSwiY2FuIjp7Im5hbWVzcGFjZSI6InduZnMiLCJzZWdtZW50cyI6WyJPVkVSV1JJVEUiXX19XSwiZXhwIjo5MjU2OTM5NTA1LCJpc3MiOiJkaWQ6a2V5Ono2TWtyNWFlZmluMUR6akc3TUJKM25zRkNzbnZIS0V2VGIyQzRZQUp3Ynh0MWpGUyIsInByZiI6WyJleUpoYkdjaU9pSkZaRVJUUVNJc0luUjVjQ0k2SWtwWFZDSXNJblZqZGlJNklqQXVPQzR4SW4wLmV5SmhkV1FpT2lKa2FXUTZhMlY1T25vMlRXdHlOV0ZsWm1sdU1VUjZha2MzVFVKS00yNXpSa056Ym5aSVMwVjJWR0l5UXpSWlFVcDNZbmgwTVdwR1V5SXNJbUYwZENJNlczc2lkMmwwYUNJNmV5SnpZMmhsYldVaU9pSjNibVp6SWl3aWFHbGxjbEJoY25RaU9pSXZMMlJsYlc5MWMyVnlMbVpwYzNOcGIyNHVibUZ0WlM5d2RXSnNhV012Y0dodmRHOXpMeUo5TENKallXNGlPbnNpYm1GdFpYTndZV05sSWpvaWQyNW1jeUlzSW5ObFoyMWxiblJ6SWpwYklrOVdSVkpYVWtsVVJTSmRmWDFkTENKbGVIQWlPamt5TlRZNU16azFNRFVzSW1semN5STZJbVJwWkRwclpYazZlalpOYTJ0WGIzRTJVek4wY1ZKWGNXdFNibmxOWkZobWNuTTFORGxGWm5VMmNVTjFOSFZxUkdaTlkycEdVRXBTSWl3aWNISm1JanBiWFgwLlNqS2FIR18yQ2UwcGp1TkY1T0QtYjZqb04xU0lKTXBqS2pqbDRKRTYxX3VwT3J0dktvRFFTeFo3V2VZVkFJQVREbDhFbWNPS2o5T3FPU3cwVmc4VkNBIiwiZXlKaGJHY2lPaUpGWkVSVFFTSXNJblI1Y0NJNklrcFhWQ0lzSW5WamRpSTZJakF1T0M0eEluMC5leUpoZFdRaU9pSmthV1E2YTJWNU9ubzJUV3R5TldGbFptbHVNVVI2YWtjM1RVSktNMjV6UmtOemJuWklTMFYyVkdJeVF6UlpRVXAzWW5oME1XcEdVeUlzSW1GMGRDSTZXM3NpZDJsMGFDSTZleUp6WTJobGJXVWlPaUozYm1aeklpd2lhR2xsY2xCaGNuUWlPaUl2TDJSbGJXOTFjMlZ5TG1acGMzTnBiMjR1Ym1GdFpTOXdkV0pzYVdNdmNHaHZkRzl6THlKOUxDSmpZVzRpT25zaWJtRnRaWE53WVdObElqb2lkMjVtY3lJc0luTmxaMjFsYm5SeklqcGJJazlXUlZKWFVrbFVSU0pkZlgxZExDSmxlSEFpT2preU5UWTVNemsxTURVc0ltbHpjeUk2SW1ScFpEcHJaWGs2ZWpaTmEydFhiM0UyVXpOMGNWSlhjV3RTYm5sTlpGaG1jbk0xTkRsRlpuVTJjVU4xTkhWcVJHWk5ZMnBHVUVwU0lpd2ljSEptSWpwYlhYMC5TakthSEdfMkNlMHBqdU5GNU9ELWI2am9OMVNJSk1waktqamw0SkU2MV91cE9ydHZLb0RRU3haN1dlWVZBSUFURGw4RW1jT0tqOU9xT1N3MFZnOFZDQSJdfQ.Ab-xfYRoqYEHuo-252MKXDSiOZkLD-h1gHt8gKBP0AVdJZ6Jruv49TLZOvgWy9QkCpiwKUeGVbHodKcVx-azCQ", + "bafkreihogico5an3e2xy3fykalfwxxry7itbhfcgq6f47sif6d7w6uk2ze": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInVhdiI6IjAuMS4wIn0.eyJhdWQiOiJkaWQ6a2V5OnpTdEVacHpTTXRUdDlrMnZzemd2Q3dGNGZMUVFTeUExNVc1QVE0ejNBUjZCeDRlRko1Y3JKRmJ1R3hLbWJtYTQiLCJpc3MiOiJkaWQ6a2V5Ono1QzRmdVAyRERKQ2hoTUJDd0FrcFlVTXVKWmROV1dINU5lWWpVeVk4YnRZZnpEaDNhSHdUNXBpY0hyOVR0anEiLCJuYmYiOjE1ODg3MTM2MjIsImV4cCI6MTU4OTAwMDAwMCwic2NwIjoiLyIsInB0YyI6IkFQUEVORCIsInByZiI6bnVsbH0.Ay8C5ajYWHxtD8y0msla5IJ8VFffTHgVq448Hlr818JtNaTUzNIwFiuutEMECGTy69hV9Xu9bxGxTe0TpC7AzV34p0wSFax075mC3w9JYB8yqck_MEBg_dZ1xlJCfDve60AHseKPtbr2emp6hZVfTpQGZzusstimAxyYPrQUWv9wqTFmin0Ls-loAWamleUZoE1Tarlp_0h9SeV614RfRTC0e3x_VP9Ra_84JhJHZ7kiLf44TnyPl_9AbzuMdDwCvu-zXjd_jMlDyYcuwamJ15XqrgykLOm0WTREgr_sNLVciXBXd6EQ-Zh2L7hd38noJm1P_MIr9_EDRWAhoRLXPQ" +} +``` + +# 8. Token Resolution + +Token resolution is transport specific. The exact format is left to the relevant UCAN transport specification. At minimum, such a specification MUST define at least the following: + +1. Request protocol +2. Response protocol +3. Collections format + +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. + + +[Alan Karp]: https://github.com/alanhkarp +[Benjamin Goering]: https://github.com/gobengo +[Biscuit]: https://github.com/biscuit-auth/biscuit/ +[Blaine Cook]: https://github.com/blaine +[Bluesky]: https://blueskyweb.xyz/ +[Brendan O'Brien]: https://github.com/b5 +[Brian Ginsburg]: https://github.com/bgins +[Brooklyn Zelenka]: https://github.com/expede +[CACAO]: https://blog.ceramic.network/capability-based-data-security-on-ceramic/ +[CIDv1]: https://docs.ipfs.io/concepts/content-addressing/#identifier-formats +[Canonical CID]: #651-cid-canonicalization +[Capability Myths Demolished]: https://srl.cs.jhu.edu/pubs/SRL2003-02.pdf +[Christine Lemmer-Webber]: https://github.com/cwebber +[Christopher Joel]: https://github.com/cdata +[DID fragment]: https://www.w3.org/TR/did-core/#fragment +[DID path]: https://www.w3.org/TR/did-core/#path +[DID subject]: https://www.w3.org/TR/did-core/#dfn-did-subjects +[DID]: https://www.w3.org/TR/did-core/ +[Dan Finlay]: https://github.com/danfinlay +[Daniel Holmgren]: https://github.com/dholms +[ECDSA security]: https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Security +[FIDO]: https://fidoalliance.org/fido-authentication/ +[Fission]: https://fission.codes +[Hugo Dias]: https://github.com/hugomrdias +[Irakli Gozalishvili]: https://github.com/Gozala +[JWT]: https://datatracker.ietf.org/doc/html/rfc7519 +[Juan Caballero]: https://github.com/bumblefudge +[Local-First Auth]: https://github.com/local-first-web/auth +[Macaroon]: https://storage.googleapis.com/pub-tools-public-publication-data/pdf/41892.pdf +[Mark Miller]: https://github.com/erights +[Mikael Rogers]: https://github.com/mikeal/ +[OCAP]: http://erights.org/elib/capability/index.html +[OCapN]: https://github.com/ocapn/ocapn +[POLA]: https://en.wikipedia.org/wiki/Principle_of_least_privilege +[Philipp Krüger]: https://github.com/matheus23 +[Protocol Labs]: https://protocol.ai/ +[RFC 2119]: https://datatracker.ietf.org/doc/html/rfc2119 +[RFC 3339]: https://www.rfc-editor.org/rfc/rfc3339 +[RFC 8037]: https://datatracker.ietf.org/doc/html/rfc8037 +[SHA2-256]: https://en.wikipedia.org/wiki/SHA-2 +[SPKI/SDSI]: https://datatracker.ietf.org/wg/spki/about/ +[SPKI]: https://theworld.com/~cme/html/spki.html +[Seitan token exchange]: https://book.keybase.io/docs/teams/seitan +[Steven Vandevelde]: https://github.com/icidasset +[Token Uniqueness]: #622-token-uniqueness +[URI]: https://www.rfc-editor.org/rfc/rfc3986 +[Verifiable credentials]: https://www.w3.org/2017/vc/WG/ +[W3C]: https://www.w3.org/ +[ZCAP-LD]: https://w3c-ccg.github.io/zcap-spec/ +[`did:3`]: https://github.com/ceramicnetwork/CIPs/blob/main/CIPs/cip-79.md +[`did:ion`]: https://github.com/decentralized-identity/ion +[`did:key`]: https://w3c-ccg.github.io/did-method-key/ +[base32]: https://github.com/multiformats/multibase/blob/master/multibase.csv#L12 +[browser api crypto key]: https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey +[canonical collections]: #71-canonical-json-collection +[capabilities]: https://en.wikipedia.org/wiki/Object-capability_model +[caps as keys]: http://www.erights.org/elib/capability/duals/myths.html#caps-as-keys +[confinement]: http://www.erights.org/elib/capability/dist-confine.html +[constructive semantics]: https://en.wikipedia.org/wiki/Intuitionistic_logic +[content addressable storage]: https://en.wikipedia.org/wiki/Content-addressable_storage +[content addressing]: https://en.wikipedia.org/wiki/Content-addressable_storage +[content identifiers]: #65-content-identifiers +[dag-json multicodec]: https://github.com/multiformats/multicodec/blob/master/table.csv#L104 +[delegation]: #51-ucan-delegation +[disjunction]: https://en.wikipedia.org/wiki/Logical_disjunction +[invocation]: https://github.com/ucan-wg/invocation +[prf field]: #3271-prf-field +[raw data multicodec]: https://github.com/multiformats/multicodec/blob/a03169371c0a4aec0083febc996c38c3846a0914/table.csv?plain=1#L41 +[replay attack prevention]: #93-replay-attack-prevention +[revocation]: #66-revocation +[rights amplification]: #64-rights-amplification +[secure hardware enclave]: https://support.apple.com/en-ca/guide/security/sec59b0b31ff +[spki rfc]: https://www.rfc-editor.org/rfc/rfc2693.html +[time definition]: https://en.wikipedia.org/wiki/Temporal_database +[token resolution]: #8-token-resolution +[top ability]: #41-top +[ucan.xyz]: https://ucan.xyz diff --git a/Scope.md b/Scope.md new file mode 100644 index 0000000..f940d7b --- /dev/null +++ b/Scope.md @@ -0,0 +1,5 @@ +# Scope + +This document specifies an eventaully consistent, content addressed revocation mechanism for the UCAN certificate capabilty format. + +Any changes of Scope are not retroactive. From 0d0b80d76fa6cfb9ab1437b5e698277bbc2f5b6c Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Sun, 13 Aug 2023 22:52:12 -0700 Subject: [PATCH 02/53] fix .github --- .github/{.github => }/CODEOWNERS | 2 +- .github/{.github => }/workflows/linkcheck.yml | 0 .github/{.github => }/workflows/spellcheck.yml | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename .github/{.github => }/CODEOWNERS (83%) rename .github/{.github => }/workflows/linkcheck.yml (100%) rename .github/{.github => }/workflows/spellcheck.yml (100%) diff --git a/.github/.github/CODEOWNERS b/.github/CODEOWNERS similarity index 83% rename from .github/.github/CODEOWNERS rename to .github/CODEOWNERS index 628788e..866e6cf 100644 --- a/.github/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,4 +2,4 @@ # the repo. Unless a later match takes precedence, # @global-owner1 and @global-owner2 will be requested for # review when someone opens a pull request. -* @expede @matheus23 @gozala @dholms +* @expede diff --git a/.github/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml similarity index 100% rename from .github/.github/workflows/linkcheck.yml rename to .github/workflows/linkcheck.yml diff --git a/.github/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml similarity index 100% rename from .github/.github/workflows/spellcheck.yml rename to .github/workflows/spellcheck.yml From a3bf6675f8d436f03fed35acaab3880939e3c163 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Mon, 14 Aug 2023 19:49:29 -0700 Subject: [PATCH 03/53] Prettier graph --- README.md | 102 +++++++++++++++--------------------------------------- 1 file changed, 28 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index 98a9d5c..bada11a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# UCAN Revocation Specification v1.0.0 +# UCAN Revocation Specification v1.0.0-RC ## Editors @@ -6,10 +6,13 @@ ## Authors +* [Daniel Holmgren], [Bluesky] * [Brooklyn Zelenka], [Fission] # 0. Abstract +This document describes how to revoke a previously issued delegation. + ## Language The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119]. @@ -38,6 +41,8 @@ It is RECOMMENDED that the canonical revocation store be kept as close to (or in Revocations MUST be irreversible. If the revocation was issued in error, a unique UCAN MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. +# Format + A revocation message MUST conform to the following JSON format: ``` js @@ -54,87 +59,36 @@ Any other proofs in the selected UCAN not issued by the same DID as the revocati Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid via its proactive mechanisms. -### 6.6.1 Example - -``` - Root - ┌────────────────┐ ─┐ - │ │ │ - │ iss: Alice │ │ - │ aud: Bob │ ├─ Alice can revoke - │ │ │ - └───┬────────┬───┘ │ - │ │ │ - │ │ │ - ▼ ▼ │ -┌──────────────┐ ┌──────────────┐ │ ─┐ -│ │ │ │ │ │ -│ iss: Bob │ │ iss: Bob │ │ │ -│ aud: Carol │ │ aud: Dan │ │ ├─ Bob can revoke -│ cap: [X,Y] │ │ cap: [Y,Z] │ │ │ -│ │ │ │ │ │ -└───────┬──────┘ └──┬───────────┘ │ │ - │ │ │ │ - │ │ │ │ - ▼ │ │ │ -┌──────────────┐ │ │ │ ─┐ -│ │ │ │ │ │ -│ iss: Carol │ │ │ │ │ -│ aud: Dan │ │ │ │ ├─ Carol can revoke -│ cap: [X,Y] │ │ │ │ │ -│ │ │ │ │ │ -└───────────┬──┘ │ │ │ │ - │ │ │ │ │ - │ │ │ │ │ - ▼ ▼ │ │ │ - ┌────────────────┐ │ │ │ ─┐ - │ │ │ │ │ │ - │ iss: Dan │ │ │ │ │ - │ aud: Erin │ │ │ │ ├─ Dan can revoke - │ cap: [X,Y,Z] │ │ │ │ │ - │ │ │ │ │ │ - └────────────────┘ ─┘ ─┘ ─┘ ─┘ -``` - -In this example, Alice MAY revoke any of the UCANs in the chain, Carol MAY revoke the bottom two, and so on. If the UCAN `Carol → Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for `X` since its proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice → Bob → Dan → Erin` includes them. Note that despite `Y` being in the revoked `Carol → Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. - -## 6.7 Backwards Compatibility - -A UCAN validator MAY implement backward compatibility with previous versions of UCAN. Delegated UCANs MUST be of an equal or higher version than their proofs. For example, a v0.9.0 UCAN that includes proofs that are separately v0.9.0, v0.8.1, v0.7.0, and v0.5.0 MAY be considered valid. A v0.5.0 UCAN that has a UCAN v0.9.0 proof MUST NOT be considered valid. +## 6.6.1 Example -# 7. Collections +``` mermaid +flowchart TB + subgraph RA[Alice can revoke] + AB["(Root)\niss: Alice\naud: Bob\ncap:[X,Y,Z]"] -UCANs are indexed by their hash — often called their ["content address"][content addressable storage]. UCANs MUST be addressable as [CIDv1]. Use of a [canonical CID] is RECOMMENDED. + subgraph RB[Bob can revoke] + BC["iss: Bob\naud: Carol\ncap: [X,Y]"] + BD["iss: Bob\naud: Dan\ncap:[Y,Z]"] -Content addressing the proofs has multiple advantages over inlining tokens, including: -* Avoids re-encoding deeply nested proofs as Base64 many times (and the associated size increase) -* Canonical signature -* Enables only transmitting the relevant proofs + subgraph RC[Carol can revoke] + CD["iss: Carol\naud: Dan\ncap:[X,Y]"] -Multiple UCANs in a single request MAY be collected into one table. It is RECOMMENDED that these be indexed by CID. The [canonical JSON representation][canonical collections] (below) MUST be supported. Implementations MAY include more formats, for example to optimize for a particular transport. Transports MAY map their collection to this collection format. + subgraph RD[Dan can revoke] + DE["iss: Dan\naud: Erin\ncap:[X,Y,Z]"] + end + end + end + end -### 7.1 Canonical JSON Collection - -The canonical JSON representation is an key-value object, mapping UCAN content identifiers to their fully-encoded base64url strings. A root "entry point" (if one exists) MUST be indexed by the slash `/` character. - -#### 7.1.1 Example - -``` json -{ - "/": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsInVjdiI6IjAuOC4xIn0.eyJhdWQiOiJkaWQ6a2V5Ono2TWtmUWhMSEJTRk11UjdiUVhUUWVxZTVrWVVXNTFIcGZaZWF5bWd5MXprUDJqTSIsImF0dCI6W3sid2l0aCI6eyJzY2hlbWUiOiJ3bmZzIiwiaGllclBhcnQiOiIvL2RlbW91c2VyLmZpc3Npb24ubmFtZS9wdWJsaWMvcGhvdG9zLyJ9LCJjYW4iOnsibmFtZXNwYWNlIjoid25mcyIsInNlZ21lbnRzIjpbIk9WRVJXUklURSJdfX0seyJ3aXRoIjp7InNjaGVtZSI6InduZnMiLCJoaWVyUGFydCI6Ii8vZGVtb3VzZXIuZmlzc2lvbi5uYW1lL3B1YmxpYy9ub3Rlcy8ifSwiY2FuIjp7Im5hbWVzcGFjZSI6InduZnMiLCJzZWdtZW50cyI6WyJPVkVSV1JJVEUiXX19XSwiZXhwIjo5MjU2OTM5NTA1LCJpc3MiOiJkaWQ6a2V5Ono2TWtyNWFlZmluMUR6akc3TUJKM25zRkNzbnZIS0V2VGIyQzRZQUp3Ynh0MWpGUyIsInByZiI6WyJleUpoYkdjaU9pSkZaRVJUUVNJc0luUjVjQ0k2SWtwWFZDSXNJblZqZGlJNklqQXVPQzR4SW4wLmV5SmhkV1FpT2lKa2FXUTZhMlY1T25vMlRXdHlOV0ZsWm1sdU1VUjZha2MzVFVKS00yNXpSa056Ym5aSVMwVjJWR0l5UXpSWlFVcDNZbmgwTVdwR1V5SXNJbUYwZENJNlczc2lkMmwwYUNJNmV5SnpZMmhsYldVaU9pSjNibVp6SWl3aWFHbGxjbEJoY25RaU9pSXZMMlJsYlc5MWMyVnlMbVpwYzNOcGIyNHVibUZ0WlM5d2RXSnNhV012Y0dodmRHOXpMeUo5TENKallXNGlPbnNpYm1GdFpYTndZV05sSWpvaWQyNW1jeUlzSW5ObFoyMWxiblJ6SWpwYklrOVdSVkpYVWtsVVJTSmRmWDFkTENKbGVIQWlPamt5TlRZNU16azFNRFVzSW1semN5STZJbVJwWkRwclpYazZlalpOYTJ0WGIzRTJVek4wY1ZKWGNXdFNibmxOWkZobWNuTTFORGxGWm5VMmNVTjFOSFZxUkdaTlkycEdVRXBTSWl3aWNISm1JanBiWFgwLlNqS2FIR18yQ2UwcGp1TkY1T0QtYjZqb04xU0lKTXBqS2pqbDRKRTYxX3VwT3J0dktvRFFTeFo3V2VZVkFJQVREbDhFbWNPS2o5T3FPU3cwVmc4VkNBIiwiZXlKaGJHY2lPaUpGWkVSVFFTSXNJblI1Y0NJNklrcFhWQ0lzSW5WamRpSTZJakF1T0M0eEluMC5leUpoZFdRaU9pSmthV1E2YTJWNU9ubzJUV3R5TldGbFptbHVNVVI2YWtjM1RVSktNMjV6UmtOemJuWklTMFYyVkdJeVF6UlpRVXAzWW5oME1XcEdVeUlzSW1GMGRDSTZXM3NpZDJsMGFDSTZleUp6WTJobGJXVWlPaUozYm1aeklpd2lhR2xsY2xCaGNuUWlPaUl2TDJSbGJXOTFjMlZ5TG1acGMzTnBiMjR1Ym1GdFpTOXdkV0pzYVdNdmNHaHZkRzl6THlKOUxDSmpZVzRpT25zaWJtRnRaWE53WVdObElqb2lkMjVtY3lJc0luTmxaMjFsYm5SeklqcGJJazlXUlZKWFVrbFVSU0pkZlgxZExDSmxlSEFpT2preU5UWTVNemsxTURVc0ltbHpjeUk2SW1ScFpEcHJaWGs2ZWpaTmEydFhiM0UyVXpOMGNWSlhjV3RTYm5sTlpGaG1jbk0xTkRsRlpuVTJjVU4xTkhWcVJHWk5ZMnBHVUVwU0lpd2ljSEptSWpwYlhYMC5TakthSEdfMkNlMHBqdU5GNU9ELWI2am9OMVNJSk1waktqamw0SkU2MV91cE9ydHZLb0RRU3haN1dlWVZBSUFURGw4RW1jT0tqOU9xT1N3MFZnOFZDQSJdfQ.Ab-xfYRoqYEHuo-252MKXDSiOZkLD-h1gHt8gKBP0AVdJZ6Jruv49TLZOvgWy9QkCpiwKUeGVbHodKcVx-azCQ", - "bafkreihogico5an3e2xy3fykalfwxxry7itbhfcgq6f47sif6d7w6uk2ze": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInVhdiI6IjAuMS4wIn0.eyJhdWQiOiJkaWQ6a2V5OnpTdEVacHpTTXRUdDlrMnZzemd2Q3dGNGZMUVFTeUExNVc1QVE0ejNBUjZCeDRlRko1Y3JKRmJ1R3hLbWJtYTQiLCJpc3MiOiJkaWQ6a2V5Ono1QzRmdVAyRERKQ2hoTUJDd0FrcFlVTXVKWmROV1dINU5lWWpVeVk4YnRZZnpEaDNhSHdUNXBpY0hyOVR0anEiLCJuYmYiOjE1ODg3MTM2MjIsImV4cCI6MTU4OTAwMDAwMCwic2NwIjoiLyIsInB0YyI6IkFQUEVORCIsInByZiI6bnVsbH0.Ay8C5ajYWHxtD8y0msla5IJ8VFffTHgVq448Hlr818JtNaTUzNIwFiuutEMECGTy69hV9Xu9bxGxTe0TpC7AzV34p0wSFax075mC3w9JYB8yqck_MEBg_dZ1xlJCfDve60AHseKPtbr2emp6hZVfTpQGZzusstimAxyYPrQUWv9wqTFmin0Ls-loAWamleUZoE1Tarlp_0h9SeV614RfRTC0e3x_VP9Ra_84JhJHZ7kiLf44TnyPl_9AbzuMdDwCvu-zXjd_jMlDyYcuwamJ15XqrgykLOm0WTREgr_sNLVciXBXd6EQ-Zh2L7hd38noJm1P_MIr9_EDRWAhoRLXPQ" -} + BD -->|proof| AB + BC -->|proof| AB + CD -->|proof| BC + DE -->|proof| CD + DE -->|proof| BD ``` -# 8. Token Resolution - -Token resolution is transport specific. The exact format is left to the relevant UCAN transport specification. At minimum, such a specification MUST define at least the following: - -1. Request protocol -2. Response protocol -3. Collections format +In this example, Alice MAY revoke any of the UCANs in the chain, Carol MAY revoke the bottom two, and so on. If the UCAN `Carol → Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for `X` since its proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice → Bob → Dan → Erin` includes them. Note that despite `Y` being in the revoked `Carol → Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. -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. [Alan Karp]: https://github.com/alanhkarp From 7bffa6dc6bebf2ab4bc862ea4d535ec40b4a483e Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Mon, 14 Aug 2023 21:42:07 -0700 Subject: [PATCH 04/53] Start fleshing out format --- README.md | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index bada11a..4da3f87 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ # 0. Abstract -This document describes how to revoke a previously issued delegation. +This specification describes how to revoke a previously issued UCAN delegation. ## Language @@ -19,15 +19,21 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S # 1. Introduction +Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). + +In the case of UCAN, this MUST be done by a proof's issuer DID. For more on the exact mechanism, see the revocation validation section. + ## 1.1 Motivation -## 2.9 Revocation +Even when not in error, the trust relationship between a delegator and delegatee are not immutible. While the UCAN delegation approach RECOMMENDS using the [principle of least authority][POLA], unexpected conditions can and do arise. This is an exceptional case, but is sufficiently important that a well defined method for performing revocation is needed. -Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). +## 1.1 Approach -In the case of UCAN, this MUST be done by a proof's issuer DID. For more on the exact mechanism, see the revocation validation section. +UCAN delegation is designed to be [local-first]. As such, [fail-stop] approach is thus not suitable for this context. + +UCAN revocation is accomplished with an eventually consistent mechanism. Note that the delivery tradeoff often associated with eventually consistent systems only apply in the worst case: it is entirely possible to communicate directly with the resource server for resources that have a single source of truth. The extra generality allows UCAN revocations to work with structures like [CRDT]s, operate over gossip channels, and at the edge. -## 6.6 Revocation +# 2 Semantics Any issuer of a UCAN MAY later revoke that UCAN or the capabilities that have been derived from it further downstream in a proof chain. @@ -41,15 +47,23 @@ It is RECOMMENDED that the canonical revocation store be kept as close to (or in Revocations MUST be irreversible. If the revocation was issued in error, a unique UCAN MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. -# Format +# 3 Format + +A revocation message MUST contain the following information: + +| Field | Type | Description | Required | +|-------|--------------------------|--------------------------------------------------------------|----------| +| `iss` | [DID] | The DID of the revoker | Yes | +| `rev` | [CID] | The [canonical CID] of the UCAN being revoked | Yes | +| `clg` | [base64-unpadded] string | The base64 encoded signature of `REVOKE:${canonicalUcanCid}` | Yes | -A revocation message MUST conform to the following JSON format: +Since revocations MAY be passed between systems, supporting the canonical JSON encoding is REQUIRED: ``` js { - "iss": did, - "revoke": canonicalUcanCid, - "challenge": base64Unpadded(sign(did.privateKey, `REVOKE:${canonicalUcanCid}`)) + "iss": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", + "rev": "bafkreia7l6bthgtpaaw4qbfacun6p4rt5rcorsognxgojvkyvhlmo7kf4a", + "clg": "FJi1Rnpj3/otydngacrwddFvwz/dTDsBv62uZDN2fZM" } ``` From 3d9acd30ccff44fdb20a519acc222823bdb16c46 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Mon, 14 Aug 2023 22:50:43 -0700 Subject: [PATCH 05/53] Add headers, minor rearrangement --- README.md | 82 +++++++++++++++++++++++++++---------------------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 4da3f87..e32ec46 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,12 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S # 1. Introduction -Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). - -In the case of UCAN, this MUST be done by a proof's issuer DID. For more on the exact mechanism, see the revocation validation section. - ## 1.1 Motivation -Even when not in error, the trust relationship between a delegator and delegatee are not immutible. While the UCAN delegation approach RECOMMENDS using the [principle of least authority][POLA], unexpected conditions can and do arise. This is an exceptional case, but is sufficiently important that a well defined method for performing revocation is needed. +Even when not in error, the trust relationship between a delegator and delegatee are not immutible. While the UCAN delegation approach RECOMMENDS using the [principle of least authority][POLA], unexpected conditions can and do arise. This is an exceptional case, but is sufficiently important that a well defined method for performing revocation is needed. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). + +Expiry is preferred, but +Manual method beyond expiry ## 1.1 Approach @@ -33,8 +32,12 @@ UCAN delegation is designed to be [local-first]. As such, [fail-stop] approach i UCAN revocation is accomplished with an eventually consistent mechanism. Note that the delivery tradeoff often associated with eventually consistent systems only apply in the worst case: it is entirely possible to communicate directly with the resource server for resources that have a single source of truth. The extra generality allows UCAN revocations to work with structures like [CRDT]s, operate over gossip channels, and at the edge. +In the case of UCAN, this MUST be done by a proof's issuer DID. For more on the exact mechanism, see the revocation validation section. + # 2 Semantics +- Invidates proofs, but can still be valid because constructive + Any issuer of a UCAN MAY later revoke that UCAN or the capabilities that have been derived from it further downstream in a proof chain. This mechanism is eventually consistent and SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. @@ -45,35 +48,7 @@ Every resource type SHOULD have a canonical location where its revocations are k It is RECOMMENDED that the canonical revocation store be kept as close to (or inside) the resource it is about as possible. For example, the WebNative File System maintains a Merkle tree of revoked CIDs at a well-known path. Another example is that a centralized server could have an endpoint that lists the revoked UCANs by [canonical CID]. -Revocations MUST be irreversible. If the revocation was issued in error, a unique UCAN MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. - -# 3 Format - -A revocation message MUST contain the following information: - -| Field | Type | Description | Required | -|-------|--------------------------|--------------------------------------------------------------|----------| -| `iss` | [DID] | The DID of the revoker | Yes | -| `rev` | [CID] | The [canonical CID] of the UCAN being revoked | Yes | -| `clg` | [base64-unpadded] string | The base64 encoded signature of `REVOKE:${canonicalUcanCid}` | Yes | - -Since revocations MAY be passed between systems, supporting the canonical JSON encoding is REQUIRED: - -``` js -{ - "iss": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", - "rev": "bafkreia7l6bthgtpaaw4qbfacun6p4rt5rcorsognxgojvkyvhlmo7kf4a", - "clg": "FJi1Rnpj3/otydngacrwddFvwz/dTDsBv62uZDN2fZM" -} -``` - -This format makes it easy to select the relevant UCAN, confirm that the issuer is in the proof chain for some or all capabilities, and validate that the revocation was signed by the same issuer. - -Any other proofs in the selected UCAN not issued by the same DID as the revocation issuer MUST be treated as valid. - -Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid via its proactive mechanisms. - -## 6.6.1 Example +Revocations MUST be immutible and irreversible. If the revocation was issued in error, a new unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. ``` mermaid flowchart TB @@ -103,19 +78,42 @@ flowchart TB In this example, Alice MAY revoke any of the UCANs in the chain, Carol MAY revoke the bottom two, and so on. If the UCAN `Carol → Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for `X` since its proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice → Bob → Dan → Erin` includes them. Note that despite `Y` being in the revoked `Carol → Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. +# 3 Format + +A revocation message MUST contain the following information: + +| Field | Type | Description | Required | +|-------|--------------------------|--------------------------------------------------------------|----------| +| `iss` | [DID] | The DID of the revoker | Yes | +| `rev` | [CID] | The [canonical CID] of the UCAN being revoked | Yes | +| `clg` | [base64-unpadded] string | The base64 encoded signature of `REVOKE:${canonicalUcanCid}` | Yes | + +Since revocations MAY be passed between systems, supporting the canonical JSON encoding is REQUIRED: + +``` js +{ + "iss": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", + "rev": "bafkreia7l6bthgtpaaw4qbfacun6p4rt5rcorsognxgojvkyvhlmo7kf4a", + "clg": "FJi1Rnpj3/otydngacrwddFvwz/dTDsBv62uZDN2fZM" +} +``` + +# 4 Revocation Store + +The agent that controls a resource SHOULD maintain a cache of revocations that it's seen. Other agents MAY also maintain a cache of revocations that they're aware of. + +## 4.1 Eviction + +Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid via its proactive mechanisms. + +A revocation store MOST only keep UCAN revocations for UCANs that are otherwise still valid. For example, expired UCANs are already invalid, so a revocation MUST NOT affect this invalid status. The revocation is thus redundant, and MAY be evicted from the store. + -[Alan Karp]: https://github.com/alanhkarp -[Benjamin Goering]: https://github.com/gobengo -[Biscuit]: https://github.com/biscuit-auth/biscuit/ -[Blaine Cook]: https://github.com/blaine [Bluesky]: https://blueskyweb.xyz/ -[Brendan O'Brien]: https://github.com/b5 -[Brian Ginsburg]: https://github.com/bgins [Brooklyn Zelenka]: https://github.com/expede -[CACAO]: https://blog.ceramic.network/capability-based-data-security-on-ceramic/ [CIDv1]: https://docs.ipfs.io/concepts/content-addressing/#identifier-formats -[Canonical CID]: #651-cid-canonicalization +FIXME [Canonical CID]: #651-cid-canonicalization [Capability Myths Demolished]: https://srl.cs.jhu.edu/pubs/SRL2003-02.pdf [Christine Lemmer-Webber]: https://github.com/cwebber [Christopher Joel]: https://github.com/cdata From c3e3472f36e08ab397e954a9a8ed8d70c6426e30 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 16:52:16 -0700 Subject: [PATCH 06/53] Starting the top-to-bottom --- README.md | 110 ++++++++++++++---------------------------------------- 1 file changed, 28 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index e32ec46..b1b92be 100644 --- a/README.md +++ b/README.md @@ -9,35 +9,32 @@ * [Daniel Holmgren], [Bluesky] * [Brooklyn Zelenka], [Fission] -# 0. Abstract +## Language -This specification describes how to revoke a previously issued UCAN delegation. +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP 14] ([RFC2119] and [RFC8174]) when, and only when, they appear in all capitals, as shown here. -## Language +# 0 Abstract -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119]. +This specification describes how to revoke a previously issued UCAN delegation. -# 1. Introduction +# 1 Introduction -## 1.1 Motivation +Using the [principle of least authprity][POLA] such as certificate expiry and reduced capabilty scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It is not a perfect method, and cannot undo irreversable actions already performed with capability, but MAY limit misuse going forward. -Even when not in error, the trust relationship between a delegator and delegatee are not immutible. While the UCAN delegation approach RECOMMENDS using the [principle of least authority][POLA], unexpected conditions can and do arise. This is an exceptional case, but is sufficiently important that a well defined method for performing revocation is needed. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). +## 1.1 Motivation -Expiry is preferred, but -Manual method beyond expiry +Even when not in error at time of issuance, the trust relationship between a delegator and delegatee is not immutible. An agent can go rogue, keys can be compromised, and the privacy requirements of resources changed. While the UCAN delegation approach RECOMMENDS using the [principle of least authority][POLA], such unexpected conditions can and do arise. These are exceptional cases, but are sufficiently important that a well defined method for performing revocation is nearly always desired. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). ## 1.1 Approach -UCAN delegation is designed to be [local-first]. As such, [fail-stop] approach is thus not suitable for this context. - -UCAN revocation is accomplished with an eventually consistent mechanism. Note that the delivery tradeoff often associated with eventually consistent systems only apply in the worst case: it is entirely possible to communicate directly with the resource server for resources that have a single source of truth. The extra generality allows UCAN revocations to work with structures like [CRDT]s, operate over gossip channels, and at the edge. +UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. -In the case of UCAN, this MUST be done by a proof's issuer DID. For more on the exact mechanism, see the revocation validation section. +UCAN revocation is accomplished with an eventually consistent message. Note that the delivery tradeoff often associated with eventually consistent systems only apply in the worst case: it is entirely possible to communicate directly with the resource server when there is a single source of truth. The extra generality of eventual consistency allows UCAN revocations to be compatible with the weaker assumptions in resources such as [CRDT]s, when communicating over gossip channels, and at the edge. # 2 Semantics - Invidates proofs, but can still be valid because constructive - +- [ ] Any issuer of a UCAN MAY later revoke that UCAN or the capabilities that have been derived from it further downstream in a proof chain. This mechanism is eventually consistent and SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. @@ -100,7 +97,7 @@ Since revocations MAY be passed between systems, supporting the canonical JSON e # 4 Revocation Store -The agent that controls a resource SHOULD maintain a cache of revocations that it's seen. Other agents MAY also maintain a cache of revocations that they're aware of. +The agent that controls a resource SHOULD maintain a cache of revocations that it's seen. Other agents MAY also maintain a cache of revocations that they're aware of. On recept of a UCAN delegation or invocation, the ## 4.1 Eviction @@ -108,75 +105,24 @@ Revocations MAY be deleted once the UCAN that they reference expires or otherwis A revocation store MOST only keep UCAN revocations for UCANs that are otherwise still valid. For example, expired UCANs are already invalid, so a revocation MUST NOT affect this invalid status. The revocation is thus redundant, and MAY be evicted from the store. +# 5 Prior Art + +SPKI/SDSI recovcation lists +# 6 Acknowledgements + + + + + + + + + +[BCP 14]: https://www.rfc-editor.org/info/bcp14 [Bluesky]: https://blueskyweb.xyz/ [Brooklyn Zelenka]: https://github.com/expede [CIDv1]: https://docs.ipfs.io/concepts/content-addressing/#identifier-formats -FIXME [Canonical CID]: #651-cid-canonicalization -[Capability Myths Demolished]: https://srl.cs.jhu.edu/pubs/SRL2003-02.pdf -[Christine Lemmer-Webber]: https://github.com/cwebber -[Christopher Joel]: https://github.com/cdata -[DID fragment]: https://www.w3.org/TR/did-core/#fragment -[DID path]: https://www.w3.org/TR/did-core/#path -[DID subject]: https://www.w3.org/TR/did-core/#dfn-did-subjects -[DID]: https://www.w3.org/TR/did-core/ -[Dan Finlay]: https://github.com/danfinlay -[Daniel Holmgren]: https://github.com/dholms -[ECDSA security]: https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Security -[FIDO]: https://fidoalliance.org/fido-authentication/ -[Fission]: https://fission.codes -[Hugo Dias]: https://github.com/hugomrdias -[Irakli Gozalishvili]: https://github.com/Gozala -[JWT]: https://datatracker.ietf.org/doc/html/rfc7519 -[Juan Caballero]: https://github.com/bumblefudge -[Local-First Auth]: https://github.com/local-first-web/auth -[Macaroon]: https://storage.googleapis.com/pub-tools-public-publication-data/pdf/41892.pdf -[Mark Miller]: https://github.com/erights -[Mikael Rogers]: https://github.com/mikeal/ -[OCAP]: http://erights.org/elib/capability/index.html -[OCapN]: https://github.com/ocapn/ocapn -[POLA]: https://en.wikipedia.org/wiki/Principle_of_least_privilege -[Philipp Krüger]: https://github.com/matheus23 -[Protocol Labs]: https://protocol.ai/ -[RFC 2119]: https://datatracker.ietf.org/doc/html/rfc2119 -[RFC 3339]: https://www.rfc-editor.org/rfc/rfc3339 -[RFC 8037]: https://datatracker.ietf.org/doc/html/rfc8037 -[SHA2-256]: https://en.wikipedia.org/wiki/SHA-2 -[SPKI/SDSI]: https://datatracker.ietf.org/wg/spki/about/ -[SPKI]: https://theworld.com/~cme/html/spki.html -[Seitan token exchange]: https://book.keybase.io/docs/teams/seitan -[Steven Vandevelde]: https://github.com/icidasset -[Token Uniqueness]: #622-token-uniqueness -[URI]: https://www.rfc-editor.org/rfc/rfc3986 -[Verifiable credentials]: https://www.w3.org/2017/vc/WG/ -[W3C]: https://www.w3.org/ -[ZCAP-LD]: https://w3c-ccg.github.io/zcap-spec/ -[`did:3`]: https://github.com/ceramicnetwork/CIPs/blob/main/CIPs/cip-79.md -[`did:ion`]: https://github.com/decentralized-identity/ion -[`did:key`]: https://w3c-ccg.github.io/did-method-key/ -[base32]: https://github.com/multiformats/multibase/blob/master/multibase.csv#L12 -[browser api crypto key]: https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey -[canonical collections]: #71-canonical-json-collection -[capabilities]: https://en.wikipedia.org/wiki/Object-capability_model -[caps as keys]: http://www.erights.org/elib/capability/duals/myths.html#caps-as-keys -[confinement]: http://www.erights.org/elib/capability/dist-confine.html -[constructive semantics]: https://en.wikipedia.org/wiki/Intuitionistic_logic -[content addressable storage]: https://en.wikipedia.org/wiki/Content-addressable_storage -[content addressing]: https://en.wikipedia.org/wiki/Content-addressable_storage -[content identifiers]: #65-content-identifiers -[dag-json multicodec]: https://github.com/multiformats/multicodec/blob/master/table.csv#L104 -[delegation]: #51-ucan-delegation -[disjunction]: https://en.wikipedia.org/wiki/Logical_disjunction -[invocation]: https://github.com/ucan-wg/invocation -[prf field]: #3271-prf-field -[raw data multicodec]: https://github.com/multiformats/multicodec/blob/a03169371c0a4aec0083febc996c38c3846a0914/table.csv?plain=1#L41 -[replay attack prevention]: #93-replay-attack-prevention -[revocation]: #66-revocation -[rights amplification]: #64-rights-amplification -[secure hardware enclave]: https://support.apple.com/en-ca/guide/security/sec59b0b31ff -[spki rfc]: https://www.rfc-editor.org/rfc/rfc2693.html -[time definition]: https://en.wikipedia.org/wiki/Temporal_database -[token resolution]: #8-token-resolution -[top ability]: #41-top -[ucan.xyz]: https://ucan.xyz + + From 5f99474b4162af2b23eed7f5de9c673c30ab47a3 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 17:31:52 -0700 Subject: [PATCH 07/53] Authors --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b1b92be..60bea39 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# UCAN Revocation Specification v1.0.0-RC +# UCAN Revocation Specification 1.0.0-RC.1 ## Editors @@ -6,8 +6,10 @@ ## Authors -* [Daniel Holmgren], [Bluesky] * [Brooklyn Zelenka], [Fission] +* [Daniel Holmgren], [Bluesky] +* [Irakli Gozalishvili], [Protocol Labs] +* [Philipp Krüger], [Fission] ## Language @@ -95,9 +97,9 @@ Since revocations MAY be passed between systems, supporting the canonical JSON e } ``` -# 4 Revocation Store +# 4 Cache -The agent that controls a resource SHOULD maintain a cache of revocations that it's seen. Other agents MAY also maintain a cache of revocations that they're aware of. On recept of a UCAN delegation or invocation, the +The agent that controls a resource SHOULD maintain a cache of revocations that it has seen. Other agents MAY also maintain a cache of revocations that they're aware of. On recept of a UCAN delegation or invocation, the ## 4.1 Eviction From 63cc1143925258e5a33979d04a3298573a85935c Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 17:59:47 -0700 Subject: [PATCH 08/53] Fleshing out --- README.md | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 60bea39..a9d04b5 100644 --- a/README.md +++ b/README.md @@ -37,17 +37,14 @@ UCAN revocation is accomplished with an eventually consistent message. Note that - Invidates proofs, but can still be valid because constructive - [ ] -Any issuer of a UCAN MAY later revoke that UCAN or the capabilities that have been derived from it further downstream in a proof chain. -This mechanism is eventually consistent and SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. -While some resources are centralized (e.g. access to a server), others are unbound from specific locations (e.g. a CRDT), in which case it will take longer for the revocation to propagate. -Every resource type SHOULD have a canonical location where its revocations are kept. This list is non-exclusive, and revocation messages MAY be gossiped between peers in a network to share this information more quickly. +UCAN capability revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. -It is RECOMMENDED that the canonical revocation store be kept as close to (or inside) the resource it is about as possible. For example, the WebNative File System maintains a Merkle tree of revoked CIDs at a well-known path. Another example is that a centralized server could have an endpoint that lists the revoked UCANs by [canonical CID]. +All UCAN capabilities are either claimed by direct authority over the resource, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). Any issuer in a proof chain MAY revoke access to the capabilties that it delegated anywhere in a proof chain. Note that this is not the same as revoking the specific delegation signed by the issuer: any UCAN that contains the issuer transatively in the delegation chain MAY be revoked. -Revocations MUST be immutible and irreversible. If the revocation was issued in error, a new unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. +As a concrete example: ``` mermaid flowchart TB @@ -75,7 +72,36 @@ flowchart TB DE -->|proof| BD ``` -In this example, Alice MAY revoke any of the UCANs in the chain, Carol MAY revoke the bottom two, and so on. If the UCAN `Carol → Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for `X` since its proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice → Bob → Dan → Erin` includes them. Note that despite `Y` being in the revoked `Carol → Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. +Here Alice is the root issuer. She MAY revoke any of the UCANs in the chain, Carol MAY revoke the two innermost, and so on. If the UCAN `Carol to Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for the `X` capability, since its only proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice to Bob to Dan to Erin` includes them. Note that despite `Y` being in the revoked `Carol to Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. + + + +Revocations MUST be immutible and irreversible. If the revocation was issued in error, a new unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. + +## Multiple Paths + +Revocation by a particular proof does not guarantee that the principle no longer has access to the capabilty in question. If a principal is able to construct a valid proof chain without relying on the revoked proof, they still have access to the capability. By real-world analogy, if Mallory has two tickets to a film, and one of them is invalidated by its serial number, she is still able to present the valid ticket to see the film. + + + + + + +## Consistency Models + + +### Eventual Consistency + +This mechanism is eventually consistent and SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. + +### Direct Revocation + +While some resources are centralized (e.g. access to a server), others are unbound from specific locations (e.g. a CRDT), in which case it will take longer for the revocation to propagate. + +Every resource type SHOULD have a canonical location where its revocations are kept. This list is non-exclusive, and revocation messages MAY be gossiped between peers in a network to share this information more quickly. + + + # 3 Format @@ -101,6 +127,13 @@ Since revocations MAY be passed between systems, supporting the canonical JSON e The agent that controls a resource SHOULD maintain a cache of revocations that it has seen. Other agents MAY also maintain a cache of revocations that they're aware of. On recept of a UCAN delegation or invocation, the + + + + +It is RECOMMENDED that the canonical revocation store be kept as close to (or inside) the resource it is about as possible. For example, the WebNative File System maintains a Merkle tree of revoked CIDs at a well-known path. Another example is that a centralized server could have an endpoint that lists the revoked UCANs by [canonical CID]. + + ## 4.1 Eviction Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid via its proactive mechanisms. From 9668db04396684e5ecabe32f1a91f0c482001d53 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 20:54:16 -0700 Subject: [PATCH 09/53] Rearrange --- README.md | 76 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index a9d04b5..b633c90 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# UCAN Revocation Specification 1.0.0-RC.1 +# UCAN Revocation Specification 1.0.0-rc.1 ## Editors @@ -40,11 +40,15 @@ UCAN revocation is accomplished with an eventually consistent message. Note that -UCAN capability revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. +UCAN revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. All UCAN capabilities are either claimed by direct authority over the resource, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). -All UCAN capabilities are either claimed by direct authority over the resource, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). Any issuer in a proof chain MAY revoke access to the capabilties that it delegated anywhere in a proof chain. Note that this is not the same as revoking the specific delegation signed by the issuer: any UCAN that contains the issuer transatively in the delegation chain MAY be revoked. +An issuer of a proof in a delegation chain MAY revoke access to the capabilties that it granted. Note that this is not the same as revoking the specific delegation signed by the issuer: any UCAN that contains a proof where the revoker matches the `iss` field — even transatively in the delegation chain — MAY be revoked. -As a concrete example: +Revocations MUST be immutible and irreversible. If the revocation was issued in error, a new unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. + +Revocation by a particular proof does not guarantee that the principle no longer has access to the capabilty in question. If a principal is able to construct a valid proof chain without relying on the revoked proof, they still have access to the capability. By real-world analogy, if Mallory has two tickets to a film, and one of them is invalidated by its serial number, she is still able to present the valid ticket to see the film. + +## 2.1 Revocation Scope Example ``` mermaid flowchart TB @@ -76,25 +80,16 @@ Here Alice is the root issuer. She MAY revoke any of the UCANs in the chain, Car -Revocations MUST be immutible and irreversible. If the revocation was issued in error, a new unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. - -## Multiple Paths - -Revocation by a particular proof does not guarantee that the principle no longer has access to the capabilty in question. If a principal is able to construct a valid proof chain without relying on the revoked proof, they still have access to the capability. By real-world analogy, if Mallory has two tickets to a film, and one of them is invalidated by its serial number, she is still able to present the valid ticket to see the film. - +## 2.2 Consistency Models - -## Consistency Models - - -### Eventual Consistency +### 2.2.1 Eventual Consistency This mechanism is eventually consistent and SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. -### Direct Revocation +### 2.2.2 Direct Revocation While some resources are centralized (e.g. access to a server), others are unbound from specific locations (e.g. a CRDT), in which case it will take longer for the revocation to propagate. @@ -103,27 +98,8 @@ Every resource type SHOULD have a canonical location where its revocations are k -# 3 Format - -A revocation message MUST contain the following information: - -| Field | Type | Description | Required | -|-------|--------------------------|--------------------------------------------------------------|----------| -| `iss` | [DID] | The DID of the revoker | Yes | -| `rev` | [CID] | The [canonical CID] of the UCAN being revoked | Yes | -| `clg` | [base64-unpadded] string | The base64 encoded signature of `REVOKE:${canonicalUcanCid}` | Yes | -Since revocations MAY be passed between systems, supporting the canonical JSON encoding is REQUIRED: - -``` js -{ - "iss": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", - "rev": "bafkreia7l6bthgtpaaw4qbfacun6p4rt5rcorsognxgojvkyvhlmo7kf4a", - "clg": "FJi1Rnpj3/otydngacrwddFvwz/dTDsBv62uZDN2fZM" -} -``` - -# 4 Cache +# 3 Cache The agent that controls a resource SHOULD maintain a cache of revocations that it has seen. Other agents MAY also maintain a cache of revocations that they're aware of. On recept of a UCAN delegation or invocation, the @@ -134,12 +110,38 @@ The agent that controls a resource SHOULD maintain a cache of revocations that i It is RECOMMENDED that the canonical revocation store be kept as close to (or inside) the resource it is about as possible. For example, the WebNative File System maintains a Merkle tree of revoked CIDs at a well-known path. Another example is that a centralized server could have an endpoint that lists the revoked UCANs by [canonical CID]. -## 4.1 Eviction +## 3.1 Eviction Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid via its proactive mechanisms. A revocation store MOST only keep UCAN revocations for UCANs that are otherwise still valid. For example, expired UCANs are already invalid, so a revocation MUST NOT affect this invalid status. The revocation is thus redundant, and MAY be evicted from the store. +# 4 Format + +A revocation message MUST contain the following information: + +| Field | Type | Description | Required | +|-------|--------------------------|-------------------------------------------------------|----------| +| `ucv` | [Semver] string | Version of UCAN Revocation (`1.0.0-rc.1`) | Yes | +| `iss` | [DID] | Revoker DID | Yes | +| `rvk` | [CID] | The [canonical CID] of the UCAN being revoked | Yes | +| `sig` | [base64-unpadded] string | The base64 encoded signature of `` `REVOKE:${rvk}` `` | Yes | + +Note that the revoker DID is not listed directly, since it can be inferred by inspecting the UCAN delagation being revoked. + +## 4.1 Canonicalization + +As revocations MAY be gossiped between systems, revocations MUST be encoded canconically as JSON. + +``` json +{ + "ucv": "1.0.0-rc.1", + "iss": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", + "rvk": "bafkreia7l6bthgtpaaw4qbfacun6p4rt5rcorsognxgojvkyvhlmo7kf4a", + "sig": "FJi1Rnpj3/otydngacrwddFvwz/dTDsBv62uZDN2fZM" +} +``` + # 5 Prior Art SPKI/SDSI recovcation lists From 0c74bab62c884696d68935557e0f729d384ee52f Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 21:10:59 -0700 Subject: [PATCH 10/53] Rearrange, figure number --- README.md | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index b633c90..746b8b7 100644 --- a/README.md +++ b/README.md @@ -35,20 +35,19 @@ UCAN revocation is accomplished with an eventually consistent message. Note that # 2 Semantics -- Invidates proofs, but can still be valid because constructive -- [ ] +UCAN revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. All UCAN capabilities are either claimed by direct authority over the resource, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). +Revocations MUST be immutible and irreversible. If the revocation was issued in error, a new unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. - -UCAN revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. All UCAN capabilities are either claimed by direct authority over the resource, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). +## 2.1 Scope An issuer of a proof in a delegation chain MAY revoke access to the capabilties that it granted. Note that this is not the same as revoking the specific delegation signed by the issuer: any UCAN that contains a proof where the revoker matches the `iss` field — even transatively in the delegation chain — MAY be revoked. -Revocations MUST be immutible and irreversible. If the revocation was issued in error, a new unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. - Revocation by a particular proof does not guarantee that the principle no longer has access to the capabilty in question. If a principal is able to construct a valid proof chain without relying on the revoked proof, they still have access to the capability. By real-world analogy, if Mallory has two tickets to a film, and one of them is invalidated by its serial number, she is still able to present the valid ticket to see the film. -## 2.1 Revocation Scope Example +### 2.1.1 Example + +
``` mermaid flowchart TB @@ -76,11 +75,11 @@ flowchart TB DE -->|proof| BD ``` -Here Alice is the root issuer. She MAY revoke any of the UCANs in the chain, Carol MAY revoke the two innermost, and so on. If the UCAN `Carol to Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for the `X` capability, since its only proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice to Bob to Dan to Erin` includes them. Note that despite `Y` being in the revoked `Carol to Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. - - +
Figure 1 — Revocation scope example
+
+Here Alice is the root issuer. She MAY revoke any of the UCANs in the chain, Carol MAY revoke the two innermost, and so on. If the UCAN `Carol to Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for the `X` capability, since its only proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice to Bob to Dan to Erin` includes them. Note that despite `Y` being in the revoked `Carol to Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. ## 2.2 Consistency Models @@ -118,24 +117,38 @@ A revocation store MOST only keep UCAN revocations for UCANs that are otherwise # 4 Format -A revocation message MUST contain the following information: +A revocation message MUST contain the following fields: | Field | Type | Description | Required | |-------|--------------------------|-------------------------------------------------------|----------| -| `ucv` | [Semver] string | Version of UCAN Revocation (`1.0.0-rc.1`) | Yes | +| `urv` | [Semver] string | Version of UCAN Revocation (`1.0.0-rc.1`) | Yes | | `iss` | [DID] | Revoker DID | Yes | | `rvk` | [CID] | The [canonical CID] of the UCAN being revoked | Yes | | `sig` | [base64-unpadded] string | The base64 encoded signature of `` `REVOKE:${rvk}` `` | Yes | Note that the revoker DID is not listed directly, since it can be inferred by inspecting the UCAN delagation being revoked. -## 4.1 Canonicalization +Revocations MAY be gossiped between systems. As such, they need to be parsable by a wide number of lanaguges and contexts. To accomodate this, compliant UCAN revocations MUST be JSON-encoded. + +## 4.1 `urv` Version + +The UCAN Revocation Version, i.e. the version of this document: `1.0.0-rc.1`. + +## 4.2 `iss` Issuer + +The issuer DID of this revocation. This DID MUST match one or more `iss` fields in the proof chain of the UCAN listed in the `rvk` field. This DID MUST also validate against the signature in the `sig` field. + +## 4.3 `rvk` Revoker + +The `rvk` field + +## 4.4 `sig` Signature -As revocations MAY be gossiped between systems, revocations MUST be encoded canconically as JSON. +## 4.5 Example ``` json { - "ucv": "1.0.0-rc.1", + "urv": "1.0.0-rc.1", "iss": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", "rvk": "bafkreia7l6bthgtpaaw4qbfacun6p4rt5rcorsognxgojvkyvhlmo7kf4a", "sig": "FJi1Rnpj3/otydngacrwddFvwz/dTDsBv62uZDN2fZM" From f4dc5758db127ca137661d94a4c3a9a873d24f34 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 21:23:21 -0700 Subject: [PATCH 11/53] Finish fields --- README.md | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 746b8b7..b6d6e75 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,9 @@ Using the [principle of least authprity][POLA] such as certificate expiry and re Even when not in error at time of issuance, the trust relationship between a delegator and delegatee is not immutible. An agent can go rogue, keys can be compromised, and the privacy requirements of resources changed. While the UCAN delegation approach RECOMMENDS using the [principle of least authority][POLA], such unexpected conditions can and do arise. These are exceptional cases, but are sufficiently important that a well defined method for performing revocation is nearly always desired. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). -## 1.1 Approach +## 1.2 Approach -UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. - -UCAN revocation is accomplished with an eventually consistent message. Note that the delivery tradeoff often associated with eventually consistent systems only apply in the worst case: it is entirely possible to communicate directly with the resource server when there is a single source of truth. The extra generality of eventual consistency allows UCAN revocations to be compatible with the weaker assumptions in resources such as [CRDT]s, when communicating over gossip channels, and at the edge. +UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished via an unforgable message # 2 Semantics @@ -47,8 +45,6 @@ Revocation by a particular proof does not guarantee that the principle no longer ### 2.1.1 Example -
- ``` mermaid flowchart TB subgraph RA[Alice can revoke] @@ -75,11 +71,7 @@ flowchart TB DE -->|proof| BD ``` -
Figure 1 — Revocation scope example
-
- - -Here Alice is the root issuer. She MAY revoke any of the UCANs in the chain, Carol MAY revoke the two innermost, and so on. If the UCAN `Carol to Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for the `X` capability, since its only proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice to Bob to Dan to Erin` includes them. Note that despite `Y` being in the revoked `Carol to Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. +Here Alice is the root issuer / resource owner. Alice MAY revoke any of the UCANs in the chain, Carol MAY revoke the two innermost, and so on. If the UCAN `Carol to Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for the `X` capability, since its only proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice to Bob to Dan to Erin` includes them. Note that despite `Y` being in the revoked `Carol to Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. ## 2.2 Consistency Models @@ -88,6 +80,8 @@ Here Alice is the root issuer. She MAY revoke any of the UCANs in the chain, Car This mechanism is eventually consistent and SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. +Note that the delivery tradeoff often associated with eventually consistent systems only apply in the worst case: it is entirely possible to communicate directly with the resource server when there is a single source of truth. The extra generality of eventual consistency allows UCAN revocations to be compatible with the weaker assumptions in resources such as [CRDT]s, when communicating over gossip channels, and at the edge. + ### 2.2.2 Direct Revocation While some resources are centralized (e.g. access to a server), others are unbound from specific locations (e.g. a CRDT), in which case it will take longer for the revocation to propagate. @@ -119,30 +113,32 @@ A revocation store MOST only keep UCAN revocations for UCANs that are otherwise A revocation message MUST contain the following fields: -| Field | Type | Description | Required | -|-------|--------------------------|-------------------------------------------------------|----------| -| `urv` | [Semver] string | Version of UCAN Revocation (`1.0.0-rc.1`) | Yes | -| `iss` | [DID] | Revoker DID | Yes | -| `rvk` | [CID] | The [canonical CID] of the UCAN being revoked | Yes | -| `sig` | [base64-unpadded] string | The base64 encoded signature of `` `REVOKE:${rvk}` `` | Yes | - -Note that the revoker DID is not listed directly, since it can be inferred by inspecting the UCAN delagation being revoked. +| Field | Type | Description | Required | +|-------|--------------------------|------------------------------------------------------------|----------| +| `urv` | [Semver] string | Version of UCAN Revocation (`1.0.0-rc.1`) | Yes | +| `iss` | [DID] | Revoker DID | Yes | +| `rvk` | [CID] | The [canonical CID] of the UCAN being revoked | Yes | +| `sig` | [base64-unpadded] string | The base64 encoded signature of `` `REVOKE-UCAN:${rvk}` `` | Yes | Revocations MAY be gossiped between systems. As such, they need to be parsable by a wide number of lanaguges and contexts. To accomodate this, compliant UCAN revocations MUST be JSON-encoded. -## 4.1 `urv` Version +## 4.1 `urv` UCAN Revocation Version The UCAN Revocation Version, i.e. the version of this document: `1.0.0-rc.1`. -## 4.2 `iss` Issuer +## 4.2 `iss` Revocation Issuer The issuer DID of this revocation. This DID MUST match one or more `iss` fields in the proof chain of the UCAN listed in the `rvk` field. This DID MUST also validate against the signature in the `sig` field. -## 4.3 `rvk` Revoker +## 4.3 `rvk` Revoked UCAN + +The `rvk` field MUST contain the [canonical CID] for the UCAN delegation being revoked. The target UCAN MUST contain a (potentially nested) UCAN proof where the `iss` field matches the `iss` field of this revocation. + +Note that this revocation MUST only revoke the particular capabilities from the relevant proof(s). The resultant proof chain MUST be treated as if that proof were not present, with no other changes. -The `rvk` field +## 4.4 `sig` Prefixed Signature -## 4.4 `sig` Signature +The `sig` field MUST contain a signature that validates against the revoker's DID. The format to sign over MUST be prefixed with the UTF-8 string `REVOKE-UCAN:`, followed by the CID from the `rvk` field. ## 4.5 Example From da8dcee45e58741b15027bb0a8b33444daaeee00 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 21:51:41 -0700 Subject: [PATCH 12/53] Cleanup consistency --- README.md | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index b6d6e75..99c7f9a 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,18 @@ UCAN revocation is the act of invalidating a proof in a delegation chain for som Revocations MUST be immutible and irreversible. If the revocation was issued in error, a new unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. + + + + + + +passing and SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. + + + + + ## 2.1 Scope An issuer of a proof in a delegation chain MAY revoke access to the capabilties that it granted. Note that this is not the same as revoking the specific delegation signed by the issuer: any UCAN that contains a proof where the revoker matches the `iss` field — even transatively in the delegation chain — MAY be revoked. @@ -75,29 +87,18 @@ Here Alice is the root issuer / resource owner. Alice MAY revoke any of the UCAN ## 2.2 Consistency Models +UCAN revocation is designed to work in the broadest possible scenarios, and as such needs very weak constraints. UCAN revocation MAY operate in fully eventually consistent contexts, with single sources of truth, or among nodes participating in consensus. The format of the revocation does not change in these situations; it is entirely managed by how revocations are passed around the network. -### 2.2.1 Eventual Consistency - -This mechanism is eventually consistent and SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. - -Note that the delivery tradeoff often associated with eventually consistent systems only apply in the worst case: it is entirely possible to communicate directly with the resource server when there is a single source of truth. The extra generality of eventual consistency allows UCAN revocations to be compatible with the weaker assumptions in resources such as [CRDT]s, when communicating over gossip channels, and at the edge. - -### 2.2.2 Direct Revocation - -While some resources are centralized (e.g. access to a server), others are unbound from specific locations (e.g. a CRDT), in which case it will take longer for the revocation to propagate. - -Every resource type SHOULD have a canonical location where its revocations are kept. This list is non-exclusive, and revocation messages MAY be gossiped between peers in a network to share this information more quickly. - - - - +These weak assumptions are often associated with being unable to guarantee delivery in a certain time bound. Weak assumptions can always be strengthened, but not vice-versa. For example, if a capability describes access to a resource with a single location or souce of truth, sending a revocation to that specific agent enables confirmatation in bounded time. This grants nearly idential semantics that many people turn to ACLs for, but with all of the benefits of capabilties. # 3 Cache The agent that controls a resource SHOULD maintain a cache of revocations that it has seen. Other agents MAY also maintain a cache of revocations that they're aware of. On recept of a UCAN delegation or invocation, the +kepp them close to eth reouce +MAY hold on to extra ones for othrs It is RECOMMENDED that the canonical revocation store be kept as close to (or inside) the resource it is about as possible. For example, the WebNative File System maintains a Merkle tree of revoked CIDs at a well-known path. Another example is that a centralized server could have an endpoint that lists the revoked UCANs by [canonical CID]. From dd831d78e4c51fdbe53e0112cfb602a548f421d4 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 22:13:01 -0700 Subject: [PATCH 13/53] Flesh out many sections --- README.md | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 99c7f9a..9ce8be0 100644 --- a/README.md +++ b/README.md @@ -13,15 +13,15 @@ ## Language -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP 14] ([RFC2119] and [RFC8174]) when, and only when, they appear in all capitals, as shown here. +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP 14] when, and only when, they appear in all capitals, as shown here. # 0 Abstract -This specification describes how to revoke a previously issued UCAN delegation. +This specification describes the format and semantics for revoking a previously issued UCAN delegation. # 1 Introduction -Using the [principle of least authprity][POLA] such as certificate expiry and reduced capabilty scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It is not a perfect method, and cannot undo irreversable actions already performed with capability, but MAY limit misuse going forward. +Using the [principle of least authority][POLA] such as certificate expiry and reduced capabilty scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It is not a perfect method, and cannot undo irreversable actions already performed with capability, but MAY limit misuse going forward. ## 1.1 Motivation @@ -29,25 +29,15 @@ Even when not in error at time of issuance, the trust relationship between a del ## 1.2 Approach -UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished via an unforgable message +UCAN Rovocations are similar to [blocklists]: they identify delegations that are retracted and no longer suitable for use. Revocation SHOULD considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. + +UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished via delivery of an unforgable message from a previous delegator. # 2 Semantics UCAN revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. All UCAN capabilities are either claimed by direct authority over the resource, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). -Revocations MUST be immutible and irreversible. If the revocation was issued in error, a new unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes revocation stores append-only and highly amenable to caching. - - - - - - - -passing and SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. - - - - +Revocations MUST be immutible and irreversible. Recipients of revocations SHOULD treat them as a grow-only set (see [XYZ] for eviction policies). If a revocation was issued in error, it MUST NOT be retracted — a new, unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes [revocation stores] append-only and highly amenable to caching. ## 2.1 Scope @@ -87,24 +77,26 @@ Here Alice is the root issuer / resource owner. Alice MAY revoke any of the UCAN ## 2.2 Consistency Models -UCAN revocation is designed to work in the broadest possible scenarios, and as such needs very weak constraints. UCAN revocation MAY operate in fully eventually consistent contexts, with single sources of truth, or among nodes participating in consensus. The format of the revocation does not change in these situations; it is entirely managed by how revocations are passed around the network. +UCAN revocation is designed to work in the broadest possible scenarios, and as such needs very weak constraints. UCAN revocation MAY operate in fully eventually consistent contexts, with single sources of truth, or among nodes participating in consensus. The format of the revocation does not change in these situations; it is entirely managed by how revocations are passed around the network. +Weak assumptions enable UCAN to work with eventually consistent resources, such as [CRDT]s, [Git] forks, delay-tolerant replicated state machines, and so on. -These weak assumptions are often associated with being unable to guarantee delivery in a certain time bound. Weak assumptions can always be strengthened, but not vice-versa. For example, if a capability describes access to a resource with a single location or souce of truth, sending a revocation to that specific agent enables confirmatation in bounded time. This grants nearly idential semantics that many people turn to ACLs for, but with all of the benefits of capabilties. +These weak assumptions are often associated with being unable to guarantee delivery in a certain time bound. Weak assumptions can always be strengthened, but not vice-versa. For example, if a capability describes access to a resource with a single location or souce of truth, sending a revocation to that specific agent enables confirmatation in bounded time. This grants nearly idential semantics that many people turn to [ACL]s for, but with all of the benefits of capabilties during delegation and invocation. # 3 Cache -The agent that controls a resource SHOULD maintain a cache of revocations that it has seen. Other agents MAY also maintain a cache of revocations that they're aware of. On recept of a UCAN delegation or invocation, the - +The agent that controls a resource SHOULD maintain a cache of revocations that it has seen. Agents are not limited to only storing revocations for resources that they control. -kepp them close to eth reouce +During validation of a UCAN delegation chain, the [canonical CID] of each UCAN delegation MUST be checked agianst the cache. If there's a match, the relevenat delegation MUST be ignored. Note that this MAY NOT invalidate the entire UCAN chain. -MAY hold on to extra ones for othrs +## 3.1 Locality +Revocation caches SHOULD be kept as close to the resource they describe as possible. -It is RECOMMENDED that the canonical revocation store be kept as close to (or inside) the resource it is about as possible. For example, the WebNative File System maintains a Merkle tree of revoked CIDs at a well-known path. Another example is that a centralized server could have an endpoint that lists the revoked UCANs by [canonical CID]. +Resources with a single source of truth SHOULD follow the typical approach of maintaining a revication store at the same physical location as the resoucre. For exmape, a centralized server MAY have an endpoint that lists the revoked UCANs by [canonical CID]. +For eventually consistent data structures, this MAY be achieved by including the store directly inside the resource itself. For example, a CRDT-based file system SHOULD maintain the revocation store directly at a well-known path. -## 3.1 Eviction +## 3.2 Eviction Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid via its proactive mechanisms. From bd08abbe9bf44a2720fe5ba583ef26effa381d04 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 22:24:34 -0700 Subject: [PATCH 14/53] Starting on prior art --- README.md | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9ce8be0..b891086 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ A revocation message MUST contain the following fields: |-------|--------------------------|------------------------------------------------------------|----------| | `urv` | [Semver] string | Version of UCAN Revocation (`1.0.0-rc.1`) | Yes | | `iss` | [DID] | Revoker DID | Yes | -| `rvk` | [CID] | The [canonical CID] of the UCAN being revoked | Yes | +| `rvk` | [CIDv1] | The [canonical CID] of the UCAN being revoked | Yes | | `sig` | [base64-unpadded] string | The base64 encoded signature of `` `REVOKE-UCAN:${rvk}` `` | Yes | Revocations MAY be gossiped between systems. As such, they need to be parsable by a wide number of lanaguges and contexts. To accomodate this, compliant UCAN revocations MUST be JSON-encoded. @@ -131,7 +131,7 @@ Note that this revocation MUST only revoke the particular capabilities from the ## 4.4 `sig` Prefixed Signature -The `sig` field MUST contain a signature that validates against the revoker's DID. The format to sign over MUST be prefixed with the UTF-8 string `REVOKE-UCAN:`, followed by the CID from the `rvk` field. +The `sig` field MUST contain a signature that validates against the revoker's DID. The format to sign over MUST be prefixed with the UTF-8 string `REVOKE-UCAN:`, followed by the CID from the `rvk` field. Note that the prefix contains no spaces. ## 4.5 Example @@ -146,22 +146,54 @@ The `sig` field MUST contain a signature that validates against the revoker's DI # 5 Prior Art -SPKI/SDSI recovcation lists +[SPKI/SDSI] is closely related to UCAN. A different format is used, and some details vary (such as a delegation-locking bit), but the core idea and general usage pattern are very close. UCAN can be seen as making these ideas more palatable to a modern audience and adding a few features such as content IDs that were less widespread at the time SPKI/SDSI were written. + +[ZCAP-LD] is closely related to UCAN. The primary differences are in formatting, addressing by URL instead of CID, the mechanism of separating invocation from authorization, and single versus multiple proofs. + +[OAuth 2.0 Revocation][RFC 7009] + + +Verfiable crednetial revocations + # 6 Acknowledgements +Thank you [Blaine Cook] for the real-world feedback, ideas on future features, and lessons from other auth standards. +Thanks to [Juan Caballero] for the numerous questions, clarifications, and general advice on putting together a comprehensible spec. +Many thanks to [Alan Karp] for sharing his vast experience with capability-based authorization, patterns, and many right words for us to search for. +Thanks to [Benjamin Goering] for the many community threads and connections to [W3C] standards. +Many thanks to [Christine Lemmer-Webber] for her handwritten(!) feedback on the design of UCAN, spearheading the [OCapN] initiative, and her related work on [ZCAP-LD]. + +Thanks to the entire [SPKI WG][SPKI/SDSI] for their closely related pioneering work. + +We want to especially recognize [Mark Miller] for his numerous contributions to the field of distributed auth, programming languages, and computer security writ large. + + +[Alan Karp]: https://github.com/alanhkarp [BCP 14]: https://www.rfc-editor.org/info/bcp14 [Bluesky]: https://blueskyweb.xyz/ [Brooklyn Zelenka]: https://github.com/expede [CIDv1]: https://docs.ipfs.io/concepts/content-addressing/#identifier-formats - - +[Christine Lemmer-Webber]: https://github.com/cwebber +[DID]: https://www.w3.org/TR/did-core/ +[Daniel Holmgren]: https://github.com/dholms +[Fission]: https://fission.codes +[Irakli Gozalishvili]: https://github.com/Gozala +[Mark Miller]: https://github.com/erights +[OCAP]: http://erights.org/elib/capability/index.html +[OCapN]: https://github.com/ocapn/ocapn +[POLA]: https://en.wikipedia.org/wiki/Principle_of_least_privilege +[Protocol Labs]: https://protocol.ai/ +[RFC 7009]: https://datatracker.ietf.org/doc/html/rfc7009 +[SPKI/SDSI]: https://datatracker.ietf.org/wg/spki/about/ +[VC Revocations]: https://w3c-ccg.github.io/vc-status-rl-2020/ +[ZCAP-LD]: https://w3c-ccg.github.io/zcap-spec/ From 74e1912149fb7bdf86e178b97609007b03ea0fd3 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 23:00:14 -0700 Subject: [PATCH 15/53] Working on prior art --- README.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b891086..7a153f1 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,8 @@ Weak assumptions enable UCAN to work with eventually consistent resources, such These weak assumptions are often associated with being unable to guarantee delivery in a certain time bound. Weak assumptions can always be strengthened, but not vice-versa. For example, if a capability describes access to a resource with a single location or souce of truth, sending a revocation to that specific agent enables confirmatation in bounded time. This grants nearly idential semantics that many people turn to [ACL]s for, but with all of the benefits of capabilties during delegation and invocation. +Out of order delivery is typical of distributed systems. Further, a mallicious user can otherwise delay revealing that they have a capability until the last possible moment in hopes of evading detection. Accepting revocations for resources that the agent controls prior to the delegation targeted by the revocaton is recieved is thus RECOMMENDED. + # 3 Cache The agent that controls a resource SHOULD maintain a cache of revocations that it has seen. Agents are not limited to only storing revocations for resources that they control. @@ -104,7 +106,7 @@ A revocation store MOST only keep UCAN revocations for UCANs that are otherwise # 4 Format -A revocation message MUST contain the following fields: +A revocation message MUST contain the following information: | Field | Type | Description | Required | |-------|--------------------------|------------------------------------------------------------|----------| @@ -146,15 +148,21 @@ The `sig` field MUST contain a signature that validates against the revoker's DI # 5 Prior Art +[Revocation lists][Cert Revocation Wikipedia] are a well + [SPKI/SDSI] is closely related to UCAN. A different format is used, and some details vary (such as a delegation-locking bit), but the core idea and general usage pattern are very close. UCAN can be seen as making these ideas more palatable to a modern audience and adding a few features such as content IDs that were less widespread at the time SPKI/SDSI were written. -[ZCAP-LD] is closely related to UCAN. The primary differences are in formatting, addressing by URL instead of CID, the mechanism of separating invocation from authorization, and single versus multiple proofs. +[X.509 Certificate Revocation Lists][RFC 5280] defines two kinds of certificate invalidaton: temporary ("hold") and permanent ("revocation"). This RFC also includes a field for indicating a reason for revocation. UCAN Revocation has no concept of a temporary hold on a capabilty, but this behaviour MAY be emulated by revoking a credential and issuing a new UCAN with a `nbf` field set to a time in the future. + +[ZCAP-LD] is closely related to UCAN, but situated in the W3C-style linked data world (the "LD" in ZCAP-LD). Revocation in ZCAP-LD is only granted to those who have a special caveat on a capabilty. In contrast, UCAN capabilties MAY be revoked by anyone in the relevant deleagtion path. + +[OAuth 2.0 Revocation][RFC 7009] is very similar to UCAN revocation. It is largely concerned with the HTTP interactions to make OAuth revocation work. OAuth doesn't have a concept of subdelegation, so only the user that has been granted the token can revoke it. However, this may cascade to revocation of other tokens, but the exact mechanism is left to the implementer. -[OAuth 2.0 Revocation][RFC 7009] +The [Verfiable Credential Revocation][VC Revocation] spec follows a similar -Verfiable crednetial revocations +[Object capabilities] use active nework connections to revoke delegations. This is typically achieved by delegating access to a proxy agent, and later shutting down that proxy to break the authority. In many ways, UCAN Revocation attempts to emulate this behaviour. Unlike UCAN REvocations, E-style object capabilities are [fail-stop] and thus by defnition not partition tolerant. # 6 Acknowledgements @@ -180,20 +188,24 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [Alan Karp]: https://github.com/alanhkarp [BCP 14]: https://www.rfc-editor.org/info/bcp14 +[Blaine Cook]: https://github.com/blaine [Bluesky]: https://blueskyweb.xyz/ [Brooklyn Zelenka]: https://github.com/expede [CIDv1]: https://docs.ipfs.io/concepts/content-addressing/#identifier-formats +[Cert Revocation Wikipedia]: https://en.wikipedia.org/wiki/Certificate_revocation_list [Christine Lemmer-Webber]: https://github.com/cwebber [DID]: https://www.w3.org/TR/did-core/ [Daniel Holmgren]: https://github.com/dholms [Fission]: https://fission.codes [Irakli Gozalishvili]: https://github.com/Gozala +[Juan Caballero]: https://github.com/bumblefudge [Mark Miller]: https://github.com/erights [OCAP]: http://erights.org/elib/capability/index.html [OCapN]: https://github.com/ocapn/ocapn [POLA]: https://en.wikipedia.org/wiki/Principle_of_least_privilege [Protocol Labs]: https://protocol.ai/ +[RFC 5280]: https://www.rfc-editor.org/rfc/rfc5280 [RFC 7009]: https://datatracker.ietf.org/doc/html/rfc7009 [SPKI/SDSI]: https://datatracker.ietf.org/wg/spki/about/ -[VC Revocations]: https://w3c-ccg.github.io/vc-status-rl-2020/ +[VC Revocation]: https://w3c-ccg.github.io/vc-status-rl-2020/ [ZCAP-LD]: https://w3c-ccg.github.io/zcap-spec/ From d92bfbf7b02247b1a67f446437fd81275a98ad43 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 23:13:49 -0700 Subject: [PATCH 16/53] Fixup links --- README.md | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7a153f1..35ba551 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ These weak assumptions are often associated with being unable to guarantee deliv Out of order delivery is typical of distributed systems. Further, a mallicious user can otherwise delay revealing that they have a capability until the last possible moment in hopes of evading detection. Accepting revocations for resources that the agent controls prior to the delegation targeted by the revocaton is recieved is thus RECOMMENDED. -# 3 Cache +# 3 Store The agent that controls a resource SHOULD maintain a cache of revocations that it has seen. Agents are not limited to only storing revocations for resources that they control. @@ -148,7 +148,7 @@ The `sig` field MUST contain a signature that validates against the revoker's DI # 5 Prior Art -[Revocation lists][Cert Revocation Wikipedia] are a well +[Revocation lists][Cert Revocation Wikipedia] are a fairly widely used concept. [SPKI/SDSI] is closely related to UCAN. A different format is used, and some details vary (such as a delegation-locking bit), but the core idea and general usage pattern are very close. UCAN can be seen as making these ideas more palatable to a modern audience and adding a few features such as content IDs that were less widespread at the time SPKI/SDSI were written. @@ -158,11 +158,9 @@ The `sig` field MUST contain a signature that validates against the revoker's DI [OAuth 2.0 Revocation][RFC 7009] is very similar to UCAN revocation. It is largely concerned with the HTTP interactions to make OAuth revocation work. OAuth doesn't have a concept of subdelegation, so only the user that has been granted the token can revoke it. However, this may cascade to revocation of other tokens, but the exact mechanism is left to the implementer. +While strctly speaking being about assertions rather than capabilities, [Verfiable Credential Revocation][VC Revocation] spec follows a similar pattern to those listed above. -The [Verfiable Credential Revocation][VC Revocation] spec follows a similar - - -[Object capabilities] use active nework connections to revoke delegations. This is typically achieved by delegating access to a proxy agent, and later shutting down that proxy to break the authority. In many ways, UCAN Revocation attempts to emulate this behaviour. Unlike UCAN REvocations, E-style object capabilities are [fail-stop] and thus by defnition not partition tolerant. +[E][E-lang]-style [object capabilities][Robust Composition] use active nework connections with [proxy agents][Robust Composition] to revoke delegations. Revocation is achoeved by shutting down that proxy to break the authorizing reference. In many ways, UCAN Revocation attempts to emulate this behaviour. Unlike UCAN REvocations, E-style object capabilities are [fail-stop] and thus by defnition not partition tolerant. # 6 Acknowledgements @@ -182,30 +180,42 @@ We want to especially recognize [Mark Miller] for his numerous contributions to - +[revocation stores]: #3-store +[ACL]: https://en.wikipedia.org/wiki/Access-control_list [Alan Karp]: https://github.com/alanhkarp [BCP 14]: https://www.rfc-editor.org/info/bcp14 +[Benjamin Goering]: https://github.com/gobengo [Blaine Cook]: https://github.com/blaine [Bluesky]: https://blueskyweb.xyz/ [Brooklyn Zelenka]: https://github.com/expede [CIDv1]: https://docs.ipfs.io/concepts/content-addressing/#identifier-formats +[CRDT]: https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type [Cert Revocation Wikipedia]: https://en.wikipedia.org/wiki/Certificate_revocation_list [Christine Lemmer-Webber]: https://github.com/cwebber [DID]: https://www.w3.org/TR/did-core/ [Daniel Holmgren]: https://github.com/dholms +[E-lang]: http://erights.org/elang/ [Fission]: https://fission.codes +[Git]: https://git-scm.com/ [Irakli Gozalishvili]: https://github.com/Gozala [Juan Caballero]: https://github.com/bumblefudge [Mark Miller]: https://github.com/erights [OCAP]: http://erights.org/elib/capability/index.html [OCapN]: https://github.com/ocapn/ocapn [POLA]: https://en.wikipedia.org/wiki/Principle_of_least_privilege +[Philipp Krüger]: https://github.com/matheus23 [Protocol Labs]: https://protocol.ai/ [RFC 5280]: https://www.rfc-editor.org/rfc/rfc5280 [RFC 7009]: https://datatracker.ietf.org/doc/html/rfc7009 +[Robust Composition]: https://jscholarship.library.jhu.edu/bitstream/handle/1774.2/873/markm-thesis.pdf?page=100 [SPKI/SDSI]: https://datatracker.ietf.org/wg/spki/about/ [VC Revocation]: https://w3c-ccg.github.io/vc-status-rl-2020/ +[W3C]: https://www.w3.org/ [ZCAP-LD]: https://w3c-ccg.github.io/zcap-spec/ +[blocklists]: https://en.wikipedia.org/w/index.php?title=Block_list&redirect=no +[canonical CID]: https://github.com/ucan-wg/spec/blob/d5a844cceff569838881c7fa30ff4bfad338e771/README.md?plain=1#L800-L807 +[fail-stop]: https://en.wikipedia.org/wiki/Fail-stop +[local-first]: https://www.inkandswitch.com/local-first/ From 878c3056ac359dc47f03c38a70829313a19c769c Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 23:15:56 -0700 Subject: [PATCH 17/53] add links --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 35ba551..0f22555 100644 --- a/README.md +++ b/README.md @@ -108,12 +108,12 @@ A revocation store MOST only keep UCAN revocations for UCANs that are otherwise A revocation message MUST contain the following information: -| Field | Type | Description | Required | -|-------|--------------------------|------------------------------------------------------------|----------| -| `urv` | [Semver] string | Version of UCAN Revocation (`1.0.0-rc.1`) | Yes | -| `iss` | [DID] | Revoker DID | Yes | -| `rvk` | [CIDv1] | The [canonical CID] of the UCAN being revoked | Yes | -| `sig` | [base64-unpadded] string | The base64 encoded signature of `` `REVOKE-UCAN:${rvk}` `` | Yes | +| Field | Type | Description | Required | +|-------|------------------------------------|------------------------------------------------------------|----------| +| `urv` | [Semver] string | Version of UCAN Revocation (`1.0.0-rc.1`) | Yes | +| `iss` | [DID] | Revoker DID | Yes | +| `rvk` | [CIDv1] | The [canonical CID] of the UCAN being revoked | Yes | +| `sig` | [base64-unpadded][RFC 4648] string | The base64 encoded signature of `` `REVOKE-UCAN:${rvk}` `` | Yes | Revocations MAY be gossiped between systems. As such, they need to be parsable by a wide number of lanaguges and contexts. To accomodate this, compliant UCAN revocations MUST be JSON-encoded. @@ -208,10 +208,12 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [POLA]: https://en.wikipedia.org/wiki/Principle_of_least_privilege [Philipp Krüger]: https://github.com/matheus23 [Protocol Labs]: https://protocol.ai/ +[RFC 4648]: https://www.rfc-editor.org/rfc/rfc4648.html [RFC 5280]: https://www.rfc-editor.org/rfc/rfc5280 [RFC 7009]: https://datatracker.ietf.org/doc/html/rfc7009 [Robust Composition]: https://jscholarship.library.jhu.edu/bitstream/handle/1774.2/873/markm-thesis.pdf?page=100 [SPKI/SDSI]: https://datatracker.ietf.org/wg/spki/about/ +[Semver]: https://semver.org/ [VC Revocation]: https://w3c-ccg.github.io/vc-status-rl-2020/ [W3C]: https://www.w3.org/ [ZCAP-LD]: https://w3c-ccg.github.io/zcap-spec/ From a5d54af257cc3b009b529a60c84a4962375036be Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 23:17:20 -0700 Subject: [PATCH 18/53] Internal link --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f22555..68b6062 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches UCAN revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. All UCAN capabilities are either claimed by direct authority over the resource, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). -Revocations MUST be immutible and irreversible. Recipients of revocations SHOULD treat them as a grow-only set (see [XYZ] for eviction policies). If a revocation was issued in error, it MUST NOT be retracted — a new, unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes [revocation stores] append-only and highly amenable to caching. +Revocations MUST be immutible and irreversible. Recipients of revocations SHOULD treat them as a grow-only set (see the [eviction] section). If a revocation was issued in error, it MUST NOT be retracted — a new, unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes [revocation stores] append-only and highly amenable to caching. ## 2.1 Scope @@ -180,6 +180,7 @@ We want to especially recognize [Mark Miller] for his numerous contributions to +[eviction]: #32-eviction [revocation stores]: #3-store From e4eb1fae2b39e11cce6b68d6ad695266366bcf0b Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 23:21:58 -0700 Subject: [PATCH 19/53] Spelling --- .custom-words.txt | 8 ++++++++ README.md | 18 +++++++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.custom-words.txt b/.custom-words.txt index 77a3e0d..3ffa5e4 100644 --- a/.custom-words.txt +++ b/.custom-words.txt @@ -1,5 +1,6 @@ ACL ACLs +Acknowledgements AlicePhone AliceRoot Attenuations @@ -43,6 +44,7 @@ Memoized Merkle Mikael MkiTBz +OAuth OCAP OCapN PITM @@ -60,6 +62,7 @@ SPKI ScopeA ScopeB Seitan +Semver Subschemes TXT TypeScript @@ -68,6 +71,7 @@ UCAN's UCANs URI URIs +UTF Vandevelde WG WebNative @@ -119,6 +123,9 @@ multicodec namespace namespaced namespaces +naud +ncap +niss nota plaintext potencies @@ -129,6 +136,7 @@ reauthorizations recommentations redelegate redelegates +revoker's rootAud rootCap rootIss diff --git a/README.md b/README.md index 68b6062..05225ae 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ This specification describes the format and semantics for revoking a previously # 1 Introduction -Using the [principle of least authority][POLA] such as certificate expiry and reduced capabilty scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It is not a perfect method, and cannot undo irreversable actions already performed with capability, but MAY limit misuse going forward. +Using the [principle of least authority][POLA] such as certificate expiry and reduced capability scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It is not a perfect method, and cannot undo irreversable actions already performed with capability, but MAY limit misuse going forward. ## 1.1 Motivation @@ -41,9 +41,9 @@ Revocations MUST be immutible and irreversible. Recipients of revocations SHOULD ## 2.1 Scope -An issuer of a proof in a delegation chain MAY revoke access to the capabilties that it granted. Note that this is not the same as revoking the specific delegation signed by the issuer: any UCAN that contains a proof where the revoker matches the `iss` field — even transatively in the delegation chain — MAY be revoked. +An issuer of a proof in a delegation chain MAY revoke access to the capabilities that it granted. Note that this is not the same as revoking the specific delegation signed by the issuer: any UCAN that contains a proof where the revoker matches the `iss` field — even transatively in the delegation chain — MAY be revoked. -Revocation by a particular proof does not guarantee that the principle no longer has access to the capabilty in question. If a principal is able to construct a valid proof chain without relying on the revoked proof, they still have access to the capability. By real-world analogy, if Mallory has two tickets to a film, and one of them is invalidated by its serial number, she is still able to present the valid ticket to see the film. +Revocation by a particular proof does not guarantee that the principle no longer has access to the capability in question. If a principal is able to construct a valid proof chain without relying on the revoked proof, they still have access to the capability. By real-world analogy, if Mallory has two tickets to a film, and one of them is invalidated by its serial number, she is still able to present the valid ticket to see the film. ### 2.1.1 Example @@ -80,7 +80,7 @@ Here Alice is the root issuer / resource owner. Alice MAY revoke any of the UCAN UCAN revocation is designed to work in the broadest possible scenarios, and as such needs very weak constraints. UCAN revocation MAY operate in fully eventually consistent contexts, with single sources of truth, or among nodes participating in consensus. The format of the revocation does not change in these situations; it is entirely managed by how revocations are passed around the network. Weak assumptions enable UCAN to work with eventually consistent resources, such as [CRDT]s, [Git] forks, delay-tolerant replicated state machines, and so on. -These weak assumptions are often associated with being unable to guarantee delivery in a certain time bound. Weak assumptions can always be strengthened, but not vice-versa. For example, if a capability describes access to a resource with a single location or souce of truth, sending a revocation to that specific agent enables confirmatation in bounded time. This grants nearly idential semantics that many people turn to [ACL]s for, but with all of the benefits of capabilties during delegation and invocation. +These weak assumptions are often associated with being unable to guarantee delivery in a certain time bound. Weak assumptions can always be strengthened, but not vice-versa. For example, if a capability describes access to a resource with a single location or souce of truth, sending a revocation to that specific agent enables confirmatation in bounded time. This grants nearly idential semantics that many people turn to [ACL]s for, but with all of the benefits of capabilities during delegation and invocation. Out of order delivery is typical of distributed systems. Further, a mallicious user can otherwise delay revealing that they have a capability until the last possible moment in hopes of evading detection. Accepting revocations for resources that the agent controls prior to the delegation targeted by the revocaton is recieved is thus RECOMMENDED. @@ -152,15 +152,15 @@ The `sig` field MUST contain a signature that validates against the revoker's DI [SPKI/SDSI] is closely related to UCAN. A different format is used, and some details vary (such as a delegation-locking bit), but the core idea and general usage pattern are very close. UCAN can be seen as making these ideas more palatable to a modern audience and adding a few features such as content IDs that were less widespread at the time SPKI/SDSI were written. -[X.509 Certificate Revocation Lists][RFC 5280] defines two kinds of certificate invalidaton: temporary ("hold") and permanent ("revocation"). This RFC also includes a field for indicating a reason for revocation. UCAN Revocation has no concept of a temporary hold on a capabilty, but this behaviour MAY be emulated by revoking a credential and issuing a new UCAN with a `nbf` field set to a time in the future. +[X.509 Certificate Revocation Lists][RFC 5280] defines two kinds of certificate invalication: temporary ("hold") and permanent ("revocation"). This RFC also includes a field for indicating a reason for revocation. UCAN Revocation has no concept of a temporary hold on a capability, but this behavior MAY be emulated by revoking a credential and issuing a new UCAN with a `nbf` field set to a time in the future. -[ZCAP-LD] is closely related to UCAN, but situated in the W3C-style linked data world (the "LD" in ZCAP-LD). Revocation in ZCAP-LD is only granted to those who have a special caveat on a capabilty. In contrast, UCAN capabilties MAY be revoked by anyone in the relevant deleagtion path. +[ZCAP-LD] is closely related to UCAN, but situated in the W3C-style linked data world (the "LD" in ZCAP-LD). Revocation in ZCAP-LD is only granted to those who have a special caveat on a capability. In contrast, UCAN capabilities MAY be revoked by anyone in the relevant delegation path. -[OAuth 2.0 Revocation][RFC 7009] is very similar to UCAN revocation. It is largely concerned with the HTTP interactions to make OAuth revocation work. OAuth doesn't have a concept of subdelegation, so only the user that has been granted the token can revoke it. However, this may cascade to revocation of other tokens, but the exact mechanism is left to the implementer. +[OAuth 2.0 Revocation][RFC 7009] is very similar to UCAN revocation. It is largely concerned with the HTTP interactions to make OAuth revocation work. OAuth doesn't have a concept of sub-delegation, so only the user that has been granted the token can revoke it. However, this may cascade to revocation of other tokens, but the exact mechanism is left to the implementer. -While strctly speaking being about assertions rather than capabilities, [Verfiable Credential Revocation][VC Revocation] spec follows a similar pattern to those listed above. +While strictly speaking being about assertions rather than capabilities, [Verfiable Credential Revocation][VC Revocation] spec follows a similar pattern to those listed above. -[E][E-lang]-style [object capabilities][Robust Composition] use active nework connections with [proxy agents][Robust Composition] to revoke delegations. Revocation is achoeved by shutting down that proxy to break the authorizing reference. In many ways, UCAN Revocation attempts to emulate this behaviour. Unlike UCAN REvocations, E-style object capabilities are [fail-stop] and thus by defnition not partition tolerant. +[E][E-lang]-style [object capabilities][Robust Composition] use active network connections with [proxy agents][Robust Composition] to revoke delegations. Revocation is achoeved by shutting down that proxy to break the authorizing reference. In many ways, UCAN Revocation attempts to emulate this behavior. Unlike UCAN Revocations, E-style object capabilities are [fail-stop] and thus by defnition not partition tolerant. # 6 Acknowledgements From 60cf4d5838f5efe9903d892c79ae2684717a8c02 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 23:24:39 -0700 Subject: [PATCH 20/53] Fix markdown link checker --- .github/workflows/linkcheck.cfg.json | 10 ++++++++++ .github/workflows/linkcheck.yml | 1 + 2 files changed, 11 insertions(+) create mode 100644 .github/workflows/linkcheck.cfg.json diff --git a/.github/workflows/linkcheck.cfg.json b/.github/workflows/linkcheck.cfg.json new file mode 100644 index 0000000..1d3eb1e --- /dev/null +++ b/.github/workflows/linkcheck.cfg.json @@ -0,0 +1,10 @@ +{ + "ignorePatterns": [ + { + "pattern": "https://share.ansi.org/Shared%20Documents/Standards%20Activities/American%20National%20Standards/Procedures,%20Guides,%20and%20Forms/2020_ANSI_Essential_Requirements.pdf" + }, + { + "pattern": "https://share.ansi.org/Shared%20Documents/Standards%20Activities/American%20National%20Standards/Procedures,%20Guides,%20and%20Forms/2020_ANSI_Essential_Requirements.pdf" + } + ] +} diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml index b25de1f..998d61a 100644 --- a/.github/workflows/linkcheck.yml +++ b/.github/workflows/linkcheck.yml @@ -12,3 +12,4 @@ jobs: use-quiet-mode: 'yes' check-modified-files-only: 'yes' base-branch: 'main' + config-file: './.github/workflows/linkcheck.cfg.json' From aeff0dc58da014965418cb66ede3fee0db591428 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 23:32:00 -0700 Subject: [PATCH 21/53] Spelling --- .custom-words.txt | 7 +++++++ README.md | 28 ++++++++++++++-------------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/.custom-words.txt b/.custom-words.txt index 3ffa5e4..9a8350c 100644 --- a/.custom-words.txt +++ b/.custom-words.txt @@ -8,6 +8,7 @@ Aud Auth AuthorityA AuthorityB +BCP BT Bluesky BxZ @@ -73,6 +74,7 @@ URI URIs UTF Vandevelde +Verfiable WG WebNative Webber @@ -92,6 +94,7 @@ crudGraph cryptographically del delegable +delegatee delegator dereference disambiguates @@ -127,15 +130,18 @@ naud ncap niss nota +parsable plaintext potencies pre preimages quG +rc reauthorizations recommentations redelegate redelegates +revoker revoker's rootAud rootCap @@ -154,6 +160,7 @@ trustlessly ucan un unary +unpadded unresolvable url validatable diff --git a/README.md b/README.md index 05225ae..c05c8b2 100644 --- a/README.md +++ b/README.md @@ -21,27 +21,27 @@ This specification describes the format and semantics for revoking a previously # 1 Introduction -Using the [principle of least authority][POLA] such as certificate expiry and reduced capability scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It is not a perfect method, and cannot undo irreversable actions already performed with capability, but MAY limit misuse going forward. +Using the [principle of least authority][POLA] such as certificate expiry and reduced capability scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It is not a perfect method, and cannot undo irreversible actions already performed with capability, but MAY limit misuse going forward. ## 1.1 Motivation -Even when not in error at time of issuance, the trust relationship between a delegator and delegatee is not immutible. An agent can go rogue, keys can be compromised, and the privacy requirements of resources changed. While the UCAN delegation approach RECOMMENDS using the [principle of least authority][POLA], such unexpected conditions can and do arise. These are exceptional cases, but are sufficiently important that a well defined method for performing revocation is nearly always desired. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). +Even when not in error at time of issuance, the trust relationship between a delegator and delegatee is not immutable. An agent can go rogue, keys can be compromised, and the privacy requirements of resources changed. While the UCAN delegation approach RECOMMENDS using the [principle of least authority][POLA], such unexpected conditions can and do arise. These are exceptional cases, but are sufficiently important that a well defined method for performing revocation is nearly always desired. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). ## 1.2 Approach -UCAN Rovocations are similar to [blocklists]: they identify delegations that are retracted and no longer suitable for use. Revocation SHOULD considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. +UCAN Revocations are similar to [block lists]: they identify delegations that are retracted and no longer suitable for use. Revocation SHOULD considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. -UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished via delivery of an unforgable message from a previous delegator. +UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished via delivery of an unforgeable message from a previous delegator. # 2 Semantics UCAN revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. All UCAN capabilities are either claimed by direct authority over the resource, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). -Revocations MUST be immutible and irreversible. Recipients of revocations SHOULD treat them as a grow-only set (see the [eviction] section). If a revocation was issued in error, it MUST NOT be retracted — a new, unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes [revocation stores] append-only and highly amenable to caching. +Revocations MUST be immutable and irreversible. Recipients of revocations SHOULD treat them as a grow-only set (see the [eviction] section). If a revocation was issued in error, it MUST NOT be retracted — a new, unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes [revocation stores] append-only and highly amenable to caching. ## 2.1 Scope -An issuer of a proof in a delegation chain MAY revoke access to the capabilities that it granted. Note that this is not the same as revoking the specific delegation signed by the issuer: any UCAN that contains a proof where the revoker matches the `iss` field — even transatively in the delegation chain — MAY be revoked. +An issuer of a proof in a delegation chain MAY revoke access to the capabilities that it granted. Note that this is not the same as revoking the specific delegation signed by the issuer: any UCAN that contains a proof where the revoker matches the `iss` field — even transitively in the delegation chain — MAY be revoked. Revocation by a particular proof does not guarantee that the principle no longer has access to the capability in question. If a principal is able to construct a valid proof chain without relying on the revoked proof, they still have access to the capability. By real-world analogy, if Mallory has two tickets to a film, and one of them is invalidated by its serial number, she is still able to present the valid ticket to see the film. @@ -80,21 +80,21 @@ Here Alice is the root issuer / resource owner. Alice MAY revoke any of the UCAN UCAN revocation is designed to work in the broadest possible scenarios, and as such needs very weak constraints. UCAN revocation MAY operate in fully eventually consistent contexts, with single sources of truth, or among nodes participating in consensus. The format of the revocation does not change in these situations; it is entirely managed by how revocations are passed around the network. Weak assumptions enable UCAN to work with eventually consistent resources, such as [CRDT]s, [Git] forks, delay-tolerant replicated state machines, and so on. -These weak assumptions are often associated with being unable to guarantee delivery in a certain time bound. Weak assumptions can always be strengthened, but not vice-versa. For example, if a capability describes access to a resource with a single location or souce of truth, sending a revocation to that specific agent enables confirmatation in bounded time. This grants nearly idential semantics that many people turn to [ACL]s for, but with all of the benefits of capabilities during delegation and invocation. +These weak assumptions are often associated with being unable to guarantee delivery in a certain time bound. Weak assumptions can always be strengthened, but not vice-versa. For example, if a capability describes access to a resource with a single location or source of truth, sending a revocation to that specific agent enables confirmation in bounded time. This grants nearly identical semantics that many people turn to [ACL]s for, but with all of the benefits of capabilities during delegation and invocation. -Out of order delivery is typical of distributed systems. Further, a mallicious user can otherwise delay revealing that they have a capability until the last possible moment in hopes of evading detection. Accepting revocations for resources that the agent controls prior to the delegation targeted by the revocaton is recieved is thus RECOMMENDED. +Out of order delivery is typical of distributed systems. Further, a malicious user can otherwise delay revealing that they have a capability until the last possible moment in hopes of evading detection. Accepting revocations for resources that the agent controls prior to the delegation targeted by the revocation is received is thus RECOMMENDED. # 3 Store The agent that controls a resource SHOULD maintain a cache of revocations that it has seen. Agents are not limited to only storing revocations for resources that they control. -During validation of a UCAN delegation chain, the [canonical CID] of each UCAN delegation MUST be checked agianst the cache. If there's a match, the relevenat delegation MUST be ignored. Note that this MAY NOT invalidate the entire UCAN chain. +During validation of a UCAN delegation chain, the [canonical CID] of each UCAN delegation MUST be checked against the cache. If there's a match, the relevant delegation MUST be ignored. Note that this MAY NOT invalidate the entire UCAN chain. ## 3.1 Locality Revocation caches SHOULD be kept as close to the resource they describe as possible. -Resources with a single source of truth SHOULD follow the typical approach of maintaining a revication store at the same physical location as the resoucre. For exmape, a centralized server MAY have an endpoint that lists the revoked UCANs by [canonical CID]. +Resources with a single source of truth SHOULD follow the typical approach of maintaining a revocation store at the same physical location as the resource. For example, a centralized server MAY have an endpoint that lists the revoked UCANs by [canonical CID]. For eventually consistent data structures, this MAY be achieved by including the store directly inside the resource itself. For example, a CRDT-based file system SHOULD maintain the revocation store directly at a well-known path. @@ -115,7 +115,7 @@ A revocation message MUST contain the following information: | `rvk` | [CIDv1] | The [canonical CID] of the UCAN being revoked | Yes | | `sig` | [base64-unpadded][RFC 4648] string | The base64 encoded signature of `` `REVOKE-UCAN:${rvk}` `` | Yes | -Revocations MAY be gossiped between systems. As such, they need to be parsable by a wide number of lanaguges and contexts. To accomodate this, compliant UCAN revocations MUST be JSON-encoded. +Revocations MAY be gossiped between systems. As such, they need to be parsable by a wide number of languages and contexts. To accomodate this, compliant UCAN revocations MUST be JSON-encoded. ## 4.1 `urv` UCAN Revocation Version @@ -152,7 +152,7 @@ The `sig` field MUST contain a signature that validates against the revoker's DI [SPKI/SDSI] is closely related to UCAN. A different format is used, and some details vary (such as a delegation-locking bit), but the core idea and general usage pattern are very close. UCAN can be seen as making these ideas more palatable to a modern audience and adding a few features such as content IDs that were less widespread at the time SPKI/SDSI were written. -[X.509 Certificate Revocation Lists][RFC 5280] defines two kinds of certificate invalication: temporary ("hold") and permanent ("revocation"). This RFC also includes a field for indicating a reason for revocation. UCAN Revocation has no concept of a temporary hold on a capability, but this behavior MAY be emulated by revoking a credential and issuing a new UCAN with a `nbf` field set to a time in the future. +[X.509 Certificate Revocation Lists][RFC 5280] defines two kinds of certificate invalidation: temporary ("hold") and permanent ("revocation"). This RFC also includes a field for indicating a reason for revocation. UCAN Revocation has no concept of a temporary hold on a capability, but this behavior MAY be emulated by revoking a credential and issuing a new UCAN with a `nbf` field set to a time in the future. [ZCAP-LD] is closely related to UCAN, but situated in the W3C-style linked data world (the "LD" in ZCAP-LD). Revocation in ZCAP-LD is only granted to those who have a special caveat on a capability. In contrast, UCAN capabilities MAY be revoked by anyone in the relevant delegation path. @@ -160,7 +160,7 @@ The `sig` field MUST contain a signature that validates against the revoker's DI While strictly speaking being about assertions rather than capabilities, [Verfiable Credential Revocation][VC Revocation] spec follows a similar pattern to those listed above. -[E][E-lang]-style [object capabilities][Robust Composition] use active network connections with [proxy agents][Robust Composition] to revoke delegations. Revocation is achoeved by shutting down that proxy to break the authorizing reference. In many ways, UCAN Revocation attempts to emulate this behavior. Unlike UCAN Revocations, E-style object capabilities are [fail-stop] and thus by defnition not partition tolerant. +[E][E-lang]-style [object capabilities][Robust Composition] use active network connections with [proxy agents][Robust Composition] to revoke delegations. Revocation is achieved by shutting down that proxy to break the authorizing reference. In many ways, UCAN Revocation attempts to emulate this behavior. Unlike UCAN Revocations, E-style object capabilities are [fail-stop] and thus by definition not partition tolerant. # 6 Acknowledgements @@ -218,7 +218,7 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [VC Revocation]: https://w3c-ccg.github.io/vc-status-rl-2020/ [W3C]: https://www.w3.org/ [ZCAP-LD]: https://w3c-ccg.github.io/zcap-spec/ -[blocklists]: https://en.wikipedia.org/w/index.php?title=Block_list&redirect=no +[block lists]: https://en.wikipedia.org/w/index.php?title=Block_list&redirect=no [canonical CID]: https://github.com/ucan-wg/spec/blob/d5a844cceff569838881c7fa30ff4bfad338e771/README.md?plain=1#L800-L807 [fail-stop]: https://en.wikipedia.org/wiki/Fail-stop [local-first]: https://www.inkandswitch.com/local-first/ From ccfec362ee17f143bdbb3333ce42b6ad78fab423 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 23:33:22 -0700 Subject: [PATCH 22/53] Spelling --- .custom-words.txt | 1 + README.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.custom-words.txt b/.custom-words.txt index 9a8350c..db925e7 100644 --- a/.custom-words.txt +++ b/.custom-words.txt @@ -160,6 +160,7 @@ trustlessly ucan un unary +unforgeable unpadded unresolvable url diff --git a/README.md b/README.md index c05c8b2..6133268 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ A revocation message MUST contain the following information: | `rvk` | [CIDv1] | The [canonical CID] of the UCAN being revoked | Yes | | `sig` | [base64-unpadded][RFC 4648] string | The base64 encoded signature of `` `REVOKE-UCAN:${rvk}` `` | Yes | -Revocations MAY be gossiped between systems. As such, they need to be parsable by a wide number of languages and contexts. To accomodate this, compliant UCAN revocations MUST be JSON-encoded. +Revocations MAY be gossiped between systems. As such, they need to be parsable by a wide number of languages and contexts. To accommodate this, compliant UCAN revocations MUST be JSON-encoded. ## 4.1 `urv` UCAN Revocation Version From 2785948c6f8697a243b725e30853a94a6bd99fc3 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 15 Aug 2023 23:34:38 -0700 Subject: [PATCH 23/53] CODEOWNERS --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 866e6cf..628788e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,4 +2,4 @@ # the repo. Unless a later match takes precedence, # @global-owner1 and @global-owner2 will be requested for # review when someone opens a pull request. -* @expede +* @expede @matheus23 @gozala @dholms From f949d958374adc7c10cdf707fb8b583a71ba1909 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 16 Aug 2023 11:58:15 -0700 Subject: [PATCH 24/53] Update README.md Co-authored-by: Alan Shaw Signed-off-by: Brooklyn Zelenka --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6133268..139fc61 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Even when not in error at time of issuance, the trust relationship between a del ## 1.2 Approach -UCAN Revocations are similar to [block lists]: they identify delegations that are retracted and no longer suitable for use. Revocation SHOULD considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. +UCAN Revocations are similar to [block lists]: they identify delegations that are retracted and no longer suitable for use. Revocation SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished via delivery of an unforgeable message from a previous delegator. From 160d69f6082e4ff7ed2674f4c285867c9b3bf575 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 16 Aug 2023 11:58:41 -0700 Subject: [PATCH 25/53] Update README.md Co-authored-by: Brian Ginsburg <7957636+bgins@users.noreply.github.com> Signed-off-by: Brooklyn Zelenka --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 139fc61..975c0ac 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Even when not in error at time of issuance, the trust relationship between a del UCAN Revocations are similar to [block lists]: they identify delegations that are retracted and no longer suitable for use. Revocation SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. -UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished via delivery of an unforgeable message from a previous delegator. +UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished by delivery of an unforgeable message from a previous delegator. # 2 Semantics From a332c702ae5e1a8bf80b9efb3624cf3120cb9eb7 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 16 Aug 2023 11:58:59 -0700 Subject: [PATCH 26/53] Update README.md Co-authored-by: Brian Ginsburg <7957636+bgins@users.noreply.github.com> Signed-off-by: Brooklyn Zelenka --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 975c0ac..e3ca257 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ For eventually consistent data structures, this MAY be achieved by including the ## 3.2 Eviction -Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid via its proactive mechanisms. +Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid through its proactive mechanisms. A revocation store MOST only keep UCAN revocations for UCANs that are otherwise still valid. For example, expired UCANs are already invalid, so a revocation MUST NOT affect this invalid status. The revocation is thus redundant, and MAY be evicted from the store. From 79ab4beaf67808075d6d009b65eb735e5f5038f7 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 16 Aug 2023 11:59:08 -0700 Subject: [PATCH 27/53] Update README.md Co-authored-by: Brian Ginsburg <7957636+bgins@users.noreply.github.com> Signed-off-by: Brooklyn Zelenka --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e3ca257..80277ee 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Using the [principle of least authority][POLA] such as certificate expiry and re ## 1.1 Motivation -Even when not in error at time of issuance, the trust relationship between a delegator and delegatee is not immutable. An agent can go rogue, keys can be compromised, and the privacy requirements of resources changed. While the UCAN delegation approach RECOMMENDS using the [principle of least authority][POLA], such unexpected conditions can and do arise. These are exceptional cases, but are sufficiently important that a well defined method for performing revocation is nearly always desired. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). +Even when not in error at time of issuance, the trust relationship between a delegator and delegatee is not immutable. An agent can go rogue, keys can be compromised, and the privacy requirements of resources can change. While the UCAN delegation approach RECOMMENDS using the [principle of least authority][POLA], such unexpected conditions can and do arise. These are exceptional cases, but are sufficiently important that a well defined method for performing revocation is nearly always desired. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). ## 1.2 Approach From 13fcac8075bfd2347d10469fe98d31deb6214dfc Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 16 Aug 2023 12:03:25 -0700 Subject: [PATCH 28/53] Appy some of Brian's suggestions --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 80277ee..fceb6d2 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Even when not in error at time of issuance, the trust relationship between a del ## 1.2 Approach -UCAN Revocations are similar to [block lists]: they identify delegations that are retracted and no longer suitable for use. Revocation SHOULD be considered the last line of defense against abuse. Proactive expiry via time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. +UCAN Revocations are similar to [block lists]: they identify delegations that are retracted and no longer suitable for use. Revocation SHOULD be considered the last line of defense against abuse. Proactive expiry through time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished by delivery of an unforgeable message from a previous delegator. @@ -102,7 +102,7 @@ For eventually consistent data structures, this MAY be achieved by including the Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid through its proactive mechanisms. -A revocation store MOST only keep UCAN revocations for UCANs that are otherwise still valid. For example, expired UCANs are already invalid, so a revocation MUST NOT affect this invalid status. The revocation is thus redundant, and MAY be evicted from the store. +A revocation store MUST keep UCAN revocations for UCANs that are otherwise still valid. For example, expired UCANs are already invalid, so a revocation MUST NOT affect this invalid status. Such revocations are redundant, and MAY be evicted from the store. # 4 Format From 80d7e5fec4c63f14570ac3f2151defeee6b0de37 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 13:54:31 -0700 Subject: [PATCH 29/53] Merge branches --- README.md | 259 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 248 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index fceb6d2..ce1ade7 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,31 @@ -# UCAN Revocation Specification 1.0.0-rc.1 +# UCAN Revocation Specification v1.0.0-rc.1 ## Editors -* [Brooklyn Zelenka], [Fission] +- [Brooklyn Zelenka], [Fission] ## Authors -* [Brooklyn Zelenka], [Fission] -* [Daniel Holmgren], [Bluesky] -* [Irakli Gozalishvili], [Protocol Labs] -* [Philipp Krüger], [Fission] +- [Brooklyn Zelenka], [Fission] +- [Irakli Gozalishvili], [Protocol Labs] +- [Philipp Krüger], [Fission] + +## Dependencies + +- [DID] +- [IPLD] +- [UCAN Delegation] +- [UCAN Invocation] ## Language -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP 14] when, and only when, they appear in all capitals, as shown here. +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119]. -# 0 Abstract +# 0. Abstract -This specification describes the format and semantics for revoking a previously issued UCAN delegation. +This specification defines the semantics of revoking a [UCAN Delegation], and the ability to delegate such the ability to revoke a capability separately from the capability. -# 1 Introduction +# 1. Introduction Using the [principle of least authority][POLA] such as certificate expiry and reduced capability scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It is not a perfect method, and cannot undo irreversible actions already performed with capability, but MAY limit misuse going forward. @@ -29,9 +35,77 @@ Even when not in error at time of issuance, the trust relationship between a del ## 1.2 Approach +UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished by delivery of an unforgeable message from a previous delegator. + UCAN Revocations are similar to [block lists]: they identify delegations that are retracted and no longer suitable for use. Revocation SHOULD be considered the last line of defense against abuse. Proactive expiry through time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. -UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished by delivery of an unforgeable message from a previous delegator. +A UCAN Revocation is a mechanism for invalidating a particular Delegation when used in conjunction with another Delegation in an Invocation proof chain. This is a second-order reference, and is described in the following diagram: + +``` mermaid +flowchart RL + invoker((    Dan    )) + revoker((    Bob    )) + subject((    Alice    )) + + subgraph Delegations + subgraph root [Root UCAN] + subgraph rooting [Root Issuer] + rootIss(iss: Alice) + rootSub(sub: Alice) + end + + rootAud(aud: Bob) + end + + subgraph del1 [Delegated UCAN] + del1Iss(iss: Bob) --> rootAud + del1Sub(sub: Alice) + del1Aud(aud: Carol) + + + del1Sub --> rootSub + end + + subgraph del2 [☠️ Delegated UCAN ☠️] + del2Iss(iss: Carol) --> del1Aud + del2Sub(sub: Alice) + del2Aud(aud: Dan) + + del2Sub --> del1Sub + end + end + + subgraph rev [Revocation] + revCmd("cmd: ucan/revoke") + revArg("arg: {revoke: cid(carol_to_dan)}") + revIss(iss: Bob) + revPrf("proofs") + end + + subgraph inv [☠️ Invocation ☠️] + invSub(sub: Alice) + invIss(iss: Dan) + invPrf("proofs") + end + + revoker --> revIss + revArg:::revoked -.-> del2:::revoked + revIss -.-> del1Iss + revPrf:::revocation -.-> del1:::revocation + + inv:::revoked + invPrf:::revoked + + invIss --> del2Aud + invoker --> invIss + invSub --> del2Sub + rootIss --> subject + rootSub --> subject + invPrf --> Delegations + + classDef revocation stroke:blue,fill:#76b0ff + classDef revoked stroke:red,fill:#ff7676,color:red +``` # 2 Semantics @@ -178,6 +252,169 @@ Thanks to the entire [SPKI WG][SPKI/SDSI] for their closely related pioneering w We want to especially recognize [Mark Miller] for his numerous contributions to the field of distributed auth, programming languages, and computer security writ large. +# 6. Acknowledgments + +Thank you to [Brendan O'Brien] for real-world feedback, technical collaboration, and implementing the first Golang UCAN library. + +Many thanks to [Hugo Dias], [Mikael Rogers], and the entire DAG House team for the real world feedback, and finding inventive new use cases. + +Thank you [Blaine Cook] for the real-world feedback, ideas on future features, and lessons from other auth standards. + +Many thanks to [Brian Ginsburg] and [Steven Vandevelde] for their many copy edits, feedback from real world usage, maintenance of the TypeScript implementation, and tools such as [ucan.xyz]. + +Many thanks to [Christopher Joel] for his real-world feedback, raising many pragmatic considerations, and the Rust implementation and related crates. + +Many thanks to [Christine Lemmer-Webber] for her handwritten(!) feedback on the design of UCAN, spearheading the [OCapN] initiative, and her related work on [ZCAP-LD]. + +Thanks to [Benjamin Goering] for the many community threads and connections to [W3C] standards. + +Thanks to [Juan Caballero] for the numerous questions, clarifications, and general advice on putting together a comprehensible spec. + +Thank you [Dan Finlay] for being sufficiently passionate about [OCAP] that we realized that capability systems had a real chance of adoption in an ACL-dominated world. + +Thanks to the entire [SPKI WG][SPKI/SDSI] for their closely related pioneering work. + +Many thanks to [Alan Karp] for sharing his vast experience with capability-based authorization, patterns, and many right words for us to search for. + +We want to especially recognize [Mark Miller] for his numerous contributions to the field of distributed auth, programming languages, and computer security writ large. + + + +[^js-num-size]: JavaScript has a single numeric type ([`Number`][JS Number]) for both integers and floats. This representation is defined as a [IEEE-754] double-precision floating point number, which has a 53-bit significand. + + + +[Ability]: #43-ability +[Caveat]: #44-caveats +[Envelope]: #2-delegation-envelope +[Meta]: #35-meta +[Payload]: #3-delegation-payload +[Subject]: #41-subject +[True Caveat]: #441-the-true-caveat +[Wildcard Ability]: #4312--aka-wildcard + + + +[Alan Karp]: https://github.com/alanhkarp +[Benjamin Goering]: https://github.com/gobengo +[Blaine Cook]: https://github.com/blaine +[Bluesky]: https://blueskyweb.xyz/ +[Brendan O'Brien]: https://github.com/b5 +[Brian Ginsburg]: https://github.com/bgins +[Brooklyn Zelenka]: https://github.com/expede +[CIDv1]: https://github.com/multiformats/cid?tab=readme-ov-file#cidv1 +[Christine Lemmer-Webber]: https://github.com/cwebber +[Christopher Joel]: https://github.com/cdata +[DAG-CBOR]: https://ipld.io/specs/codecs/dag-cbor/spec/ +[DID fragment]: https://www.w3.org/TR/did-core/#terminology +[DID]: https://www.w3.org/TR/did-core/ +[Dan Finlay]: https://github.com/danfinlay +[Daniel Holmgren]: https://github.com/dholms +[ES256]: https://www.rfc-editor.org/rfc/rfc7518#section-3.4 +[EdDSA]: https://en.wikipedia.org/wiki/EdDSA +[Executor]: https://github.com/ucan-wg/spec#31-roles +[Fission]: https://fission.codes +[Hugo Dias]: https://github.com/hugomrdias +[IEEE-754]: https://ieeexplore.ieee.org/document/8766229 +[IPLD]: https://ipld.io/ +[Ink & Switch]: https://www.inkandswitch.com/ +[Invocation]: https://github.com/ucan-wg/invocation +[Irakli Gozalishvili]: https://github.com/Gozala +[JS Number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number +[Juan Caballero]: https://github.com/bumblefudge +[Mark Miller]: https://github.com/erights +[Martin Kleppmann]: https://martin.kleppmann.com/ +[Mikael Rogers]: https://github.com/mikeal/ +[OCAP]: https://en.wikipedia.org/wiki/Object-capability_model +[OCapN]: https://github.com/ocapn/ +[Command]: https://github.com/ucan-wg/spec#33-command +[Philipp Krüger]: https://github.com/matheus23 +[PoLA]: https://en.wikipedia.org/wiki/Principle_of_least_privilege +[Protocol Labs]: https://protocol.ai/ +[RFC 3339]: https://www.rfc-editor.org/rfc/rfc3339 +[RFC 8037]: https://www.rfc-editor.org/rfc/rfc8037 +[RS256]: https://www.rfc-editor.org/rfc/rfc7518#section-3.3 +[Raw data multicodec]: https://github.com/multiformats/multicodec/blob/master/table.csv#L41 +[SHA2-256]: https://github.com/multiformats/multicodec/blob/master/table.csv#L9 +[SPKI/SDSI]: https://datatracker.ietf.org/wg/spki/about/ +[SPKI]: https://theworld.com/~cme/html/spki.html +[Steven Vandevelde]: https://github.com/icidasset +[UCAN Invocation]: https://github.com/ucan-wg/invocation +[UCAN]: https://github.com/ucan-wg/spec +[W3C]: https://www.w3.org/ +[ZCAP-LD]: https://w3c-ccg.github.io/zcap-spec/ +[`did:key`]: https://w3c-ccg.github.io/did-method-key/ +[`did:plc`]: https://github.com/did-method-plc/did-method-plc +[`did:web`]: https://w3c-ccg.github.io/did-method-web/ +[base32]: https://github.com/multiformats/multibase/blob/master/multibase.csv#L13 +[dag-json multicodec]: https://github.com/multiformats/multicodec/blob/master/table.csv#L112 +[did:key ECDSA]: https://w3c-ccg.github.io/did-method-key/#p-256 +[did:key EdDSA]: https://w3c-ccg.github.io/did-method-key/#ed25519-x25519 +[did:key RSA]: https://w3c-ccg.github.io/did-method-key/#rsa +[external resource]: https://github.com/ucan-wg/spec#55-wrapping-existing-systems +[revocation]: https://github.com/ucan-wg/revocation +[ucan.xyz]: https://ucan.xyz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# UCAN Revocation Specification 1.0.0-rc.1 + + + + + + + + + +> The discussion talks about zAlice, and Alice delegating revoke permission to any UCAN she has created. That's a useful feature, but one that needs to be tightly controlled, e.g., don't delegate to Mallory. I'm sure people in this discussion know that Alice can have many keys, which means she can control who can revoke subsets of the UCANs she creates by using a different key for each subset. As a result, the damage that can happen if Bob delegates to Mallory is controllable. I'm just making this point explicit because I've been in discussions that rabbit holed because people got into the mode of a single key per person. + + + + + + + + + + + + + + +# 1 Introduction + + + [eviction]: #32-eviction From a01a0a62e80bd0a40f2edf1cc2be68107b63a15f Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 15:02:45 -0700 Subject: [PATCH 30/53] Fix mermaid --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce1ade7..46fe55b 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ flowchart RL del1Sub --> rootSub end - subgraph del2 [☠️ Delegated UCAN ☠️] + subgraph del2 [INVALIDATED Delegation] del2Iss(iss: Carol) --> del1Aud del2Sub(sub: Alice) del2Aud(aud: Dan) @@ -82,7 +82,7 @@ flowchart RL revPrf("proofs") end - subgraph inv [☠️ Invocation ☠️] + subgraph inv [INVALIDATED Invocation] invSub(sub: Alice) invIss(iss: Dan) invPrf("proofs") From eecd649b19e9dbbf50f7f91c51e79a6fb08c8a6e Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 15:04:23 -0700 Subject: [PATCH 31/53] Better layout --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 46fe55b..5c5aab3 100644 --- a/README.md +++ b/README.md @@ -76,10 +76,10 @@ flowchart RL end subgraph rev [Revocation] - revCmd("cmd: ucan/revoke") revArg("arg: {revoke: cid(carol_to_dan)}") - revIss(iss: Bob) + revCmd("cmd: ucan/revoke") revPrf("proofs") + revIss(iss: Bob) end subgraph inv [INVALIDATED Invocation] From 30aac2526fd51ab4a54c6bdc34e47e597c87e05f Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 15:07:47 -0700 Subject: [PATCH 32/53] More of same --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5c5aab3..2d75209 100644 --- a/README.md +++ b/README.md @@ -59,17 +59,16 @@ flowchart RL subgraph del1 [Delegated UCAN] del1Iss(iss: Bob) --> rootAud - del1Sub(sub: Alice) del1Aud(aud: Carol) - + del1Sub(sub: Alice) del1Sub --> rootSub end subgraph del2 [INVALIDATED Delegation] del2Iss(iss: Carol) --> del1Aud - del2Sub(sub: Alice) del2Aud(aud: Dan) + del2Sub(sub: Alice) del2Sub --> del1Sub end @@ -78,8 +77,8 @@ flowchart RL subgraph rev [Revocation] revArg("arg: {revoke: cid(carol_to_dan)}") revCmd("cmd: ucan/revoke") - revPrf("proofs") revIss(iss: Bob) + revPrf("proofs") end subgraph inv [INVALIDATED Invocation] From 4288c2f6c7b2b094ceecb218001c4c870f486dfa Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 15:12:55 -0700 Subject: [PATCH 33/53] Fix second diagram --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2d75209..e436060 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,8 @@ Revocation by a particular proof does not guarantee that the principle no longer ``` mermaid flowchart TB subgraph RA[Alice can revoke] + direction RL + AB["(Root)\niss: Alice\naud: Bob\ncap:[X,Y,Z]"] subgraph RB[Bob can revoke] From af086572c3f7a46323a5bbca2ca360329639fbc6 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 17:04:19 -0700 Subject: [PATCH 34/53] Arguments --- README.md | 103 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index e436060..1955d41 100644 --- a/README.md +++ b/README.md @@ -125,17 +125,17 @@ flowchart TB subgraph RA[Alice can revoke] direction RL - AB["(Root)\niss: Alice\naud: Bob\ncap:[X,Y,Z]"] + AB["(Root)\niss: Alice\naud: Bob\niff[X,Y,Z]"] subgraph RB[Bob can revoke] - BC["iss: Bob\naud: Carol\ncap: [X,Y]"] - BD["iss: Bob\naud: Dan\ncap:[Y,Z]"] + BC["iss: Bob\naud: Carol\niff [X,Y]"] + BD["iss: Bob\naud: Dan\niff[Y,Z]"] subgraph RC[Carol can revoke] - CD["iss: Carol\naud: Dan\ncap:[X,Y]"] + CD["iss: Carol\naud: Dan\niff[X,Y]"] subgraph RD[Dan can revoke] - DE["iss: Dan\naud: Erin\ncap:[X,Y,Z]"] + DE["iss: Dan\naud: Erin\niff[X,Y,Z]"] end end end @@ -179,48 +179,89 @@ Revocations MAY be deleted once the UCAN that they reference expires or otherwis A revocation store MUST keep UCAN revocations for UCANs that are otherwise still valid. For example, expired UCANs are already invalid, so a revocation MUST NOT affect this invalid status. Such revocations are redundant, and MAY be evicted from the store. -# 4 Format +# 3 Expiry -A revocation message MUST contain the following information: +FIXME Note on expiry -| Field | Type | Description | Required | -|-------|------------------------------------|------------------------------------------------------------|----------| -| `urv` | [Semver] string | Version of UCAN Revocation (`1.0.0-rc.1`) | Yes | -| `iss` | [DID] | Revoker DID | Yes | -| `rvk` | [CIDv1] | The [canonical CID] of the UCAN being revoked | Yes | -| `sig` | [base64-unpadded][RFC 4648] string | The base64 encoded signature of `` `REVOKE-UCAN:${rvk}` `` | Yes | +# 4 Action -Revocations MAY be gossiped between systems. As such, they need to be parsable by a wide number of languages and contexts. To accommodate this, compliant UCAN revocations MUST be JSON-encoded. +FIXME show delegation -## 4.1 `urv` UCAN Revocation Version +A revocation Action MUST take the following shape: -The UCAN Revocation Version, i.e. the version of this document: `1.0.0-rc.1`. +| Field | Value | +|-------|-----------------| +| `cmd` | `"ucan/revoke"` | +| `arg` | See [Arguments] | +| `nnc` | `""` | -## 4.2 `iss` Revocation Issuer +Note that per [UCAN Invocation], the `nnc` field SHOULD is set to `""` since revocation is idempotent. -The issuer DID of this revocation. This DID MUST match one or more `iss` fields in the proof chain of the UCAN listed in the `rvk` field. This DID MUST also validate against the signature in the `sig` field. +## 4.1 Arguments -## 4.3 `rvk` Revoked UCAN +Being expressed as an Invocation means that Revocations MUST define an Action type for the command `ucan/revoke`. -The `rvk` field MUST contain the [canonical CID] for the UCAN delegation being revoked. The target UCAN MUST contain a (potentially nested) UCAN proof where the `iss` field matches the `iss` field of this revocation. +| Field | Type | Required | Description | +|-------|-----------------|----------|---------------------------------------------------------------------------------------| +| `rev` | `&Delegation` | Yes | The [UCAN Delegation] that is being revoked | +| `pth` | `[&Delegation]` | No | [Proof of delegation path] from a delegation by the Revoker to the revoked Delegation | -Note that this revocation MUST only revoke the particular capabilities from the relevant proof(s). The resultant proof chain MUST be treated as if that proof were not present, with no other changes. +### 4.1.1 Revoked Delegation -## 4.4 `sig` Prefixed Signature +The target delegation MUST be referenced by its CID. -The `sig` field MUST contain a signature that validates against the revoker's DID. The format to sign over MUST be prefixed with the UTF-8 string `REVOKE-UCAN:`, followed by the CID from the `rvk` field. Note that the prefix contains no spaces. +### 4.1.2 Path Witness -## 4.5 Example +Since all delegation chains MUST be rooted in a Delegation where the `iss` and `sub` fields are equal, the root Issuer is a priori in every delegation chain. This is not the case for sub-delegation. There are many paths through the authority network. For exmaple, take the following delegation network: -``` json -{ - "urv": "1.0.0-rc.1", - "iss": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK", - "rvk": "bafkreia7l6bthgtpaaw4qbfacun6p4rt5rcorsognxgojvkyvhlmo7kf4a", - "sig": "FJi1Rnpj3/otydngacrwddFvwz/dTDsBv62uZDN2fZM" -} +``` mermaid +flowchart LR + Alice -->|delegates| Bob -->|delegates| Dan -->|delegates| Erin + Bob -->|delegates| Carol -->|delegates| Erin + Alice -->|delegates| Mallory ``` +Mallory is not in the delegation chain of Erin. This is fine, since the semantics of revocation merely state that she would assert that no delegation of hers may be used in the `prf` field of an Invocation if it also includes the `rev` Delegation. However, issuing spurious Revocations and requiring them to be stored is a potential DoS vector. Executors MAY require a delegation path witness be included to avoid this situaton. + +Unlike Mallory, Bob, Carol, and Dan can both provide valid delegation paths that include Delegations that they have issued. Bob has two paths (`Bob -> Dan -> Erin` or `Bob -> Carol -> Erin`), but either will suffice. + + + + + + + + + + + + + + + + + + + +Revocations MAY be gossiped between systems. As such, they need to be parsable by a wide number of languages and contexts. To accommodate this, compliant UCAN revocations MUST be JSON-encoded. + + + + + + + + + + + + + + + + + + # 5 Prior Art [Revocation lists][Cert Revocation Wikipedia] are a fairly widely used concept. From a9cdb33340076ea96d9e68dc77009f9ddd957e6c Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 17:17:29 -0700 Subject: [PATCH 35/53] Subtyping and values --- README.md | 49 ++++++---------------------------------------- revocation.ipldsch | 10 ++++++++++ 2 files changed, 16 insertions(+), 43 deletions(-) create mode 100644 revocation.ipldsch diff --git a/README.md b/README.md index 1955d41..2cb4fff 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ A revocation store MUST keep UCAN revocations for UCANs that are otherwise still # 3 Expiry -FIXME Note on expiry +Revocations MUST NOT expire. If a Revocation was issued in error, # 4 Action @@ -201,10 +201,10 @@ Note that per [UCAN Invocation], the `nnc` field SHOULD is set to `""` since rev Being expressed as an Invocation means that Revocations MUST define an Action type for the command `ucan/revoke`. -| Field | Type | Required | Description | -|-------|-----------------|----------|---------------------------------------------------------------------------------------| -| `rev` | `&Delegation` | Yes | The [UCAN Delegation] that is being revoked | -| `pth` | `[&Delegation]` | No | [Proof of delegation path] from a delegation by the Revoker to the revoked Delegation | +| Field | Type | Required | Description | +|-------|-----------------|----------|--------------------------------------------------------------------------| +| `rev` | `&Delegation` | Yes | The [UCAN Delegation] that is being revoked | +| `pth` | `[&Delegation]` | No | [A delegation path] that includes the Revoker and the revoked Delegation | ### 4.1.1 Revoked Delegation @@ -223,44 +223,7 @@ flowchart LR Mallory is not in the delegation chain of Erin. This is fine, since the semantics of revocation merely state that she would assert that no delegation of hers may be used in the `prf` field of an Invocation if it also includes the `rev` Delegation. However, issuing spurious Revocations and requiring them to be stored is a potential DoS vector. Executors MAY require a delegation path witness be included to avoid this situaton. -Unlike Mallory, Bob, Carol, and Dan can both provide valid delegation paths that include Delegations that they have issued. Bob has two paths (`Bob -> Dan -> Erin` or `Bob -> Carol -> Erin`), but either will suffice. - - - - - - - - - - - - - - - - - - - -Revocations MAY be gossiped between systems. As such, they need to be parsable by a wide number of languages and contexts. To accommodate this, compliant UCAN revocations MUST be JSON-encoded. - - - - - - - - - - - - - - - - - +Unlike Mallory, Bob, Carol, and Dan can both provide valid delegation paths that include Delegations that they have issued. Bob has two paths (`Alice -> Bob -> Dan -> Erin` or `Alice -> Bob -> Carol -> Erin`), and either will suffice. # 5 Prior Art diff --git a/revocation.ipldsch b/revocation.ipldsch new file mode 100644 index 0000000..8efab3c --- /dev/null +++ b/revocation.ipldsch @@ -0,0 +1,10 @@ +type RevocationAction <: Action { + cmd "ucan/revoke" + nnc "" + arg RevocationArguments +} + +type RevocationArguments struct { + rev &Delegation + pth [&Delegation] +} From bd1daf1a5ff637f8b875b49ad7ad38643285e305 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 18:25:24 -0700 Subject: [PATCH 36/53] Better diagram --- README.md | 199 +++++++++++++++++------------------------------------- 1 file changed, 61 insertions(+), 138 deletions(-) diff --git a/README.md b/README.md index 2cb4fff..869d775 100644 --- a/README.md +++ b/README.md @@ -179,11 +179,67 @@ Revocations MAY be deleted once the UCAN that they reference expires or otherwis A revocation store MUST keep UCAN revocations for UCANs that are otherwise still valid. For example, expired UCANs are already invalid, so a revocation MUST NOT affect this invalid status. Such revocations are redundant, and MAY be evicted from the store. -# 3 Expiry +## 3.3 Expiry -Revocations MUST NOT expire. If a Revocation was issued in error, +Revocations MUST NOT expire. -# 4 Action +## 3.4 Monotonicity + +Since Revocations MUST NOT be reverable, a new Delegation SHOULD be issued if a Revocation was issued in error. + +``` mermaid +flowchart LR + Alice -->|delegates| Bob -.-x|d̶e̶l̶e̶g̶a̶t̶e̶s̶| Carol -->|delegates| Dan + Alice -->|REVOKES| Carol + Alice -->|"delegates (new CID)"| Carol +``` + +# 4 Delegation Ability + +The authority to revoke some Delegation MAY be itself delegated to a Principal not in the delegation chain. This is a normal delegation: + +``` js +{ + "iss": "did:web:alice.example.com", + "aud": "did:web:zelda.example.com", + "sub": "did:web:alice.example.com", + "can": "ucan/revoke", + "iff": [ + {"rev": {"/": "bafkreiem4on23qnu2nn2jg7vwzxkns6sxi5faysq7ekwtjhugqga3vbhim"}} + ], + // ... +} +``` + +``` mermaid +flowchart LR + Alice((   Alice   )) + Bob((   Bob   )) + Carol((   Carol   )) + Dan((   Dan   )) + Zelda((   Zelda   )) + + del1{{Delegate\ncan: crud/read Alice's DB}} + del2{{Delegate\ncan: crud/read Alice's DB}} + del3{{Delegate\ncan: crud/read Alice's DB}} + + delRev{{Delegate\ncan: ucan/revoke}} + + Alice --- del1 --> Bob --- del2 --> Carol --- del3 --> Dan + Alice --- delRev --> Zelda + delRev -.->|cid| del2 + + rev>Invoke!\nRevoke Dan] + Zelda --- rev:::Invocation ---> Dan + rev -...->|prf| delRev + + classDef Invocation stroke:#F00,fill:#F00,color:#000; + linkStyle 9 stroke:red + linkStyle 10 stroke:red +``` + + +# 5 Invocation Action FIXME show delegation @@ -259,24 +315,6 @@ We want to especially recognize [Mark Miller] for his numerous contributions to # 6. Acknowledgments -Thank you to [Brendan O'Brien] for real-world feedback, technical collaboration, and implementing the first Golang UCAN library. - -Many thanks to [Hugo Dias], [Mikael Rogers], and the entire DAG House team for the real world feedback, and finding inventive new use cases. - -Thank you [Blaine Cook] for the real-world feedback, ideas on future features, and lessons from other auth standards. - -Many thanks to [Brian Ginsburg] and [Steven Vandevelde] for their many copy edits, feedback from real world usage, maintenance of the TypeScript implementation, and tools such as [ucan.xyz]. - -Many thanks to [Christopher Joel] for his real-world feedback, raising many pragmatic considerations, and the Rust implementation and related crates. - -Many thanks to [Christine Lemmer-Webber] for her handwritten(!) feedback on the design of UCAN, spearheading the [OCapN] initiative, and her related work on [ZCAP-LD]. - -Thanks to [Benjamin Goering] for the many community threads and connections to [W3C] standards. - -Thanks to [Juan Caballero] for the numerous questions, clarifications, and general advice on putting together a comprehensible spec. - -Thank you [Dan Finlay] for being sufficiently passionate about [OCAP] that we realized that capability systems had a real chance of adoption in an ACL-dominated world. - Thanks to the entire [SPKI WG][SPKI/SDSI] for their closely related pioneering work. Many thanks to [Alan Karp] for sharing his vast experience with capability-based authorization, patterns, and many right words for us to search for. @@ -285,19 +323,8 @@ We want to especially recognize [Mark Miller] for his numerous contributions to -[^js-num-size]: JavaScript has a single numeric type ([`Number`][JS Number]) for both integers and floats. This representation is defined as a [IEEE-754] double-precision floating point number, which has a 53-bit significand. - -[Ability]: #43-ability -[Caveat]: #44-caveats -[Envelope]: #2-delegation-envelope -[Meta]: #35-meta -[Payload]: #3-delegation-payload -[Subject]: #41-subject -[True Caveat]: #441-the-true-caveat -[Wildcard Ability]: #4312--aka-wildcard - [Alan Karp]: https://github.com/alanhkarp @@ -310,6 +337,7 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [CIDv1]: https://github.com/multiformats/cid?tab=readme-ov-file#cidv1 [Christine Lemmer-Webber]: https://github.com/cwebber [Christopher Joel]: https://github.com/cdata +[Command]: https://github.com/ucan-wg/spec#33-command [DAG-CBOR]: https://ipld.io/specs/codecs/dag-cbor/spec/ [DID fragment]: https://www.w3.org/TR/did-core/#terminology [DID]: https://www.w3.org/TR/did-core/ @@ -332,7 +360,6 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [Mikael Rogers]: https://github.com/mikeal/ [OCAP]: https://en.wikipedia.org/wiki/Object-capability_model [OCapN]: https://github.com/ocapn/ -[Command]: https://github.com/ucan-wg/spec#33-command [Philipp Krüger]: https://github.com/matheus23 [PoLA]: https://en.wikipedia.org/wiki/Principle_of_least_privilege [Protocol Labs]: https://protocol.ai/ @@ -344,6 +371,7 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [SPKI/SDSI]: https://datatracker.ietf.org/wg/spki/about/ [SPKI]: https://theworld.com/~cme/html/spki.html [Steven Vandevelde]: https://github.com/icidasset +[UCAN Delegation]: https://github.com/ucan-wg/delegation [UCAN Invocation]: https://github.com/ucan-wg/invocation [UCAN]: https://github.com/ucan-wg/spec [W3C]: https://www.w3.org/ @@ -359,108 +387,3 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [external resource]: https://github.com/ucan-wg/spec#55-wrapping-existing-systems [revocation]: https://github.com/ucan-wg/revocation [ucan.xyz]: https://ucan.xyz - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# UCAN Revocation Specification 1.0.0-rc.1 - - - - - - - - - -> The discussion talks about zAlice, and Alice delegating revoke permission to any UCAN she has created. That's a useful feature, but one that needs to be tightly controlled, e.g., don't delegate to Mallory. I'm sure people in this discussion know that Alice can have many keys, which means she can control who can revoke subsets of the UCANs she creates by using a different key for each subset. As a result, the damage that can happen if Bob delegates to Mallory is controllable. I'm just making this point explicit because I've been in discussions that rabbit holed because people got into the mode of a single key per person. - - - - - - - - - - - - - - -# 1 Introduction - - - - - -[eviction]: #32-eviction -[revocation stores]: #3-store - - - -[ACL]: https://en.wikipedia.org/wiki/Access-control_list -[Alan Karp]: https://github.com/alanhkarp -[BCP 14]: https://www.rfc-editor.org/info/bcp14 -[Benjamin Goering]: https://github.com/gobengo -[Blaine Cook]: https://github.com/blaine -[Bluesky]: https://blueskyweb.xyz/ -[Brooklyn Zelenka]: https://github.com/expede -[CIDv1]: https://docs.ipfs.io/concepts/content-addressing/#identifier-formats -[CRDT]: https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type -[Cert Revocation Wikipedia]: https://en.wikipedia.org/wiki/Certificate_revocation_list -[Christine Lemmer-Webber]: https://github.com/cwebber -[DID]: https://www.w3.org/TR/did-core/ -[Daniel Holmgren]: https://github.com/dholms -[E-lang]: http://erights.org/elang/ -[Fission]: https://fission.codes -[Git]: https://git-scm.com/ -[Irakli Gozalishvili]: https://github.com/Gozala -[Juan Caballero]: https://github.com/bumblefudge -[Mark Miller]: https://github.com/erights -[OCAP]: http://erights.org/elib/capability/index.html -[OCapN]: https://github.com/ocapn/ocapn -[POLA]: https://en.wikipedia.org/wiki/Principle_of_least_privilege -[Philipp Krüger]: https://github.com/matheus23 -[Protocol Labs]: https://protocol.ai/ -[RFC 4648]: https://www.rfc-editor.org/rfc/rfc4648.html -[RFC 5280]: https://www.rfc-editor.org/rfc/rfc5280 -[RFC 7009]: https://datatracker.ietf.org/doc/html/rfc7009 -[Robust Composition]: https://jscholarship.library.jhu.edu/bitstream/handle/1774.2/873/markm-thesis.pdf?page=100 -[SPKI/SDSI]: https://datatracker.ietf.org/wg/spki/about/ -[Semver]: https://semver.org/ -[VC Revocation]: https://w3c-ccg.github.io/vc-status-rl-2020/ -[W3C]: https://www.w3.org/ -[ZCAP-LD]: https://w3c-ccg.github.io/zcap-spec/ -[block lists]: https://en.wikipedia.org/w/index.php?title=Block_list&redirect=no -[canonical CID]: https://github.com/ucan-wg/spec/blob/d5a844cceff569838881c7fa30ff4bfad338e771/README.md?plain=1#L800-L807 -[fail-stop]: https://en.wikipedia.org/wiki/Fail-stop -[local-first]: https://www.inkandswitch.com/local-first/ From bdd37b6fc35a5da73204000da5ba6c01a3ee7962 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 18:40:16 -0700 Subject: [PATCH 37/53] Even more explination --- README.md | 54 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 869d775..31e378d 100644 --- a/README.md +++ b/README.md @@ -189,9 +189,34 @@ Since Revocations MUST NOT be reverable, a new Delegation SHOULD be issued if a ``` mermaid flowchart LR - Alice -->|delegates| Bob -.-x|d̶e̶l̶e̶g̶a̶t̶e̶s̶| Carol -->|delegates| Dan - Alice -->|REVOKES| Carol - Alice -->|"delegates (new CID)"| Carol + Alice((   Alice   )) + Bob((   Bob   )) + Carol((   Carol   )) + Dan((   Dan   )) + + del1{{Delegate\ncan: crud/read Alice's DB}} + del2{{Delegate\ncan: crud/read Alice's DB}} + del3{{Delegate\ncan: crud/read Alice's DB}} + newDel{{"Delegate\ncan: crud/read Alice's DB\n(Resissued) "}} + + Alice --- del1 --> Bob -.- del2:::Revoked -.-x Carol --- del3 --> Dan + Alice --- newDel:::Reissued ---> Carol + + rev>Revoke!] + Alice --- rev:::Invocation ---> del2 + + classDef Invocation stroke:#F00,fill:#F00,color:#000; + classDef Revoked stroke:#F00; + classDef Reissued stroke:green; + + linkStyle 2 stroke:red + linkStyle 3 stroke:red + + linkStyle 8 stroke:red + linkStyle 9 stroke:red + + linkStyle 6 stroke:green + linkStyle 7 stroke:green ``` # 4 Delegation Ability @@ -213,27 +238,30 @@ The authority to revoke some Delegation MAY be itself delegated to a Principal n ``` mermaid flowchart LR - Alice((   Alice   )) - Bob((   Bob   )) - Carol((   Carol   )) - Dan((   Dan   )) - Zelda((   Zelda   )) + Alice((   Alice   )) + Bob((   Bob   )) + Carol((   Carol   )) + Dan((   Dan   )) + Zelda((   Zelda   )) del1{{Delegate\ncan: crud/read Alice's DB}} del2{{Delegate\ncan: crud/read Alice's DB}} - del3{{Delegate\ncan: crud/read Alice's DB}} + del3{{Delegate\ncan: crud/read Alice's DB}}:::Revoked delRev{{Delegate\ncan: ucan/revoke}} - Alice --- del1 --> Bob --- del2 --> Carol --- del3 --> Dan + Alice --- del1 --> Bob --- del2 --> Carol -.- del3 -.-x Dan Alice --- delRev --> Zelda delRev -.->|cid| del2 - rev>Invoke!\nRevoke Dan] - Zelda --- rev:::Invocation ---> Dan - rev -...->|prf| delRev + rev>Revoke] + Zelda --- rev:::Invocation ---> del3 + classDef Revoked stroke:#F00; classDef Invocation stroke:#F00,fill:#F00,color:#000; + + linkStyle 4 stroke:red + linkStyle 5 stroke:red linkStyle 9 stroke:red linkStyle 10 stroke:red ``` From b1384595295063a6d2c6802e84a1f858c0f1694d Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 18:50:16 -0700 Subject: [PATCH 38/53] Fix rendeing bugs --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 31e378d..f27e461 100644 --- a/README.md +++ b/README.md @@ -199,11 +199,12 @@ flowchart LR del3{{Delegate\ncan: crud/read Alice's DB}} newDel{{"Delegate\ncan: crud/read Alice's DB\n(Resissued) "}} - Alice --- del1 --> Bob -.- del2:::Revoked -.-x Carol --- del3 --> Dan - Alice --- newDel:::Reissued ---> Carol + Alice === del1 ==> Bob === del2:::Revoked ===x Carol === del3 ==> Dan + Alice === newDel:::Reissued ===> Carol rev>Revoke!] - Alice --- rev:::Invocation ---> del2 + Alice === rev:::Invocation + rev -.->|rev| del2 classDef Invocation stroke:#F00,fill:#F00,color:#000; classDef Revoked stroke:#F00; @@ -250,12 +251,13 @@ flowchart LR delRev{{Delegate\ncan: ucan/revoke}} - Alice --- del1 --> Bob --- del2 --> Carol -.- del3 -.-x Dan - Alice --- delRev --> Zelda + Alice === del1 ==> Bob === del2 ===> Carol === del3 ===x Dan + Alice === delRev ===> Zelda delRev -.->|cid| del2 rev>Revoke] - Zelda --- rev:::Invocation ---> del3 + Zelda === rev:::Invocation ===> Alice + rev:::Invocation -.->|rev| del3 classDef Revoked stroke:#F00; classDef Invocation stroke:#F00,fill:#F00,color:#000; From 12f5571c990aec7cf85eab7bb9c79344aa203a63 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 20:24:05 -0700 Subject: [PATCH 39/53] FIxup intro --- README.md | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index f27e461..46653b6 100644 --- a/README.md +++ b/README.md @@ -23,23 +23,21 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S # 0. Abstract -This specification defines the semantics of revoking a [UCAN Delegation], and the ability to delegate such the ability to revoke a capability separately from the capability. +This specification defines the syntax and semantics of revoking a [UCAN Delegation], and the ability to delegate this ability to others. # 1. Introduction -Using the [principle of least authority][POLA] such as certificate expiry and reduced capability scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It is not a perfect method, and cannot undo irreversible actions already performed with capability, but MAY limit misuse going forward. +Using the [principle of least authority][POLA] such as certificate expiry and reduced capability scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It cannot undo irreversible mutations (such as sending an email), but MAY limit misuse going forward. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). -## 1.1 Motivation +Even when not in error at time of issuance, the trust relationship between a delegator and delegatee is not immutable. An agent can go rogue, keys can be compromised, and the privacy requirements of resources can (will!) change. While the UCAN Delegation approach RECOMMENDS using the [principle of least authority][POLA], unexpected conditions that require manual intervention do arise. These are exceptional cases, but are sufficiently important that a well defined method for performing revocation is nearly always desired in token and certificate systems. -Even when not in error at time of issuance, the trust relationship between a delegator and delegatee is not immutable. An agent can go rogue, keys can be compromised, and the privacy requirements of resources can change. While the UCAN delegation approach RECOMMENDS using the [principle of least authority][POLA], such unexpected conditions can and do arise. These are exceptional cases, but are sufficiently important that a well defined method for performing revocation is nearly always desired. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). +## 1.1 Approach -## 1.2 Approach +UCAN delegation is designed to be [local-first], partition-tolerant, cacheable, and latency-reducing. As such, [fail-stop] approaches are not suitable. Revocation is accomplished by delivery of an unforgeable message from a previous delegator. -UCAN delegation is designed to be [local-first]. As such, [fail-stop] approaches are not suitable. Revocation is accomplished by delivery of an unforgeable message from a previous delegator. +UCAN Revocations are similar to [block lists]: they identify delegation paths that are retracted and no longer suitable for use. Revocation SHOULD be considered the last line of defense against abuse. Proactive expiry through time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. -UCAN Revocations are similar to [block lists]: they identify delegations that are retracted and no longer suitable for use. Revocation SHOULD be considered the last line of defense against abuse. Proactive expiry through time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. - -A UCAN Revocation is a mechanism for invalidating a particular Delegation when used in conjunction with another Delegation in an Invocation proof chain. This is a second-order reference, and is described in the following diagram: +UCAN Revocation is a mechanism for invalidating a particular Delegation when used in conjunction with another Delegation in an Invocation proof chain. This is conceptually recursive, and more easily described in pictures: ``` mermaid flowchart RL @@ -271,8 +269,6 @@ flowchart LR # 5 Invocation Action -FIXME show delegation - A revocation Action MUST take the following shape: | Field | Value | @@ -289,14 +285,10 @@ Being expressed as an Invocation means that Revocations MUST define an Action ty | Field | Type | Required | Description | |-------|-----------------|----------|--------------------------------------------------------------------------| -| `rev` | `&Delegation` | Yes | The [UCAN Delegation] that is being revoked | +| `rev` | `&Delegation` | Yes | The CID of the [UCAN Delegation] that is being revoked | | `pth` | `[&Delegation]` | No | [A delegation path] that includes the Revoker and the revoked Delegation | -### 4.1.1 Revoked Delegation - -The target delegation MUST be referenced by its CID. - -### 4.1.2 Path Witness +### 4.1.1 Path Witness Since all delegation chains MUST be rooted in a Delegation where the `iss` and `sub` fields are equal, the root Issuer is a priori in every delegation chain. This is not the case for sub-delegation. There are many paths through the authority network. For exmaple, take the following delegation network: From f9d1a1ec712949ba17b948420b51a449afa4560e Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 21:21:04 -0700 Subject: [PATCH 40/53] Renumber, expand store section --- README.md | 87 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 46653b6..50ed69a 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,9 @@ This specification defines the syntax and semantics of revoking a [UCAN Delegati Using the [principle of least authority][POLA] such as certificate expiry and reduced capability scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It cannot undo irreversible mutations (such as sending an email), but MAY limit misuse going forward. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). -Even when not in error at time of issuance, the trust relationship between a delegator and delegatee is not immutable. An agent can go rogue, keys can be compromised, and the privacy requirements of resources can (will!) change. While the UCAN Delegation approach RECOMMENDS using the [principle of least authority][POLA], unexpected conditions that require manual intervention do arise. These are exceptional cases, but are sufficiently important that a well defined method for performing revocation is nearly always desired in token and certificate systems. +Even when not in error at time of issuance, the trust relationship between a delegator and delegatee is not immutable. An agent can go rogue, keys can be compromised, and the privacy requirements of resources can (will!) change. While the UCAN Delegation approach recommends following the [principle of least authority][POLA], unexpected conditions that require manual intervention do arise. These are exceptional cases, but are sufficiently important that a well defined method for performing revocation is nearly always desired in token and certificate systems. -## 1.1 Approach +# 2 Approach UCAN delegation is designed to be [local-first], partition-tolerant, cacheable, and latency-reducing. As such, [fail-stop] approaches are not suitable. Revocation is accomplished by delivery of an unforgeable message from a previous delegator. @@ -104,36 +104,34 @@ flowchart RL classDef revoked stroke:red,fill:#ff7676,color:red ``` -# 2 Semantics +# 3 Semantics -UCAN revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. All UCAN capabilities are either claimed by direct authority over the resource, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). +Revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. All UCAN capabilities are either claimed by direct authority over the Subject, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). -Revocations MUST be immutable and irreversible. Recipients of revocations SHOULD treat them as a grow-only set (see the [eviction] section). If a revocation was issued in error, it MUST NOT be retracted — a new, unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes [revocation stores] append-only and highly amenable to caching. +_Revocations MUST be immutable and irreversible._ Recipients of revocations SHOULD treat them as a monotonically-growing set. If a Revocation was issued in error, it MUST NOT be retracted — a new, unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes [revocation stores] append-only and highly amenable to caching and gossip. -## 2.1 Scope +## 3.1 Scope -An issuer of a proof in a delegation chain MAY revoke access to the capabilities that it granted. Note that this is not the same as revoking the specific delegation signed by the issuer: any UCAN that contains a proof where the revoker matches the `iss` field — even transitively in the delegation chain — MAY be revoked. +An Issuer of a particaular Delegation in a proof chain MAY revoke that Delegation. Note that this is not always the same as revoking the Delegation they they Issued; any UCAN that contains a proof where the revoker matches the `iss` field — even transitively in the delegation chain — MAY be revoked. -Revocation by a particular proof does not guarantee that the principle no longer has access to the capability in question. If a principal is able to construct a valid proof chain without relying on the revoked proof, they still have access to the capability. By real-world analogy, if Mallory has two tickets to a film, and one of them is invalidated by its serial number, she is still able to present the valid ticket to see the film. - -### 2.1.1 Example +Revocation of a particular proof does not guarantee that the Agent can no longer access to the capability in question. If an Agent is able to construct a valid proof chain without relying on the revoked proof, they still have access to the capability. By real-world analogy, if Mallory has two tickets to a film, and one of them is invalidated by its serial number, she is still able to present the valid ticket to see the film. ``` mermaid flowchart TB subgraph RA[Alice can revoke] direction RL - AB["(Root)\niss: Alice\naud: Bob\niff[X,Y,Z]"] + AB["(Root)\niss: Alice\naud: Bob\niff: [X,Y,Z]"] subgraph RB[Bob can revoke] - BC["iss: Bob\naud: Carol\niff [X,Y]"] - BD["iss: Bob\naud: Dan\niff[Y,Z]"] + BC["iss: Bob\naud: Carol\niff: [X,Y]"] + BD["iss: Bob\naud: Dan\niff: [Y,Z]"] subgraph RC[Carol can revoke] - CD["iss: Carol\naud: Dan\niff[X,Y]"] + CD["iss: Carol\naud: Dan\niff: [X,Y]"] subgraph RD[Dan can revoke] - DE["iss: Dan\naud: Erin\niff[X,Y,Z]"] + DE["iss: Dan\naud: Erin\niff: [X,Y,Z]"] end end end @@ -146,9 +144,9 @@ flowchart TB DE -->|proof| BD ``` -Here Alice is the root issuer / resource owner. Alice MAY revoke any of the UCANs in the chain, Carol MAY revoke the two innermost, and so on. If the UCAN `Carol to Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for the `X` capability, since its only proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice to Bob to Dan to Erin` includes them. Note that despite `Y` being in the revoked `Carol to Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. +Here Alice is the root Issuer. Alice MAY revoke any of the UCANs in the chain, Carol MAY revoke the two innermost, and so on. If the UCAN `Carol -> Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for the `X` capability, since its only proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice to Bob to Dan to Erin` includes them. Note that despite `Y` being in the revoked `Carol -> Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. -## 2.2 Consistency Models +## 3.2 Consistency Model UCAN revocation is designed to work in the broadest possible scenarios, and as such needs very weak constraints. UCAN revocation MAY operate in fully eventually consistent contexts, with single sources of truth, or among nodes participating in consensus. The format of the revocation does not change in these situations; it is entirely managed by how revocations are passed around the network. Weak assumptions enable UCAN to work with eventually consistent resources, such as [CRDT]s, [Git] forks, delay-tolerant replicated state machines, and so on. @@ -157,31 +155,37 @@ These weak assumptions are often associated with being unable to guarantee deliv Out of order delivery is typical of distributed systems. Further, a malicious user can otherwise delay revealing that they have a capability until the last possible moment in hopes of evading detection. Accepting revocations for resources that the agent controls prior to the delegation targeted by the revocation is received is thus RECOMMENDED. -# 3 Store - -The agent that controls a resource SHOULD maintain a cache of revocations that it has seen. Agents are not limited to only storing revocations for resources that they control. +# 4 Store -During validation of a UCAN delegation chain, the [canonical CID] of each UCAN delegation MUST be checked against the cache. If there's a match, the relevant delegation MUST be ignored. Note that this MAY NOT invalidate the entire UCAN chain. +The Agent that controls a resource MUST maintain a cache of Revocations for which it is the Subject. The Agent MAY additionally cache gossiped Revocations about other Subjects as part of a [store and forward] mechanism. -## 3.1 Locality +During validation of a UCAN delegation chain, the [canonical CID] of each UCAN delegation MUST be checked against the cache. If there's a match, the relevant Delegation MUST be ignored. Note that this MAY NOT invalidate the entire UCAN chain. -Revocation caches SHOULD be kept as close to the resource they describe as possible. +``` json +// Pseudocode -Resources with a single source of truth SHOULD follow the typical approach of maintaining a revocation store at the same physical location as the resource. For example, a centralized server MAY have an endpoint that lists the revoked UCANs by [canonical CID]. - -For eventually consistent data structures, this MAY be achieved by including the store directly inside the resource itself. For example, a CRDT-based file system SHOULD maintain the revocation store directly at a well-known path. +const proofs = invocation.prf +const delegators = new Set(proofs.map(proof => proof.iss)) -## 3.2 Eviction +proofs.forEach(delegation => { + // Is the proof in the revocation store? + store.lookup(delegation).then(revocation => { -Revocations MAY be deleted once the UCAN that they reference expires or otherwise becomes invalid through its proactive mechanisms. + // Is the revocation issuer in this proof chain? + if (delegators.has(revocation.iss)) { + throw new Error("Revoked") + } + }) +}) +``` -A revocation store MUST keep UCAN revocations for UCANs that are otherwise still valid. For example, expired UCANs are already invalid, so a revocation MUST NOT affect this invalid status. Such revocations are redundant, and MAY be evicted from the store. +## 4.1 Locality -## 3.3 Expiry +Resources with a single source of truth SHOULD follow the typical approach of maintaining a revocation store at the same physical location as the resource. For example, a centralized server MAY have an endpoint that lists the revoked UCANs by [canonical CID]. -Revocations MUST NOT expire. +For eventually consistent data structures, this MAY be achieved by including the store directly inside the resource itself. For example, a CRDT-based file system SHOULD maintain the revocation store directly at a well-known path. -## 3.4 Monotonicity +## 4.2 Monotonicity Since Revocations MUST NOT be reverable, a new Delegation SHOULD be issued if a Revocation was issued in error. @@ -218,7 +222,11 @@ flowchart LR linkStyle 7 stroke:green ``` -# 4 Delegation Ability +## 4.3 Eviction + +Revocations MAY be evicted once the UCAN that they reference expires or otherwise becomes invalid through its proactive mechanisms, such as expiry (`exp`) plus some clock-skew buffer. + +# 5 Delegating Revocation The authority to revoke some Delegation MAY be itself delegated to a Principal not in the delegation chain. This is a normal delegation: @@ -267,7 +275,7 @@ flowchart LR ``` -# 5 Invocation Action +# 6 Invoking Revocation A revocation Action MUST take the following shape: @@ -279,7 +287,7 @@ A revocation Action MUST take the following shape: Note that per [UCAN Invocation], the `nnc` field SHOULD is set to `""` since revocation is idempotent. -## 4.1 Arguments +## 6.1 Arguments Being expressed as an Invocation means that Revocations MUST define an Action type for the command `ucan/revoke`. @@ -288,7 +296,7 @@ Being expressed as an Invocation means that Revocations MUST define an Action ty | `rev` | `&Delegation` | Yes | The CID of the [UCAN Delegation] that is being revoked | | `pth` | `[&Delegation]` | No | [A delegation path] that includes the Revoker and the revoked Delegation | -### 4.1.1 Path Witness +### 6.1.1 Path Witness Since all delegation chains MUST be rooted in a Delegation where the `iss` and `sub` fields are equal, the root Issuer is a priori in every delegation chain. This is not the case for sub-delegation. There are many paths through the authority network. For exmaple, take the following delegation network: @@ -303,7 +311,7 @@ Mallory is not in the delegation chain of Erin. This is fine, since the semantic Unlike Mallory, Bob, Carol, and Dan can both provide valid delegation paths that include Delegations that they have issued. Bob has two paths (`Alice -> Bob -> Dan -> Erin` or `Alice -> Bob -> Carol -> Erin`), and either will suffice. -# 5 Prior Art +# 7 Prior Art [Revocation lists][Cert Revocation Wikipedia] are a fairly widely used concept. @@ -319,7 +327,7 @@ While strictly speaking being about assertions rather than capabilities, [Verfia [E][E-lang]-style [object capabilities][Robust Composition] use active network connections with [proxy agents][Robust Composition] to revoke delegations. Revocation is achieved by shutting down that proxy to break the authorizing reference. In many ways, UCAN Revocation attempts to emulate this behavior. Unlike UCAN Revocations, E-style object capabilities are [fail-stop] and thus by definition not partition tolerant. -# 6 Acknowledgements +# 8 Acknowledgements Thank you [Blaine Cook] for the real-world feedback, ideas on future features, and lessons from other auth standards. @@ -349,7 +357,7 @@ We want to especially recognize [Mark Miller] for his numerous contributions to -[Alan Karp]: https://github.com/alanhkarp + [Alan Karp]: https://github.com/alanhkarp [Benjamin Goering]: https://github.com/gobengo [Blaine Cook]: https://github.com/blaine [Bluesky]: https://blueskyweb.xyz/ @@ -408,4 +416,5 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [did:key RSA]: https://w3c-ccg.github.io/did-method-key/#rsa [external resource]: https://github.com/ucan-wg/spec#55-wrapping-existing-systems [revocation]: https://github.com/ucan-wg/revocation +[store and forward]: https://en.wikipedia.org/wiki/Store_and_forward [ucan.xyz]: https://ucan.xyz From 42fb59cfc6d49aede3560c3be6e03b677ad8861d Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 21:21:56 -0700 Subject: [PATCH 41/53] json -> js --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50ed69a..4ec4249 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ The Agent that controls a resource MUST maintain a cache of Revocations for whic During validation of a UCAN delegation chain, the [canonical CID] of each UCAN delegation MUST be checked against the cache. If there's a match, the relevant Delegation MUST be ignored. Note that this MAY NOT invalidate the entire UCAN chain. -``` json +``` js // Pseudocode const proofs = invocation.prf From 343e9f2d6396823625f072cf887725e4c37f5b3d Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 21:24:00 -0700 Subject: [PATCH 42/53] Less sophisticated, easier to follow --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4ec4249..625c743 100644 --- a/README.md +++ b/README.md @@ -163,16 +163,14 @@ During validation of a UCAN delegation chain, the [canonical CID] of each UCAN d ``` js // Pseudocode +const delegators = invocation.prf.map(proof => proof.iss) -const proofs = invocation.prf -const delegators = new Set(proofs.map(proof => proof.iss)) - -proofs.forEach(delegation => { +invocation.prf.forEach(delegation => { // Is the proof in the revocation store? store.lookup(delegation).then(revocation => { // Is the revocation issuer in this proof chain? - if (delegators.has(revocation.iss)) { + if (delegators.includes(revocation.iss)) { throw new Error("Revoked") } }) From aa02aa71da9b9a1f2f4c9f16e03def2459a51deb Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 21:34:29 -0700 Subject: [PATCH 43/53] I think that's most of it --- README.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 625c743..13a8332 100644 --- a/README.md +++ b/README.md @@ -168,10 +168,15 @@ const delegators = invocation.prf.map(proof => proof.iss) invocation.prf.forEach(delegation => { // Is the proof in the revocation store? store.lookup(delegation).then(revocation => { - // Is the revocation issuer in this proof chain? if (delegators.includes(revocation.iss)) { - throw new Error("Revoked") + throw new Error("Invalidated via revocation by delegation issuer") + } + + // Is the revocation based on a delegated revocation? + const cids = revocation.iff.filter(cav => !!cav.rev) + if (cids.length === 1 && invocation.prf.includes(cids[0])) { + throw new Error("Invalidated by delegated revocation") } }) }) @@ -226,7 +231,14 @@ Revocations MAY be evicted once the UCAN that they reference expires or otherwis # 5 Delegating Revocation -The authority to revoke some Delegation MAY be itself delegated to a Principal not in the delegation chain. This is a normal delegation: +The authority to revoke some Delegation MAY be itself delegated to a Principal not in the delegation chain. + +| Field | Value | +|-------|--------------------------| +| `can` | `"ucan/revoke"` | +| `iff` | `[{"rev": &Delegation}]` | + +This is a Delegation of the ability to Revoke: ``` js { @@ -272,7 +284,6 @@ flowchart LR linkStyle 10 stroke:red ``` - # 6 Invoking Revocation A revocation Action MUST take the following shape: From fb844159917dc365cef9bce5f2311b8682964151 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 21:48:37 -0700 Subject: [PATCH 44/53] CLarify --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 13a8332..4cf8612 100644 --- a/README.md +++ b/README.md @@ -202,7 +202,7 @@ flowchart LR del1{{Delegate\ncan: crud/read Alice's DB}} del2{{Delegate\ncan: crud/read Alice's DB}} del3{{Delegate\ncan: crud/read Alice's DB}} - newDel{{"Delegate\ncan: crud/read Alice's DB\n(Resissued) "}} + newDel{{"Delegate\ncan: crud/read Alice's DB\nnnc: "different-nonce"\n(Resissued) "}} Alice === del1 ==> Bob === del2:::Revoked ===x Carol === del3 ==> Dan Alice === newDel:::Reissued ===> Carol From 16f570513ea38135a3854d1bc1a327cbf1114b9a Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 21:48:58 -0700 Subject: [PATCH 45/53] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cf8612..9b27e34 100644 --- a/README.md +++ b/README.md @@ -202,7 +202,7 @@ flowchart LR del1{{Delegate\ncan: crud/read Alice's DB}} del2{{Delegate\ncan: crud/read Alice's DB}} del3{{Delegate\ncan: crud/read Alice's DB}} - newDel{{"Delegate\ncan: crud/read Alice's DB\nnnc: "different-nonce"\n(Resissued) "}} + newDel{{"Delegate\ncan: crud/read Alice's DB\nnnc: 'different-nonce'\n(Resissued) "}} Alice === del1 ==> Bob === del2:::Revoked ===x Carol === del3 ==> Dan Alice === newDel:::Reissued ===> Carol From ee02238cff0076931d52f69ebfb83b649fe25f45 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 22:02:43 -0700 Subject: [PATCH 46/53] missing links --- README.md | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9b27e34..8cdf16d 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Even when not in error at time of issuance, the trust relationship between a del # 2 Approach -UCAN delegation is designed to be [local-first], partition-tolerant, cacheable, and latency-reducing. As such, [fail-stop] approaches are not suitable. Revocation is accomplished by delivery of an unforgeable message from a previous delegator. +UCAN delegation is designed to be [local-first], partition-tolerant, cacheable, and latency-reducing. As such, [fail-safe] approaches are not suitable. Revocation is accomplished by delivery of an unforgeable message from a previous delegator. UCAN Revocations are similar to [block lists]: they identify delegation paths that are retracted and no longer suitable for use. Revocation SHOULD be considered the last line of defense against abuse. Proactive expiry through time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. @@ -108,7 +108,7 @@ flowchart RL Revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. All UCAN capabilities are either claimed by direct authority over the Subject, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). -_Revocations MUST be immutable and irreversible._ Recipients of revocations SHOULD treat them as a monotonically-growing set. If a Revocation was issued in error, it MUST NOT be retracted — a new, unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes [revocation stores] append-only and highly amenable to caching and gossip. +_Revocations MUST be immutable and irreversible._ Recipients of revocations SHOULD treat them as a monotonically-growing set. If a Revocation was issued in error, it MUST NOT be retracted — a new, unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes [revocation store]s append-only and highly amenable to caching and gossip. ## 3.1 Scope @@ -202,7 +202,7 @@ flowchart LR del1{{Delegate\ncan: crud/read Alice's DB}} del2{{Delegate\ncan: crud/read Alice's DB}} del3{{Delegate\ncan: crud/read Alice's DB}} - newDel{{"Delegate\ncan: crud/read Alice's DB\nnnc: 'different-nonce'\n(Resissued) "}} + newDel{{"Delegate\ncan: crud/read Alice's DB\n(Resissued) "}} Alice === del1 ==> Bob === del2:::Revoked ===x Carol === del3 ==> Dan Alice === newDel:::Reissued ===> Carol @@ -231,7 +231,7 @@ Revocations MAY be evicted once the UCAN that they reference expires or otherwis # 5 Delegating Revocation -The authority to revoke some Delegation MAY be itself delegated to a Principal not in the delegation chain. +The authority to revoke some Delegation MAY be itself delegated to a Principal not in the delegation chain. The revoked Delegation SHOULD be referenced by its [canonical CID]. | Field | Value | |-------|--------------------------| @@ -303,7 +303,7 @@ Being expressed as an Invocation means that Revocations MUST define an Action ty | Field | Type | Required | Description | |-------|-----------------|----------|--------------------------------------------------------------------------| | `rev` | `&Delegation` | Yes | The CID of the [UCAN Delegation] that is being revoked | -| `pth` | `[&Delegation]` | No | [A delegation path] that includes the Revoker and the revoked Delegation | +| `pth` | `[&Delegation]` | No | A [delegation path] that includes the Revoker and the revoked Delegation | ### 6.1.1 Path Witness @@ -334,7 +334,7 @@ Unlike Mallory, Bob, Carol, and Dan can both provide valid delegation paths that While strictly speaking being about assertions rather than capabilities, [Verfiable Credential Revocation][VC Revocation] spec follows a similar pattern to those listed above. -[E][E-lang]-style [object capabilities][Robust Composition] use active network connections with [proxy agents][Robust Composition] to revoke delegations. Revocation is achieved by shutting down that proxy to break the authorizing reference. In many ways, UCAN Revocation attempts to emulate this behavior. Unlike UCAN Revocations, E-style object capabilities are [fail-stop] and thus by definition not partition tolerant. +[E][E-lang]-style [object capabilities][Robust Composition] use active network connections with [proxy agents][Robust Composition] to revoke delegations. Revocation is achieved by shutting down that proxy to break the authorizing reference. In many ways, UCAN Revocation attempts to emulate this behavior. Unlike UCAN Revocations, E-style object capabilities are [fail-safe] and thus by definition not partition tolerant. # 8 Acknowledgements @@ -352,7 +352,7 @@ Thanks to the entire [SPKI WG][SPKI/SDSI] for their closely related pioneering w We want to especially recognize [Mark Miller] for his numerous contributions to the field of distributed auth, programming languages, and computer security writ large. -# 6. Acknowledgments +# 9. Acknowledgments Thanks to the entire [SPKI WG][SPKI/SDSI] for their closely related pioneering work. @@ -364,9 +364,14 @@ We want to especially recognize [Mark Miller] for his numerous contributions to +[Arguments]: #61-arguments +[delegation path]: #611-path-witness +[revocation store]: #4-store + - [Alan Karp]: https://github.com/alanhkarp +[ACL]: https://en.wikipedia.org/wiki/Access-control_list +[Alan Karp]: https://github.com/alanhkarp [Benjamin Goering]: https://github.com/gobengo [Blaine Cook]: https://github.com/blaine [Bluesky]: https://blueskyweb.xyz/ @@ -374,6 +379,8 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [Brian Ginsburg]: https://github.com/bgins [Brooklyn Zelenka]: https://github.com/expede [CIDv1]: https://github.com/multiformats/cid?tab=readme-ov-file#cidv1 +[CRDT]: https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type +[Cert Revocation Wikipedia]: https://en.wikipedia.org/wiki/Certificate_revocation [Christine Lemmer-Webber]: https://github.com/cwebber [Christopher Joel]: https://github.com/cdata [Command]: https://github.com/ucan-wg/spec#33-command @@ -382,10 +389,12 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [DID]: https://www.w3.org/TR/did-core/ [Dan Finlay]: https://github.com/danfinlay [Daniel Holmgren]: https://github.com/dholms +[E-lang]: http://www.erights.org/ [ES256]: https://www.rfc-editor.org/rfc/rfc7518#section-3.4 [EdDSA]: https://en.wikipedia.org/wiki/EdDSA [Executor]: https://github.com/ucan-wg/spec#31-roles [Fission]: https://fission.codes +[Git]: https://git-scm.com/ [Hugo Dias]: https://github.com/hugomrdias [IEEE-754]: https://ieeexplore.ieee.org/document/8766229 [IPLD]: https://ipld.io/ @@ -403,6 +412,8 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [PoLA]: https://en.wikipedia.org/wiki/Principle_of_least_privilege [Protocol Labs]: https://protocol.ai/ [RFC 3339]: https://www.rfc-editor.org/rfc/rfc3339 +[RFC 5280]: https://www.rfc-editor.org/rfc/rfc5280 +[RFC 7009]: https://www.rfc-editor.org/rfc/rfc7009 [RFC 8037]: https://www.rfc-editor.org/rfc/rfc8037 [RS256]: https://www.rfc-editor.org/rfc/rfc7518#section-3.3 [Raw data multicodec]: https://github.com/multiformats/multicodec/blob/master/table.csv#L41 @@ -413,17 +424,23 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [UCAN Delegation]: https://github.com/ucan-wg/delegation [UCAN Invocation]: https://github.com/ucan-wg/invocation [UCAN]: https://github.com/ucan-wg/spec +[VC Revocation]: https://learn.microsoft.com/en-us/azure/active-directory/verifiable-credentials/how-to-issuer-revoke [W3C]: https://www.w3.org/ [ZCAP-LD]: https://w3c-ccg.github.io/zcap-spec/ [`did:key`]: https://w3c-ccg.github.io/did-method-key/ [`did:plc`]: https://github.com/did-method-plc/did-method-plc [`did:web`]: https://w3c-ccg.github.io/did-method-web/ [base32]: https://github.com/multiformats/multibase/blob/master/multibase.csv#L13 +[block list]: https://en.wikipedia.org/wiki/Blacklist_(computing) +[canonical CID]: https://github.com/ucan-wg/spec#41-content-identifiers [dag-json multicodec]: https://github.com/multiformats/multicodec/blob/master/table.csv#L112 [did:key ECDSA]: https://w3c-ccg.github.io/did-method-key/#p-256 [did:key EdDSA]: https://w3c-ccg.github.io/did-method-key/#ed25519-x25519 [did:key RSA]: https://w3c-ccg.github.io/did-method-key/#rsa [external resource]: https://github.com/ucan-wg/spec#55-wrapping-existing-systems +[fail-safe]: https://en.wikipedia.org/wiki/Fail-safe +[local-first]: https://www.inkandswitch.com/local-first/ +[object capabilities]: https://en.wikipedia.org/wiki/Object-capability_model [revocation]: https://github.com/ucan-wg/revocation [store and forward]: https://en.wikipedia.org/wiki/Store_and_forward [ucan.xyz]: https://ucan.xyz From 12538d858e438007aaedbfd94ea5388c669ce002 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 22:04:28 -0700 Subject: [PATCH 47/53] miore missing links --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8cdf16d..8035aab 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ ## Language -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119]. +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP 14] when, and only when, they appear in all capitals, as shown here. # 0. Abstract @@ -35,7 +35,7 @@ Even when not in error at time of issuance, the trust relationship between a del UCAN delegation is designed to be [local-first], partition-tolerant, cacheable, and latency-reducing. As such, [fail-safe] approaches are not suitable. Revocation is accomplished by delivery of an unforgeable message from a previous delegator. -UCAN Revocations are similar to [block lists]: they identify delegation paths that are retracted and no longer suitable for use. Revocation SHOULD be considered the last line of defense against abuse. Proactive expiry through time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. +UCAN Revocations are similar to [block list]s: they identify delegation paths that are retracted and no longer suitable for use. Revocation SHOULD be considered the last line of defense against abuse. Proactive expiry through time bounds or other constraints SHOULD be preferred, as they do not require learning more information than what would be available on an offline computer. UCAN Revocation is a mechanism for invalidating a particular Delegation when used in conjunction with another Delegation in an Invocation proof chain. This is conceptually recursive, and more easily described in pictures: @@ -334,7 +334,7 @@ Unlike Mallory, Bob, Carol, and Dan can both provide valid delegation paths that While strictly speaking being about assertions rather than capabilities, [Verfiable Credential Revocation][VC Revocation] spec follows a similar pattern to those listed above. -[E][E-lang]-style [object capabilities][Robust Composition] use active network connections with [proxy agents][Robust Composition] to revoke delegations. Revocation is achieved by shutting down that proxy to break the authorizing reference. In many ways, UCAN Revocation attempts to emulate this behavior. Unlike UCAN Revocations, E-style object capabilities are [fail-safe] and thus by definition not partition tolerant. +[E][E-lang]-style [object capabilities] use active network connections with [proxy agents][Robust Composition] to revoke delegations. Revocation is achieved by shutting down that proxy to break the authorizing reference. In many ways, UCAN Revocation attempts to emulate this behavior. Unlike UCAN Revocations, E-style object capabilities are [fail-safe] and thus by definition not partition tolerant. # 8 Acknowledgements @@ -370,6 +370,7 @@ We want to especially recognize [Mark Miller] for his numerous contributions to +[Robust Composition]: http://www.erights.org/talks/thesis/markm-thesis.pdf [ACL]: https://en.wikipedia.org/wiki/Access-control_list [Alan Karp]: https://github.com/alanhkarp [Benjamin Goering]: https://github.com/gobengo From 11c52ecc28b9c00358931dcb6e27a9b633d9519e Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 22:05:19 -0700 Subject: [PATCH 48/53] more of same --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8035aab..a3c08b8 100644 --- a/README.md +++ b/README.md @@ -370,9 +370,9 @@ We want to especially recognize [Mark Miller] for his numerous contributions to -[Robust Composition]: http://www.erights.org/talks/thesis/markm-thesis.pdf [ACL]: https://en.wikipedia.org/wiki/Access-control_list [Alan Karp]: https://github.com/alanhkarp +[BCP 14]: https://www.rfc-editor.org/info/bcp14 [Benjamin Goering]: https://github.com/gobengo [Blaine Cook]: https://github.com/blaine [Bluesky]: https://blueskyweb.xyz/ @@ -418,6 +418,7 @@ We want to especially recognize [Mark Miller] for his numerous contributions to [RFC 8037]: https://www.rfc-editor.org/rfc/rfc8037 [RS256]: https://www.rfc-editor.org/rfc/rfc7518#section-3.3 [Raw data multicodec]: https://github.com/multiformats/multicodec/blob/master/table.csv#L41 +[Robust Composition]: http://www.erights.org/talks/thesis/markm-thesis.pdf [SHA2-256]: https://github.com/multiformats/multicodec/blob/master/table.csv#L9 [SPKI/SDSI]: https://datatracker.ietf.org/wg/spki/about/ [SPKI]: https://theworld.com/~cme/html/spki.html From 36644c33cc4379cc4d0b53fbebbe6ed2e5fb3e48 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 22:08:04 -0700 Subject: [PATCH 49/53] Spelling --- .custom-words.txt | 20 ++++++++++++++++++++ README.md | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/.custom-words.txt b/.custom-words.txt index db925e7..21e1e99 100644 --- a/.custom-words.txt +++ b/.custom-words.txt @@ -25,6 +25,7 @@ DIDs DNS DNSLinks Datalog +DoS ECDSA EdDSA GLVVQR @@ -33,6 +34,7 @@ Gozalishvili HEHYSF Haus Holmgren +IPLD Irakli JSON JWT @@ -45,12 +47,14 @@ Memoized Merkle Mikael MkiTBz +Monotonicity OAuth OCAP OCapN PITM PKI Philipp +Pseudocode RESTful RL RSA @@ -79,6 +83,7 @@ WG WebNative Webber ZCAP +Zelda Zelenka adoptability alice @@ -90,12 +95,14 @@ bene blockchain codec codecs +const crudGraph cryptographically del delegable delegatee delegator +delegators dereference disambiguates disjunct @@ -105,6 +112,7 @@ enums extractable filesystem fooey +forEach hawaii init inlining @@ -127,6 +135,16 @@ namespace namespaced namespaces naud +nbsp +nbsp +nbspAlice +nbspAlice +nbspBob +nbspBob +nbspCarol +nbspDan +nbspDan +nbspZelda ncap niss nota @@ -135,6 +153,8 @@ plaintext potencies pre preimages +prf +priori quG rc reauthorizations diff --git a/README.md b/README.md index a3c08b8..2fce998 100644 --- a/README.md +++ b/README.md @@ -307,7 +307,7 @@ Being expressed as an Invocation means that Revocations MUST define an Action ty ### 6.1.1 Path Witness -Since all delegation chains MUST be rooted in a Delegation where the `iss` and `sub` fields are equal, the root Issuer is a priori in every delegation chain. This is not the case for sub-delegation. There are many paths through the authority network. For exmaple, take the following delegation network: +Since all delegation chains MUST be rooted in a Delegation where the `iss` and `sub` fields are equal, the root Issuer is a priori in every delegation chain. This is not the case for sub-delegation. There are many paths through the authority network. For example, take the following delegation network: ``` mermaid flowchart LR @@ -316,7 +316,7 @@ flowchart LR Alice -->|delegates| Mallory ``` -Mallory is not in the delegation chain of Erin. This is fine, since the semantics of revocation merely state that she would assert that no delegation of hers may be used in the `prf` field of an Invocation if it also includes the `rev` Delegation. However, issuing spurious Revocations and requiring them to be stored is a potential DoS vector. Executors MAY require a delegation path witness be included to avoid this situaton. +Mallory is not in the delegation chain of Erin. This is fine, since the semantics of revocation merely state that she would assert that no delegation of hers may be used in the `prf` field of an Invocation if it also includes the `rev` Delegation. However, issuing spurious Revocations and requiring them to be stored is a potential DoS vector. Executors MAY require a delegation path witness be included to avoid this situation. Unlike Mallory, Bob, Carol, and Dan can both provide valid delegation paths that include Delegations that they have issued. Bob has two paths (`Alice -> Bob -> Dan -> Erin` or `Alice -> Bob -> Carol -> Erin`), and either will suffice. From 8bd51c1ca86d4727c830fb5d4334ed3ad27f82fb Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 22:09:19 -0700 Subject: [PATCH 50/53] Dictionary --- .custom-words.txt | 1 + README.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.custom-words.txt b/.custom-words.txt index 21e1e99..f13e8c5 100644 --- a/.custom-words.txt +++ b/.custom-words.txt @@ -93,6 +93,7 @@ auth autonumber bene blockchain +cacheable codec codecs const diff --git a/README.md b/README.md index 2fce998..0a8ef21 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ _Revocations MUST be immutable and irreversible._ Recipients of revocations SHOU ## 3.1 Scope -An Issuer of a particaular Delegation in a proof chain MAY revoke that Delegation. Note that this is not always the same as revoking the Delegation they they Issued; any UCAN that contains a proof where the revoker matches the `iss` field — even transitively in the delegation chain — MAY be revoked. +An Issuer of a particular Delegation in a proof chain MAY revoke that Delegation. Note that this is not always the same as revoking the Delegation they they Issued; any UCAN that contains a proof where the revoker matches the `iss` field — even transitively in the delegation chain — MAY be revoked. Revocation of a particular proof does not guarantee that the Agent can no longer access to the capability in question. If an Agent is able to construct a valid proof chain without relying on the revoked proof, they still have access to the capability. By real-world analogy, if Mallory has two tickets to a film, and one of them is invalidated by its serial number, she is still able to present the valid ticket to see the film. @@ -190,7 +190,7 @@ For eventually consistent data structures, this MAY be achieved by including the ## 4.2 Monotonicity -Since Revocations MUST NOT be reverable, a new Delegation SHOULD be issued if a Revocation was issued in error. +Since Revocations MUST NOT be reversable, a new Delegation SHOULD be issued if a Revocation was issued in error. ``` mermaid flowchart LR From 523240f13711861ada99d4c8b0818281a720477d Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Tue, 17 Oct 2023 22:10:47 -0700 Subject: [PATCH 51/53] a -> i --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a8ef21..0638e3f 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ For eventually consistent data structures, this MAY be achieved by including the ## 4.2 Monotonicity -Since Revocations MUST NOT be reversable, a new Delegation SHOULD be issued if a Revocation was issued in error. +Since Revocations MUST NOT be reversible, a new Delegation SHOULD be issued if a Revocation was issued in error. ``` mermaid flowchart LR From ced1d1c748e66c99c9e104f96d926480716a5bf2 Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 20 Dec 2023 18:19:31 +0200 Subject: [PATCH 52/53] Add example --- README.md | 104 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 0638e3f..26473ce 100644 --- a/README.md +++ b/README.md @@ -21,17 +21,17 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [BCP 14] when, and only when, they appear in all capitals, as shown here. -# 0. Abstract +# Abstract This specification defines the syntax and semantics of revoking a [UCAN Delegation], and the ability to delegate this ability to others. -# 1. Introduction +# Introduction Using the [principle of least authority][POLA] such as certificate expiry and reduced capability scope SHOULD be the preferred method for securing a UCAN, but does not cover every situation. Revocation is a manual method for reversing a delegation. It cannot undo irreversible mutations (such as sending an email), but MAY limit misuse going forward. Revocation is the act of invalidating a UCAN after the fact, outside of the limitations placed on it by the UCAN's fields (such as its expiry). Even when not in error at time of issuance, the trust relationship between a delegator and delegatee is not immutable. An agent can go rogue, keys can be compromised, and the privacy requirements of resources can (will!) change. While the UCAN Delegation approach recommends following the [principle of least authority][POLA], unexpected conditions that require manual intervention do arise. These are exceptional cases, but are sufficiently important that a well defined method for performing revocation is nearly always desired in token and certificate systems. -# 2 Approach +# Approach UCAN delegation is designed to be [local-first], partition-tolerant, cacheable, and latency-reducing. As such, [fail-safe] approaches are not suitable. Revocation is accomplished by delivery of an unforgeable message from a previous delegator. @@ -104,13 +104,13 @@ flowchart RL classDef revoked stroke:red,fill:#ff7676,color:red ``` -# 3 Semantics +# Semantics Revocation is the act of invalidating a proof in a delegation chain for some specific UCAN delegation by its CID. All UCAN capabilities are either claimed by direct authority over the Subject, or by delegation chain terminating in that direct ("root") authority. Each link in a delegation chain contains an explicit issuer (delegator) and audience (delegatee). _Revocations MUST be immutable and irreversible._ Recipients of revocations SHOULD treat them as a monotonically-growing set. If a Revocation was issued in error, it MUST NOT be retracted — a new, unique UCAN delegation MAY be issued (e.g. by updating the nonce or changing the time bounds). This prevents confusion as the revocation moves through the network and makes [revocation store]s append-only and highly amenable to caching and gossip. -## 3.1 Scope +## Scope An Issuer of a particular Delegation in a proof chain MAY revoke that Delegation. Note that this is not always the same as revoking the Delegation they they Issued; any UCAN that contains a proof where the revoker matches the `iss` field — even transitively in the delegation chain — MAY be revoked. @@ -146,7 +146,7 @@ flowchart TB Here Alice is the root Issuer. Alice MAY revoke any of the UCANs in the chain, Carol MAY revoke the two innermost, and so on. If the UCAN `Carol -> Dan` is revoked by Alice, Bob, or Carol, then Erin will not have a valid chain for the `X` capability, since its only proof is invalid. However, Erin can still prove the valid capability for `Y` and `Z` since the still-valid ("unbroken") chain `Alice to Bob to Dan to Erin` includes them. Note that despite `Y` being in the revoked `Carol -> Dan` UCAN, it does not invalidate `Y` for Erin, since the unbroken chain also included a proof for `Y`. -## 3.2 Consistency Model +## Consistency Model UCAN revocation is designed to work in the broadest possible scenarios, and as such needs very weak constraints. UCAN revocation MAY operate in fully eventually consistent contexts, with single sources of truth, or among nodes participating in consensus. The format of the revocation does not change in these situations; it is entirely managed by how revocations are passed around the network. Weak assumptions enable UCAN to work with eventually consistent resources, such as [CRDT]s, [Git] forks, delay-tolerant replicated state machines, and so on. @@ -155,7 +155,7 @@ These weak assumptions are often associated with being unable to guarantee deliv Out of order delivery is typical of distributed systems. Further, a malicious user can otherwise delay revealing that they have a capability until the last possible moment in hopes of evading detection. Accepting revocations for resources that the agent controls prior to the delegation targeted by the revocation is received is thus RECOMMENDED. -# 4 Store +# Store The Agent that controls a resource MUST maintain a cache of Revocations for which it is the Subject. The Agent MAY additionally cache gossiped Revocations about other Subjects as part of a [store and forward] mechanism. @@ -182,13 +182,13 @@ invocation.prf.forEach(delegation => { }) ``` -## 4.1 Locality +## Locality Resources with a single source of truth SHOULD follow the typical approach of maintaining a revocation store at the same physical location as the resource. For example, a centralized server MAY have an endpoint that lists the revoked UCANs by [canonical CID]. For eventually consistent data structures, this MAY be achieved by including the store directly inside the resource itself. For example, a CRDT-based file system SHOULD maintain the revocation store directly at a well-known path. -## 4.2 Monotonicity +## Monotonicity Since Revocations MUST NOT be reversible, a new Delegation SHOULD be issued if a Revocation was issued in error. @@ -225,18 +225,18 @@ flowchart LR linkStyle 7 stroke:green ``` -## 4.3 Eviction +## Eviction Revocations MAY be evicted once the UCAN that they reference expires or otherwise becomes invalid through its proactive mechanisms, such as expiry (`exp`) plus some clock-skew buffer. -# 5 Delegating Revocation +# Delegating Revocation The authority to revoke some Delegation MAY be itself delegated to a Principal not in the delegation chain. The revoked Delegation SHOULD be referenced by its [canonical CID]. -| Field | Value | -|-------|--------------------------| -| `can` | `"ucan/revoke"` | -| `iff` | `[{"rev": &Delegation}]` | +| Field | Value | +|--------|---------------------------| +| `can` | `"ucan/revoke"` | +| `args` | `{"revoke": &Delegation}` | This is a Delegation of the ability to Revoke: @@ -244,11 +244,10 @@ This is a Delegation of the ability to Revoke: { "iss": "did:web:alice.example.com", "aud": "did:web:zelda.example.com", - "sub": "did:web:alice.example.com", "can": "ucan/revoke", - "iff": [ - {"rev": {"/": "bafkreiem4on23qnu2nn2jg7vwzxkns6sxi5faysq7ekwtjhugqga3vbhim"}} - ], + "args": { + "revoke": {"/": "bafkreiem4on23qnu2nn2jg7vwzxkns6sxi5faysq7ekwtjhugqga3vbhim"} + }, // ... } ``` @@ -284,28 +283,28 @@ flowchart LR linkStyle 10 stroke:red ``` -# 6 Invoking Revocation +# Invoking Revocation A revocation Action MUST take the following shape: -| Field | Value | -|-------|-----------------| -| `cmd` | `"ucan/revoke"` | -| `arg` | See [Arguments] | -| `nnc` | `""` | +| Field | Value | +|---------|-----------------| +| `do` | `"ucan/revoke"` | +| `args` | See [Arguments] | +| `nonce` | `""` | Note that per [UCAN Invocation], the `nnc` field SHOULD is set to `""` since revocation is idempotent. -## 6.1 Arguments +## Arguments Being expressed as an Invocation means that Revocations MUST define an Action type for the command `ucan/revoke`. -| Field | Type | Required | Description | -|-------|-----------------|----------|--------------------------------------------------------------------------| -| `rev` | `&Delegation` | Yes | The CID of the [UCAN Delegation] that is being revoked | -| `pth` | `[&Delegation]` | No | A [delegation path] that includes the Revoker and the revoked Delegation | +| Field | Type | Required | Description | +|----------|-----------------|----------|--------------------------------------------------------------------------| +| `revoke` | `&Delegation` | Yes | The CID of the [UCAN Delegation] that is being revoked | +| `path` | `[&Delegation]` | No | A [delegation path] that includes the Revoker and the revoked Delegation | -### 6.1.1 Path Witness +### Path Witness Since all delegation chains MUST be rooted in a Delegation where the `iss` and `sub` fields are equal, the root Issuer is a priori in every delegation chain. This is not the case for sub-delegation. There are many paths through the authority network. For example, take the following delegation network: @@ -320,7 +319,38 @@ Mallory is not in the delegation chain of Erin. This is fine, since the semantic Unlike Mallory, Bob, Carol, and Dan can both provide valid delegation paths that include Delegations that they have issued. Bob has two paths (`Alice -> Bob -> Dan -> Erin` or `Alice -> Bob -> Carol -> Erin`), and either will suffice. -# 7 Prior Art +### Example + +``` js +// DAG-JSON +{ + "s": {"/": {"bytes": "7aEDQIscUKVuAIB2Yj6jdX5ru9OcnQLxLutvHPjeMD3pbtHIoErFpo7OoC79Oe2ShgQMLbo2e6dvHh9scqHKEOmieA0"}}, + "p": { + "h": {"/": {"bytes": "NBIFEgEAcQ"}}, + "ucan/i/1.0.0-rc.1": { + "iss": "did:plc:ewvi7nxzyoun6zhxrhs64oiz", + "sub": "did:key:z6MkrZ1r5XBFZjBU34qyD8fueMbMRkKw17BZaq2ivKFjnz2z", + "do": "ucan/revoke", + "args": { + "revoke": {"/": "bafkreictzcfwelyww7zmjkl5nptyot24oilky2bppw42nui2acozhfmzqa"}, + "path": [ + {"/": "bafkreic4lzfu6gq6pxonmalbjzjumrs5p47plsolmccaz4qhgmzo24fagu"}, + {"/": bafkreicc3jmhhtkzv26rb43cfx6ihyjlj2hixdfrkirglrermfo6cduelm""} + ] + }, + "nonce": {"/": {"bytes": ""}}, + "meta": { + "comment": "bad behaviour" + }, + "prf": [ + {"/": "bafkr4idnrqfouibxdqpvh2lmkhgsbw5yabvjbiaea3fplrb4vxifaphvgy"}, + ] + } + } +} +``` + +# Prior Art [Revocation lists][Cert Revocation Wikipedia] are a fairly widely used concept. @@ -336,7 +366,7 @@ While strictly speaking being about assertions rather than capabilities, [Verfia [E][E-lang]-style [object capabilities] use active network connections with [proxy agents][Robust Composition] to revoke delegations. Revocation is achieved by shutting down that proxy to break the authorizing reference. In many ways, UCAN Revocation attempts to emulate this behavior. Unlike UCAN Revocations, E-style object capabilities are [fail-safe] and thus by definition not partition tolerant. -# 8 Acknowledgements +# Acknowledgements Thank you [Blaine Cook] for the real-world feedback, ideas on future features, and lessons from other auth standards. @@ -352,7 +382,7 @@ Thanks to the entire [SPKI WG][SPKI/SDSI] for their closely related pioneering w We want to especially recognize [Mark Miller] for his numerous contributions to the field of distributed auth, programming languages, and computer security writ large. -# 9. Acknowledgments +# Acknowledgments Thanks to the entire [SPKI WG][SPKI/SDSI] for their closely related pioneering work. @@ -364,9 +394,9 @@ We want to especially recognize [Mark Miller] for his numerous contributions to -[Arguments]: #61-arguments -[delegation path]: #611-path-witness -[revocation store]: #4-store +[Arguments]: #arguments +[delegation path]: #path-witness +[revocation store]: #store From 230495e70fdc5e1b359a9b3517a157852f39d70e Mon Sep 17 00:00:00 2001 From: Brooklyn Zelenka Date: Wed, 20 Dec 2023 18:25:05 +0200 Subject: [PATCH 53/53] Remove duplicate Ack section --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index 26473ce..fc246d2 100644 --- a/README.md +++ b/README.md @@ -382,14 +382,6 @@ Thanks to the entire [SPKI WG][SPKI/SDSI] for their closely related pioneering w We want to especially recognize [Mark Miller] for his numerous contributions to the field of distributed auth, programming languages, and computer security writ large. -# Acknowledgments - -Thanks to the entire [SPKI WG][SPKI/SDSI] for their closely related pioneering work. - -Many thanks to [Alan Karp] for sharing his vast experience with capability-based authorization, patterns, and many right words for us to search for. - -We want to especially recognize [Mark Miller] for his numerous contributions to the field of distributed auth, programming languages, and computer security writ large. -