From cc4bb8fede5d88140db7c0b03cf6bb2dc84a2da2 Mon Sep 17 00:00:00 2001 From: Joel Thorstensson Date: Fri, 13 Jan 2023 14:22:24 +0000 Subject: [PATCH 1/9] Rewrite of 3ID --- CIPs/cip-79.md | 525 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 348 insertions(+), 177 deletions(-) diff --git a/CIPs/cip-79.md b/CIPs/cip-79.md index de3e7b5..7bbb021 100644 --- a/CIPs/cip-79.md +++ b/CIPs/cip-79.md @@ -1,281 +1,452 @@ --- cip: 79 -title: 3ID DID Method Specification +title: 3 DID Method Specification author: Joel Thorstensson (@oed) discussions-to: https://github.com/ceramicnetwork/CIP/issues/80 status: Draft category: Standards -type: RFC +type: Core created: 2021-02-12 +updated: 2023-01-13 --- -# 3ID DID Method Specification +## Simple Summary -3ID is a DID method that is implemented natively on Ceramic. It uses the Tile Document StreamType to create a mutable stream that stores the information which makes up the DID document for the 3ID. The Tile Document StreamType supports secure key rotation for 3IDs since its updates must be anchored into a blockchain, providing explicit versions and *proof-of-publication* at specific points in time (blockheights). This means that 3ID inherits this property. + +The 3 DID method enables users to compose multiple accounts into a signle identifier. -## DID Method Name -The name string that shall identify this DID method is: `3`. +## Abstract -A DID that uses this method MUST begin with the following prefix: `did:3`. Per the [DID specification](https://w3c.github.io/did-core/), this string MUST be in lowercase. The remainder of the DID, after the prefix, is specified below. + +With a special type of Ceramic stream 3ID enables a revocation registry that can be used to add and remove verification methods from the 3 DID method as well as revoke any capability issued by the identifier. The revocation registry is based on hashes of object-capabilities encoded as CACAO. -## Method Specific Identifier -There are two versions of 3IDs. Both versions use a Ceramic Tile Document StreamType as a way to update the DID document. 3IDv1 is the most recent version, however 3IDv0 is supported for legacy reasons. If you are creating new 3IDs you should always use 3IDv1. Both versions are always encoded using multibase. To determine if it's v1 or v0, first convert the multibase string into a byte array. If the first varint is `0x01` it's a 3IDv0, and if the first varint is `0xce` it's a 3IDv1. +## Motivation -### 3IDv1 + +Currently in Ceramic the main accounts types are PKH DID. These are great because they enable existing wallets to be used directly with Ceramic. However, these accounts are inherently tied to a specific account and there is no way to rotate keys in a simple manner. The 3 DID method changes this by defining a DID method which works with object-capabilities and supports all DID CRUD operations. -The method specific identifier for 3IDv1 is simply a Ceramic StreamID. The StreamID used refers to the Ceramic stream which contains the information needed to construct the DID Document upon resolution. StreamIDs are encoded according to [CIP-59](https://github.com/ceramicnetwork/CIP/blob/master/CIPs/CIP-59/CIP-59.md). +Furthermore, the revocation regsitry of the 3 DID method enables the DID subject to revoke any object-capability issued by the 3ID. This can be useful in case of a key compromise, e.g. for a temporary session key. -``` -3idv1 = "did:3:" -``` +## Specification -#### Example + +Specification goes here. -```sh -did:3:kjzl6cwe1jw149tlplc4bgnpn1v4uwk9rg9jkvijx0u0zmfa97t69dnqibqa2as -``` +### The did:3 identifier -### 3IDv0 +> ``` +> did:3: +> ``` -The method specific identifier for 3IDv0 is a [CID](https://github.com/multiformats/cid) as produced by the [IPLD](https://github.com/ipld/specs) codec [dag-cbor](https://github.com/ipld/specs/blob/master/block-layer/codecs/dag-cbor.md). +The `` value is a `keccak-256` multihash over the CID of a CACAO object-capability, e.g. ReCap or UCAN. The value MUST be encoded as a multibase string, using `base58btc`. -``` -3idv0 = "did:3:" -``` +***Simple example:*** + +> ``` +> did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj +> ``` -#### Example +### CRUD Operation Definitions -```sh -did:3:bafyreiffkeeq4wq2htejqla2is5ognligi4lvjhwrpqpl2kazjdoecmugi +3IDs are created, updated, and deactivated by creating, notarizing, and revoking object-capabilities in the form of CACAOs. + +#### Create + +Create and sign a [SIWx](https://chainagnostic.org/CAIPs/caip-122) message where: + +- `address` - a blockchain address (e.g. `0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2`) +- `uri` - the PKH DID for the same address (e.g. `did:pkh:eip155:1:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2`) + +And resources contains the following ReCap object: + +```java +{ + "att": { + "did:3:new": { "3id/control": [] } + } +} +``` + +- *When signing this would look something like this for the user:* + + ``` + example.com wants you to sign in with your Ethereum account: + 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 + + I further authorize https://example.com to perform the following + actions on my behalf: (1) "3id/control" for "did:3:new". + + URI: did:pkh:eip155:1:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 + Version: 1 + Chain ID: 1 + Nonce: n-0S6_WzA2Mj + Issued At: 2022-06-21T12:00:00.000Z + Resources: + - urn:recap:example:eyJkZWYiOlsicmVhZCJdLCJ0YXIiOnsibXkucmVzb3VyY2UuMSI6WyJhcHBlbmQiLCJkZWxldGUiXSwibXkucmVzb3VyY2UuMiI6WyJhcHBlbmQiXSwibXkucmVzb3VyY2UuMyI6WyJhcHBlbmQiXX19 + ``` + +##### Create the DID + +```jsx +cacaoCID = ipld.put(CACAO(SIWx-message, signature)) +did = 'did:3:' + multihash(cacaoCID) ``` -## CRUD Operation Definitions +#### Read -In this section the CRUD operations for a 3ID DID are defined. +To read you must load a deterministic Ceramic stream to find any updates made to the 3ID. -### Create +1. Load the revocation registry Ceramic stream -A `3` DID is created by simply creating a stream that conforms to the [`tile document`](https://github.com/ceramicnetwork/CIP/blob/master/CIPs/CIP-8/CIP-8.md) StreamType. The [`tile document`](https://github.com/ceramicnetwork/CIP/blob/master/CIPs/CIP-8/CIP-8.md) takes a DID as the *controller*, and it's recommended that a `did:key` is used. The *controller* is the DID which is allowed to update the stream. The *family* of the stream is set to `3id`, and the *deterministic* flag is set to `true`. + 1. If the `?versionTime=` is specified load only the events `≤ timestamp` -Now the content of the stream should consist of a JSON object with one property *publicKeys*. These public keys will be allowed to sign messages on behalf of the 3ID, or decrypt messages encrypted to the 3ID. The value of this property should be an object where the value is a [multicodec](https://github.com/multiformats/multicodec/) + multibase(*base58btc*) encoded public key, the key for any given key should be the last *15* characters of the encoded public key. +2. Read all entries where `isRevoked = false` -The 3ID DID method supports any type of public key that can be encoded using multicodec which can easily be extended to support quantum resistant signature and encryption schemes in the future. +3. For every CACAO multihash in the registry, as well as the 3ID identifier, -#### Example + 1. Add the following object to the `verificationMethod` property of the DID document, + + ```json + { + "id": "#", + "type": "capabilityHash", + "controller": "did:3:", + "multihash": "" + } + ``` + + 2. Add `"#"` to the following fields, + + 1. `authentication` + 2. `assertionMethod` + 3. `capabilityDelegation` + 4. `capabilityInvocation` -Below you can see an example of how to create a 3ID using the Ceramic javascript api. +##### Example DID Document -```js -const doc = await ceramic.createDocument({ - metadata: { - controllers: ['did:key:zQ3shQNcackrTByiYaPGso1Nt7b6r1gSMg4XXBmavzvTMqX1h'], // secp256k1 did:key - family: '3id' - }, - content: { - publicKeys: { - "XQCT2xJHsdY6iJH": "z6LSqKWh3XQ7AfsJuE2KR23cozEut8D5CXQCT2xJHsdY6iJH", // x22519 public key - "yh27jTt7Ny2Pwdy": "zQ3shrMGEKAjUTMmvDkcZ7Y3x9XnVjTH3myh27jTt7Ny2Pwdy", // secp256k1 public key - } - }, - deterministic: true -}) +For `did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj` with no entires in the Revocation registry, -const didString = `did:3:${doc.id}` +```json +{ + "@context": [ + "", + ] + "id": "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", + "verificationMethod": [{ + "id": "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", + "type": "capabilityHash", + "controller": "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", + "multihash": "z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" + }], + "authentication": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], + "assertionMethod": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], + "capabilityDelegation": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], + "capabilityInvocation": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], +} ``` -### Read/Verify +#### Update -Resolving a 3ID is quite straight forward. It is done by taking the StreamID from the method specific identifier, looking up the referred stream using Ceramic, and converting the content of the stream into a DID document. +##### To add a verification method: -#### Loading 3IDv1 stream +1. Create a new ReCap capability with an existing VM as the issuer, delegating `"3id/control"` to another DID (PKH or Key DID), and encode it as a CACAO. -To load a 3IDv1 document simply take the StreamID from the method specific identifier and load the stream from ceramic. + ***ReCap*** -#### Loading 3IDv0 document + ```json + { + "att": { + "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj": { "3id/control": [] } + } + } + ``` -To load a 3IDv0 document, first take the CID from the method specific identifier and load the corresponding object from the IPFS network. The resolved object will contain a `publicKey` property which has an array of public key objects (see [Appendix A](#appendix-a)). + - *When signing this would look something like this for the user:* -Now find the key with an id that ends in `#signingKey` and convert it to a multicodec encoded key (in compressed format), then use it as a `did:key` and look up the ceramic document which has this key as the *controller* and *family* set to `3id`, using the *deterministic* flag. Below you can see the code to do this with the javascript Ceramic api. + ``` + example.com wants you to sign in with your Ethereum account: + 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 + + I further authorize https://example.com to perform the following + actions on my behalf: (1) "3id/control" for "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj". + + URI: did:pkh:eip155:1:0xa05bba39b223fe8d0a0e5c4f27ead9083cb22ee3 + Version: 1 + Chain ID: 1 + Nonce: n-0S6_WzA2Mj + Issued At: 2022-06-21T12:00:00.000Z + Resources: + - urn:recap:example:eyJkZWYiOlsicmVhZCJdLCJ0YXIiOnsibXkucmVzb3VyY2UuMSI6WyJhcHBlbmQiLCJkZWxldGUiXSwibXkucmVzb3VyY2UuMiI6WyJhcHBlbmQiXSwibXkucmVzb3VyY2UuMyI6WyJhcHBlbmQiXX19 + ``` +2. Load the *Revocation Registry* stream +3. Update (2) by adding the `cacao-mh` from (1) -```js -const doc = await ceramic.createDocument({ - metadata: { - controllers: [didKey], // secp256k1 did:key - family: '3id' - }, - deterministic: true -}) -``` +***To remove a verification method:*** -#### Converting the loaded Ceramic stream to the DID document +1. Load the *Revocation Registry* stream +2. Update (1) by removing the `cacao-mh` that is being revoked -Once we have the stream loaded, load the latest *AnchorCommit* in the stream (the latest commit that was anchored to a blockchain). Then get the content of the stream at this `AnchorCommit`, which will look something like this: +#### Deactivate -```json -{ - "publicKeys": { - "j9uh8iKHSDSLat4": "zQ3shaLgXkpEXt7He5mogBxFfib5cE2kv9j9uh8iKHSDSLat4", - "qYfZN2QNDgjJpaL": "z6LSnTyV1nSWfMmfV1PoRmo3enhDnfqfFqYfZN2QNDgjJpaL" - } +In order to deactivate a 3ID all capabilities will need to be revoked. + +### Revocation Registry + +3ID is based on a self-certifying revocation registry represented as a special type of Ceramic stream. In it any verification method belonging to the 3ID can be registered and revoked. Every update to the registry is recorded as a *Data Event*. When a new event is created is needs to include a valid delegation chain back to previous version of the registry. + +```verilog +type Prinicipal Bytes // multidid +type CACAOHash Bytes // multihash +type Varsig Bytes // varsig + +type RevocationEntry struct { + key CACAOHash + isRevoked Boolean +} representation tuple +// The registry should eventually be a HAMT or similar data structure +type Regsitry { CACAOHash : RevocationEntry } +type Snapshot struct { + registry &Regsitry + actions [RevocationEntry] } ``` -To convert this into a DID document first create an empty DID document: +#### Ceramic Stream -```json -{ - "@context": "https://w3id.org/did/v1", - "id": "", - "verificationMethod": [], - "authentication": [], - "keyAgreement": [] +```verilog +type Event InitEvent | DataEvent | TimeEvent + +type InitEvent &Prinicipal // an inline CID containing raw principal bytes + +type DataEvent struct { + id &InitEvent + prv [&Event] // is prv needed if it's the first event after genesis? + prf [&CACAO] // capabilities used to emit this event + data &Snapshot + sig Varsig +} + +type EthereumTx // + +type BlockchainTimestamp struct { + root Link + chainID String + txType String + txHash &EthereumTx +} + +type TimeEvent struct { + id &InitEvent + prv [&DataEvent] // should always be one CID + proof &BlockchainTimestamp + path String } ``` -Now iterate though the entires in the `publicKeys` object in the Ceramic stream and do the following: +#### Streamid -* If it's a `secp256k1` key: +Generating the Ceramic streamid can be done in three steps, - * Add a `Secp256k1VerificationKey2018` to the *verificationMethod* array: +1. Generate the multidid representation of the 3ID, - ```js - { - id: "#", - type: "EcdsaSecp256k1Signature2019", - controller: "", - publicKeyBase58: "" - } - ``` + ```solidity + := + ``` - * Add a `Secp256k1SignatureAuthentication2018` to the *authentication* array: +2. Encode the multidid as an inline CID, - ```js - { - id: "#", - type: "EcdsaSecp256k1Signature2019", - controller: "", - publicKeyBase58: "" - } - ``` + ```solidity + := + ``` -* If it's a `x25519` key: +3. Encode the Streamid - * Add a `Curve25519EncryptionPublicKey` to the *verificationMethod* array: + ```solidity + := + ``` - ```js - { - id: "#", - type: "X25519KeyAgreementKey2019", - controller: "", - publicKeyBase58: "" - } - ``` +#### Create a `DataEvent` - * Add a `X25519KeyAgreementKey2019` to the *keyAgreement* array: +New data events - ```js - { - id: "#", - type: "X25519KeyAgreementKey2019", - controller: "", - publicKeyBase58: "" - } - ``` +1. Attain a key with a valid capability chain to the most recent *previous data event(s)* -##### 3IDv0 genesis +2. Create one or more `RevocationEntry` objects and update the `State` from the -Since the content of the Ceramic document for a 3IDv0 is empty at the *GenesisCommit* we create the DID document by taking the public keys in the 3IDv0 genesis object (see [Appendix A](#appendix-a)) and convert them to multicodec public keys (one `secp256k1` and one `x25519`). The key properties in the DID document should be constructed as above, with the *entry-key* being the last *15* characters of the multicodec encoded keys. + previous data event(s): -##### DID Document Metadata + 1. Write the objects to a new array and store them on the `actions` field + 2. Also append them to the `registry` map -When resolving the DID document [DID Document Metadata](https://w3c.github.io/did-core/#did-document-metadata) should be provided. When resolving a 3ID we should populate the following fields: +3. Create the `DataEvent` struct, -* `create` - should be populated using the blockchain timestamp from the first *AnchorCommit* -* `updated` - should be populated using the blockchain timestamp from the most recent *AnchorCommit* -* `versionId` - should be equal to the commit CID from the most recent *AnchorCommit* + 1. Set `id` to the principal (an inline CID containing a multidid encoded 3ID), + 2. Add the capability chain used to the `prf` field + 3. Add the previous events to the `prv` field + 4. Add the updated state to the `data` field + 5. Create a `Varsig` over the `DataEvent` with the key from (1) and add the `sig` field -#### Resolving using the `versionId` parameter +#### Validating a `DataEvent` -When the `versionId` query parameter is given as a DID is resolved it means that we should try to resolve a specific version of the DID document. The resolution process is the same except that the *AnchorCommit* we use to get the content of the document should be equal to the DocID + CID from `versionId`. In addition we should construct the *DID Document Metadata* differently. +The certification of a `DataEvent` can be validated using the following algorithm, -##### DID Document Metadata +1. The varsig validates agains the *aud* `Principal` of the referenced CACAO -* `create` - should be populated using the blockchain timestamp from the first *AnchorCommit* -* `updated` - should be populated using the blockchain timestamp from the resolved *AnchorCommit* -* `versionId` - should be equal to the commit CID from the resolved *AnchorCommit* -* `nextUpdate` - should be populated using the blockchain timestamp from the next *AnchorCommit* (if present) -* `nextVersionId` - should be equal to the commit CID from the next *AnchorCommit* (if present) +2. The multihash of the CACAO CID (caphash) is one of: -### Update + 1. CapHash is in the `Registry` and `isRevoked` is false + 2. CapHash is in the `Principal` and **not** in the `Registry` -The 3ID DID can be updated by changing the content of the Ceramic stream corresponding to the particular 3ID. Any number of public key can be added or removed from the content. Note that the *controller* of the Ceramic stream can be changed as well. This does not have any effect on the state of the DID document, but changes the DID which is in control of the 3ID document. +3. The CACAO *ability* is one or both of: -### Deactivate + 1. `"3id/add"` - the `Registry` is only allowed to grow and, new values must have `isRevoked = false` +2. `"3id/remove"` - the `Registry` can either grow or stay the same size, all modified values must have `isRevoked = true` -The 3ID can be deactivated by removing all content in the Ceramic stream of the 3ID and replacing it with one property `deactivated` set to `true`. +#### Consensus -## Security Requirements +In case of two conflicting events (two events share the same `prv` value) the event with the earliest `TimestampEvent` should be processed first. Note that this might lead to the latter event being invalid due to its delegation chain being revoked. Also, a new event emitted after the conflict must reference both branches in its `prv` and resolve any conflict of the `Registry`. -3ID derives most of its security properties from the Ceramic protocol. Most notably *censorship resistance*, *decentralization*, and requiring a minimal amount of data to be synced to completely verify the integrity of a 3ID. For more details see the Ceramic [specification](https://github.com/ceramicnetwork/ceramic/blob/master/SPECIFICATION.md). +If there is no anchor for either event yet, the `DataEvent` with the lowest binary value of its CID will win. Note that if a `TimeEvent` appears this order might change. -### Cryptographic Agility +#### Verified timestamps -As can be seen in the CRUD section, currently only `secp256k1` and `x25519` public keys are supported. This can be easily extended by using other multicodec encoded keys. The [multicodec table](https://github.com/multiformats/multicodec/blob/master/table.csv) already has support for BLS keys for example, so adding support for it would be trivial. Once good post quantum cryptography becomes more widely available extending 3ID to support that will also be fairly straight forward. +For convenience, once a `TimeEvent` has been verified the data used to verify it can be stored as a receipt. This is helpful when resolving the registry at a particular point in time using the `?versionTime=` DID URL parameter. -## Privacy Requirements +```verilog +type EthereumHeader // -See [§ 10. Privacy Considerations](https://www.w3.org/TR/did-core/#privacy-considerations) in `did-core`. +type TimestampRecipt struct { + unixtime Integer // same as block.Time + event &TimestampEvent + block &EthereumHeader + path String // ipld path in the block to find event.txHash +} +``` -## Extensibility +#### Dereferencing the Registry - The 3ID DID Method could also easily be extended to support other features specified in [did-core](https://w3c.github.io/did-core/), e.g. service endpoints. +The 3 DID resolver can [dereference](https://wiki.trustoverip.org/display/HOME/DID+URL+Resource+Parameter+Specification) the registry to a [CAR file](https://ipld.io/specs/transport/car/carv1/) which can be independently verified. This is achieved by using the `did:3:?resource=vnd.ipld.car` DID URL. Note that the `versionTime` may be used to resolve an earlier snapshot of the registry. -## Reference Implementations +### Object Capabilities -* [3id-did-provider](https://github.com/ceramicstudio/js-3id-did-provider) - wallet side implementation of the 3ID DID method -* [3id-did-resolver](https://github.com/ceramicnetwork/js-ceramic/tree/develop/packages/3id-did-resolver) - 3ID DID method resolver +The 3 DID method relies heavily on object-capabilities as they way to add and remove verification methods, as well as delegating permissions. The root capability is `did/control`, any verification method with this capability has [independent control](https://www.w3.org/TR/did-core/#independent-control) over the DID. This means that they can take any action on behalf of this DID, `*/*` is thus a equivalent of `did/control`. The `did/vm-add` and `did/vm-remove` are actions that can be taken to update the 3ID stream and thus the DID document. In the future other more specific `did/...` capabilities my be specified to define more granular actions on the DID document. -## Appendix A +``` + ┌─────────────┐ + │ did/control │ + └──▲───▲───▲──┘ + ┌────────────┘ │ └────────┐ +┌─────┴──────┐ ┌───────┴───────┐ ┌──┴──┐ +│ did/vm-add │ │ did/vm-remove │ │ */* │ +└────────────┘ └───────────────┘ └─────┘ +``` -An example 3IDv0 genesis object +#### Updating the 3ID stream +In order to make an update to the 3ID stream, one of the verification methods could delegate the following permission to a session key: ```json { - "value": { - "id": "did:3:GENESIS", - "@context": "https://w3id.org/did/v1", - "publicKey": [ - { - "id": "did:3:GENESIS#signingKey", - "type": "Secp256k1VerificationKey2018", - "publicKeyHex": "0452fbcde75f7ddd7cff18767e2b5536211f500ad474c15da8e74577a573e7a346f2192ef49a5aa0552c41f181a7950af3afdb93cafcbff18156943e3ba312e5b2" - }, - { - "id": "did:3:GENESIS#encryptionKey", - "type": "Curve25519EncryptionPublicKey", - "publicKeyBase64": "DFxR24MNHVxEDAdL2f6pPEwNDJ2p0Ldyjoo7y/ItLDc=" - }, - { - "id": "did:3:GENESIS#managementKey", - "type": "Secp256k1VerificationKey2018", - "ethereumAddress": "0x3f0bb6247d647a30f310025662b29e6fa382b61d" + "att":{ + "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj": { + "did/vm-add": [], + "did/vm-remove": [] } - ], - "authentication": [ - { - "type": "Secp256k1SignatureAuthentication2018", - "publicKey": "did:3:GENESIS#signingKey" + // CID of the event to append to the 3ID stream + }, + "prf": [ + { "/": "bafybeigk7ly3pog6uupxku3b6bubirr434ib6tfaymvox6gotaaaaaaaaa" } + // The CID of the capability that grants the key control over the 3ID + // From this the 3ID can be found, resolve revreg to see if self cap is revoked + ] +} +``` + +#### Using a 3ID in Ceramic + +In order to act on behalf of a 3ID that controls a Ceramic stream, a delegation can be created by one of the verification methods in the 3ID. Note that the `prf` field must contain a link to the capability for the verification method. + +```json +{ + "tar":{ + "ceramic://*?model=zkfif...": { + "crud/mutate": [], + "crud/read": [] } - ] - } + }, + "prf": [ + { "/": "bafybeigk7ly3pog6uupxku3b6bubirr434ib6tfaymvox6gotaaaaaaaaa" } + // The CID of the capability that grants the key control over the 3ID + ] } ``` +## Rationale + + + +While most DID methods include full public keys, or other DIDs as verification methods 3ID chooses to use hashes of object-capabilities as verification methods. One of the main use cases for 3ID is to connect multiple PKH DIDs into a single identifier on Ceramic. While doing so publically is fine for some use cases, the ability to do so privately is quite important for many. Using *capability hashes* enables more privacy since the DIDs that are delegated to doesn't strictly need to be revealed. It is worth noting that revealing the CACAO object when used is the simplest way to prove a capability chain. However, it is possible to create zero-knowledge proofs that only reveal the hash of the capability used and which session key was delegated to. + +### Cryptographic Agility + +The 3 DID method itself doesn't really limit what cryptography can be used. It boils down to what the system that interprets the actual object capabilities is capable of. In Ceramic this includes the following, but is not limited to, and can be extended in the future: + +* `ed25519` +* `secp256k1` +* `secp256r1` + +Once good post quantum cryptography becomes more widely available extending Ceramic to support that will also be fairly straight forward. + + +## Backwards Compatibility + + +Previous iterations of 3ID relied on the TileDocument stream type and an interpretation layer above that translated the tile contents to a DID document. That approach had numerious flaws the main one being the impossibility of privacy. This version of the spec deviates from the previous experiment in that there is a special stream type for the 3ID and that it fully relies on object-capabilities as verification methods. This is a great improvement but unfortunately it is not possible to make an upgrade in a backwards compatible manner. Instead all implementers are recommended to follow this specification only. + +## Privacy Requirements + +The 3 DID method provides a unique privacy enhancement over most other DID methods in that subject only need to reveal hashes of object-capabilities in order to use it. While the simplest way of implementing usage of the system would imply pulicly revealing these object-capabilities, it is indeed possible to create zero-knowledge proofs of the valididty of an object-capability without revealing its content. + +## Security Considerations + +3ID derives most of its security properties from the Ceramic protocol. Most notably *censorship resistance*, *decentralization*, and requiring a minimal amount of data to be synced to completely verify the integrity of a 3ID. For more details see the Ceramic [specification](https://github.com/ceramicnetwork/ceramic/blob/master/SPECIFICATION.md). + +## Reference Implementations + +Currently no reference implementation for 3ID exists. + +## Appendix A: Registrations + +This appendix contains all regsitrations necessary for the 3 DID method. + +### Verification method property + +**Property name:** `multihash` + +The multihash property is used to specify a multibase-encoded multihash. Usually this is a hash over an object-capability. + +* [Multihash specification](https://github.com/multiformats/multihash) +* [Multibase specification](https://github.com/multiformats/multibase) + +### Verification Method Type + +**Type name:** `capabilityHash` + +The capabilityHash verification method type indicates that the verification method is the hash of a CACAO. For a signature to be valid under a specific capabilityHash verification method, the proof must show that there is a valid delegation chain from the CACAO that corresponds with the given hash. In the most trivial case this can be achived by revealing the CACAO itself as part of the proof, a verifier can then check the hashed value of the CACAO. However, zero-knowledge proofs may be used to remove the need to reveal the CACAO, improving privacy for the DID subject. + +* [CAIP-74: CACAO - Chain Agnostic CApability Object](https://chainagnostic.org/CAIPs/caip-74) + +### Stream type code + +**Code:** `5` + +### Multidid code + +**Code:** `0x1b` - keccak-256 ## Copyright From a836464422def7929597162ce6427027064b4f3e Mon Sep 17 00:00:00 2001 From: Joel Thorstensson Date: Tue, 31 Jan 2023 14:42:37 -0600 Subject: [PATCH 2/9] Move to separate CIP --- CIPs/CIP-122.md | 454 +++++++++++++++++++++++++++++++++++++++++ CIPs/cip-79.md | 529 ++++++++++++++++-------------------------------- README.md | 1 + 3 files changed, 635 insertions(+), 349 deletions(-) create mode 100644 CIPs/CIP-122.md diff --git a/CIPs/CIP-122.md b/CIPs/CIP-122.md new file mode 100644 index 0000000..4341838 --- /dev/null +++ b/CIPs/CIP-122.md @@ -0,0 +1,454 @@ +--- +cip: 122 +title: 3 DID Method +author: Joel Thorstensson (@oed) +discussions-to: https://forum.ceramic.network/t/cip-122-3-did-method +status: Draft +category: Standards +type: Core +created: 2021-02-12 +updated: 2023-01-31 +replaces: 79 +--- + +## Simple Summary + + +The 3 DID method enables users to compose multiple accounts into a single identifier. + + +## Abstract + + +With a special type of Ceramic stream 3ID enables a revocation registry that can be used to add and remove verification methods from the 3 DID method as well as revoke any capability issued by the identifier. The revocation registry is based on hashes of object-capabilities encoded as CACAO. + + +## Motivation + + +Currently in Ceramic the main accounts types are PKH DID. These are great because they enable existing wallets to be used directly with Ceramic. However, these accounts are inherently tied to a specific account and there is no way to rotate keys in a simple manner. The 3 DID method changes this by defining a DID method which works with object-capabilities and supports all DID CRUD operations. + +Furthermore, the revocation regsitry of the 3 DID method enables the DID subject to revoke any object-capability issued by the 3ID. This can be useful in case of a key compromise, e.g. for a temporary session key. + +## Specification + + +Specification goes here. + +### The did:3 identifier + +> ``` +> did:3: +> ``` + +The `` value is a `keccak-256` multihash over the CID of a CACAO object-capability, e.g. ReCap or UCAN. The value MUST be encoded as a multibase string, using `base58btc`. + +***Simple example:*** + +> ``` +> did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj +> ``` + +### CRUD Operation Definitions + +3IDs are created, updated, and deactivated by creating, notarizing, and revoking object-capabilities in the form of CACAOs. + +#### Create + +Create and sign a [SIWx](https://chainagnostic.org/CAIPs/caip-122) message where: + +- `address` - a blockchain address (e.g. `0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2`) +- `uri` - the PKH DID for the same address (e.g. `did:pkh:eip155:1:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2`) + +And resources contains the following ReCap object: + +```java +{ + "att": { + "did:3:new": { "3id/control": [] } + } +} +``` + +- *When signing this would look something like this for the user:* + + ``` + example.com wants you to sign in with your Ethereum account: + 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 + + I further authorize https://example.com to perform the following + actions on my behalf: (1) "3id/control" for "did:3:new". + + URI: did:pkh:eip155:1:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 + Version: 1 + Chain ID: 1 + Nonce: n-0S6_WzA2Mj + Issued At: 2022-06-21T12:00:00.000Z + Resources: + - urn:recap:example:eyJkZWYiOlsicmVhZCJdLCJ0YXIiOnsibXkucmVzb3VyY2UuMSI6WyJhcHBlbmQiLCJkZWxldGUiXSwibXkucmVzb3VyY2UuMiI6WyJhcHBlbmQiXSwibXkucmVzb3VyY2UuMyI6WyJhcHBlbmQiXX19 + ``` + +##### Create the DID + +```jsx +cacaoCID = ipld.put(CACAO(SIWx-message, signature)) +did = 'did:3:' + multihash(cacaoCID) +``` + +#### Read + +To read you must load a deterministic Ceramic stream to find any updates made to the 3ID. + +1. Load the revocation registry Ceramic stream + + 1. If the `?versionTime=` is specified load only the events `≤ timestamp` + +2. Read all entries where `isRevoked = false` + +3. For every CACAO multihash in the registry, as well as the 3ID identifier, + + 1. Add the following object to the `verificationMethod` property of the DID document, + + ```json + { + "id": "#", + "type": "capabilityHash", + "controller": "did:3:", + "multihash": "" + } + ``` + + 2. Add `"#"` to the following fields, + + 1. `authentication` + 2. `assertionMethod` + 3. `capabilityDelegation` + 4. `capabilityInvocation` + +##### Example DID Document + +For `did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj` with no entires in the Revocation registry, + +```json +{ + "@context": [ + "", + ] + "id": "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", + "verificationMethod": [{ + "id": "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", + "type": "capabilityHash", + "controller": "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", + "multihash": "z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" + }], + "authentication": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], + "assertionMethod": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], + "capabilityDelegation": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], + "capabilityInvocation": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], +} +``` + +#### Update + +##### To add a verification method: + +1. Create a new ReCap capability with an existing VM as the issuer, delegating `"3id/control"` to another DID (PKH or Key DID), and encode it as a CACAO. + + ***ReCap*** + + ```json + { + "att": { + "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj": { "3id/control": [] } + } + } + ``` + + - *When signing this would look something like this for the user:* + + ``` + example.com wants you to sign in with your Ethereum account: + 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 + + I further authorize https://example.com to perform the following + actions on my behalf: (1) "3id/control" for "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj". + + URI: did:pkh:eip155:1:0xa05bba39b223fe8d0a0e5c4f27ead9083cb22ee3 + Version: 1 + Chain ID: 1 + Nonce: n-0S6_WzA2Mj + Issued At: 2022-06-21T12:00:00.000Z + Resources: + - urn:recap:example:eyJkZWYiOlsicmVhZCJdLCJ0YXIiOnsibXkucmVzb3VyY2UuMSI6WyJhcHBlbmQiLCJkZWxldGUiXSwibXkucmVzb3VyY2UuMiI6WyJhcHBlbmQiXSwibXkucmVzb3VyY2UuMyI6WyJhcHBlbmQiXX19 + ``` + +2. Load the *Revocation Registry* stream + +3. Update (2) by adding the `cacao-mh` from (1) + +***To remove a verification method:*** + +1. Load the *Revocation Registry* stream +2. Update (1) by removing the `cacao-mh` that is being revoked + +#### Deactivate + +In order to deactivate a 3ID all capabilities will need to be revoked. + +### Revocation Registry + +3ID is based on a self-certifying revocation registry represented as a special type of Ceramic stream. In it any verification method belonging to the 3ID can be registered and revoked. Every update to the registry is recorded as a *Data Event*. When a new event is created is needs to include a valid delegation chain back to previous version of the registry. + +```verilog +type Prinicipal Bytes // multidid +type CACAOHash Bytes // multihash +type Varsig Bytes // varsig + +type RevocationEntry struct { + key CACAOHash + isRevoked Boolean +} representation tuple +// The registry should eventually be a HAMT or similar data structure +type Regsitry { CACAOHash : RevocationEntry } +type Snapshot struct { + registry &Regsitry + actions [RevocationEntry] +} +``` + +#### Ceramic Stream + +```verilog +type Event InitEvent | DataEvent | TimeEvent + +type InitEvent &Prinicipal // an inline CID containing raw principal bytes + +type DataEvent struct { + id &InitEvent + prv [&Event] // is prv needed if it's the first event after genesis? + prf [&CACAO] // capabilities used to emit this event + data &Snapshot + sig Varsig +} + +type EthereumTx // + +type BlockchainTimestamp struct { + root Link + chainID String + txType String + txHash &EthereumTx +} + +type TimeEvent struct { + id &InitEvent + prv [&DataEvent] // should always be one CID + proof &BlockchainTimestamp + path String +} +``` + +#### Streamid + +Generating the Ceramic streamid can be done in three steps, + +1. Generate the multidid representation of the 3ID, + + ```solidity + := + ``` + +2. Encode the multidid as an inline CID, + + ```solidity + := + ``` + +3. Encode the Streamid + + ```solidity + := + ``` + +#### Create a `DataEvent` + +New data events + +1. Attain a key with a valid capability chain to the most recent *previous data event(s)* + +2. Create one or more `RevocationEntry` objects and update the `State` from the + + previous data event(s): + + 1. Write the objects to a new array and store them on the `actions` field + 2. Also append them to the `registry` map + +3. Create the `DataEvent` struct, + + 1. Set `id` to the principal (an inline CID containing a multidid encoded 3ID), + 2. Add the capability chain used to the `prf` field + 3. Add the previous events to the `prv` field + 4. Add the updated state to the `data` field + 5. Create a `Varsig` over the `DataEvent` with the key from (1) and add the `sig` field + +#### Validating a `DataEvent` + +The certification of a `DataEvent` can be validated using the following algorithm, + +1. The varsig validates agains the *aud* `Principal` of the referenced CACAO + +2. The multihash of the CACAO CID (caphash) is one of: + + 1. CapHash is in the `Registry` and `isRevoked` is false + 2. CapHash is in the `Principal` and **not** in the `Registry` + +3. The CACAO *ability* is one or both of: + + 1. `"3id/add"` - the `Registry` is only allowed to grow and, new values must have `isRevoked = false` +2. `"3id/remove"` - the `Registry` can either grow or stay the same size, all modified values must have `isRevoked = true` + +#### Consensus + +In case of two conflicting events (two events share the same `prv` value) the event with the earliest `TimestampEvent` should be processed first. Note that this might lead to the latter event being invalid due to its delegation chain being revoked. Also, a new event emitted after the conflict must reference both branches in its `prv` and resolve any conflict of the `Registry`. + +If there is no anchor for either event yet, the `DataEvent` with the lowest binary value of its CID will win. Note that if a `TimeEvent` appears this order might change. + +#### Verified timestamps + +For convenience, once a `TimeEvent` has been verified the data used to verify it can be stored as a receipt. This is helpful when resolving the registry at a particular point in time using the `?versionTime=` DID URL parameter. + +```verilog +type EthereumHeader // + +type TimestampRecipt struct { + unixtime Integer // same as block.Time + event &TimestampEvent + block &EthereumHeader + path String // ipld path in the block to find event.txHash +} +``` + +#### Dereferencing the Registry + +The 3 DID resolver can [dereference](https://wiki.trustoverip.org/display/HOME/DID+URL+Resource+Parameter+Specification) the registry to a [CAR file](https://ipld.io/specs/transport/car/carv1/) which can be independently verified. This is achieved by using the `did:3:?resource=vnd.ipld.car` DID URL. Note that the `versionTime` may be used to resolve an earlier snapshot of the registry. + +### Object Capabilities + +The 3 DID method relies heavily on object-capabilities as they way to add and remove verification methods, as well as delegating permissions. The root capability is `did/control`, any verification method with this capability has [independent control](https://www.w3.org/TR/did-core/#independent-control) over the DID. This means that they can take any action on behalf of this DID, `*/*` is thus a equivalent of `did/control`. The `did/vm-add` and `did/vm-remove` are actions that can be taken to update the 3ID stream and thus the DID document. In the future other more specific `did/...` capabilities my be specified to define more granular actions on the DID document. + +``` + ┌─────────────┐ + │ did/control │ + └──▲───▲───▲──┘ + ┌────────────┘ │ └────────┐ +┌─────┴──────┐ ┌───────┴───────┐ ┌──┴──┐ +│ did/vm-add │ │ did/vm-remove │ │ */* │ +└────────────┘ └───────────────┘ └─────┘ +``` + +#### Updating the 3ID stream + +In order to make an update to the 3ID stream, one of the verification methods could delegate the following permission to a session key: + +```json +{ + "att":{ + "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj": { + "did/vm-add": [], + "did/vm-remove": [] + } + // CID of the event to append to the 3ID stream + }, + "prf": [ + { "/": "bafybeigk7ly3pog6uupxku3b6bubirr434ib6tfaymvox6gotaaaaaaaaa" } + // The CID of the capability that grants the key control over the 3ID + // From this the 3ID can be found, resolve revreg to see if self cap is revoked + ] +} +``` + +#### Using a 3ID in Ceramic + +In order to act on behalf of a 3ID that controls a Ceramic stream, a delegation can be created by one of the verification methods in the 3ID. Note that the `prf` field must contain a link to the capability for the verification method. + +```json +{ + "tar":{ + "ceramic://*?model=zkfif...": { + "crud/mutate": [], + "crud/read": [] + } + }, + "prf": [ + { "/": "bafybeigk7ly3pog6uupxku3b6bubirr434ib6tfaymvox6gotaaaaaaaaa" } + // The CID of the capability that grants the key control over the 3ID + ] +} +``` + +## Rationale + + + +While most DID methods include full public keys, or other DIDs as verification methods 3ID chooses to use hashes of object-capabilities as verification methods. One of the main use cases for 3ID is to connect multiple PKH DIDs into a single identifier on Ceramic. While doing so publically is fine for some use cases, the ability to do so privately is quite important for many. Using *capability hashes* enables more privacy since the DIDs that are delegated to doesn't strictly need to be revealed. It is worth noting that revealing the CACAO object when used is the simplest way to prove a capability chain. However, it is possible to create zero-knowledge proofs that only reveal the hash of the capability used and which session key was delegated to. + +### Cryptographic Agility + +The 3 DID method itself doesn't really limit what cryptography can be used. It boils down to what the system that interprets the actual object capabilities is capable of. In Ceramic this includes the following, but is not limited to, and can be extended in the future: + +* `ed25519` +* `secp256k1` +* `secp256r1` + +Once good post quantum cryptography becomes more widely available extending Ceramic to support that will also be fairly straight forward. + + +## Backwards Compatibility + + +Previous iterations of 3ID relied on the TileDocument stream type and an interpretation layer above that translated the tile contents to a DID document. That approach had numerious flaws the main one being the impossibility of privacy. This version of the spec deviates from the previous experiment in that there is a special stream type for the 3ID and that it fully relies on object-capabilities as verification methods. This is a great improvement but unfortunately it is not possible to make an upgrade in a backwards compatible manner. Instead all implementers are recommended to follow this specification only. + +## Privacy Requirements + +The 3 DID method provides a unique privacy enhancement over most other DID methods in that subject only need to reveal hashes of object-capabilities in order to use it. While the simplest way of implementing usage of the system would imply pulicly revealing these object-capabilities, it is indeed possible to create zero-knowledge proofs of the valididty of an object-capability without revealing its content. + +## Security Considerations + +3ID derives most of its security properties from the Ceramic protocol. Most notably *censorship resistance*, *decentralization*, and requiring a minimal amount of data to be synced to completely verify the integrity of a 3ID. For more details see the Ceramic [specification](https://github.com/ceramicnetwork/ceramic/blob/master/SPECIFICATION.md). + +## Reference Implementations + +Currently no reference implementation for 3ID exists. + +## Appendix A: Registrations + +This appendix contains all regsitrations necessary for the 3 DID method. + +### Verification method property + +**Property name:** `multihash` + +The multihash property is used to specify a multibase-encoded multihash. Usually this is a hash over an object-capability. + +* [Multihash specification](https://github.com/multiformats/multihash) +* [Multibase specification](https://github.com/multiformats/multibase) + +### Verification Method Type + +**Type name:** `capabilityHash` + +The capabilityHash verification method type indicates that the verification method is the hash of a CACAO. For a signature to be valid under a specific capabilityHash verification method, the proof must show that there is a valid delegation chain from the CACAO that corresponds with the given hash. In the most trivial case this can be achived by revealing the CACAO itself as part of the proof, a verifier can then check the hashed value of the CACAO. However, zero-knowledge proofs may be used to remove the need to reveal the CACAO, improving privacy for the DID subject. + +* [CAIP-74: CACAO - Chain Agnostic CApability Object](https://chainagnostic.org/CAIPs/caip-74) + +### Stream type code + +**Code:** `5` + +### Multidid code + +**Code:** `0x1b` - keccak-256 + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/CIPs/cip-79.md b/CIPs/cip-79.md index 7bbb021..4fcda28 100644 --- a/CIPs/cip-79.md +++ b/CIPs/cip-79.md @@ -1,452 +1,283 @@ --- cip: 79 -title: 3 DID Method Specification +title: 3ID DID Method Specification author: Joel Thorstensson (@oed) discussions-to: https://github.com/ceramicnetwork/CIP/issues/80 -status: Draft +status: Superseded category: Standards -type: Core +type: RFC created: 2021-02-12 -updated: 2023-01-13 +updated: 2023-01-31 +Superseded By: 122 --- -## Simple Summary +# 3ID DID Method Specification - -The 3 DID method enables users to compose multiple accounts into a signle identifier. +3ID is a DID method that is implemented natively on Ceramic. It uses the Tile Document StreamType to create a mutable stream that stores the information which makes up the DID document for the 3ID. The Tile Document StreamType supports secure key rotation for 3IDs since its updates must be anchored into a blockchain, providing explicit versions and *proof-of-publication* at specific points in time (blockheights). This means that 3ID inherits this property. +## DID Method Name -## Abstract +The name string that shall identify this DID method is: `3`. - -With a special type of Ceramic stream 3ID enables a revocation registry that can be used to add and remove verification methods from the 3 DID method as well as revoke any capability issued by the identifier. The revocation registry is based on hashes of object-capabilities encoded as CACAO. +A DID that uses this method MUST begin with the following prefix: `did:3`. Per the [DID specification](https://w3c.github.io/did-core/), this string MUST be in lowercase. The remainder of the DID, after the prefix, is specified below. +## Method Specific Identifier -## Motivation +There are two versions of 3IDs. Both versions use a Ceramic Tile Document StreamType as a way to update the DID document. 3IDv1 is the most recent version, however 3IDv0 is supported for legacy reasons. If you are creating new 3IDs you should always use 3IDv1. Both versions are always encoded using multibase. To determine if it's v1 or v0, first convert the multibase string into a byte array. If the first varint is `0x01` it's a 3IDv0, and if the first varint is `0xce` it's a 3IDv1. - -Currently in Ceramic the main accounts types are PKH DID. These are great because they enable existing wallets to be used directly with Ceramic. However, these accounts are inherently tied to a specific account and there is no way to rotate keys in a simple manner. The 3 DID method changes this by defining a DID method which works with object-capabilities and supports all DID CRUD operations. +### 3IDv1 -Furthermore, the revocation regsitry of the 3 DID method enables the DID subject to revoke any object-capability issued by the 3ID. This can be useful in case of a key compromise, e.g. for a temporary session key. +The method specific identifier for 3IDv1 is simply a Ceramic StreamID. The StreamID used refers to the Ceramic stream which contains the information needed to construct the DID Document upon resolution. StreamIDs are encoded according to [CIP-59](https://github.com/ceramicnetwork/CIP/blob/master/CIPs/CIP-59/CIP-59.md). -## Specification - - -Specification goes here. - -### The did:3 identifier - -> ``` -> did:3: -> ``` - -The `` value is a `keccak-256` multihash over the CID of a CACAO object-capability, e.g. ReCap or UCAN. The value MUST be encoded as a multibase string, using `base58btc`. - -***Simple example:*** - -> ``` -> did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj -> ``` - -### CRUD Operation Definitions - -3IDs are created, updated, and deactivated by creating, notarizing, and revoking object-capabilities in the form of CACAOs. - -#### Create - -Create and sign a [SIWx](https://chainagnostic.org/CAIPs/caip-122) message where: - -- `address` - a blockchain address (e.g. `0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2`) -- `uri` - the PKH DID for the same address (e.g. `did:pkh:eip155:1:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2`) - -And resources contains the following ReCap object: - -```java -{ - "att": { - "did:3:new": { "3id/control": [] } - } -} ``` - -- *When signing this would look something like this for the user:* - - ``` - example.com wants you to sign in with your Ethereum account: - 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 - - I further authorize https://example.com to perform the following - actions on my behalf: (1) "3id/control" for "did:3:new". - - URI: did:pkh:eip155:1:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 - Version: 1 - Chain ID: 1 - Nonce: n-0S6_WzA2Mj - Issued At: 2022-06-21T12:00:00.000Z - Resources: - - urn:recap:example:eyJkZWYiOlsicmVhZCJdLCJ0YXIiOnsibXkucmVzb3VyY2UuMSI6WyJhcHBlbmQiLCJkZWxldGUiXSwibXkucmVzb3VyY2UuMiI6WyJhcHBlbmQiXSwibXkucmVzb3VyY2UuMyI6WyJhcHBlbmQiXX19 - ``` - -##### Create the DID - -```jsx -cacaoCID = ipld.put(CACAO(SIWx-message, signature)) -did = 'did:3:' + multihash(cacaoCID) +3idv1 = "did:3:" ``` -#### Read +#### Example -To read you must load a deterministic Ceramic stream to find any updates made to the 3ID. +```sh +did:3:kjzl6cwe1jw149tlplc4bgnpn1v4uwk9rg9jkvijx0u0zmfa97t69dnqibqa2as +``` -1. Load the revocation registry Ceramic stream +### 3IDv0 - 1. If the `?versionTime=` is specified load only the events `≤ timestamp` +The method specific identifier for 3IDv0 is a [CID](https://github.com/multiformats/cid) as produced by the [IPLD](https://github.com/ipld/specs) codec [dag-cbor](https://github.com/ipld/specs/blob/master/block-layer/codecs/dag-cbor.md). -2. Read all entries where `isRevoked = false` +``` +3idv0 = "did:3:" +``` -3. For every CACAO multihash in the registry, as well as the 3ID identifier, +#### Example - 1. Add the following object to the `verificationMethod` property of the DID document, - - ```json - { - "id": "#", - "type": "capabilityHash", - "controller": "did:3:", - "multihash": "" - } - ``` - - 2. Add `"#"` to the following fields, - - 1. `authentication` - 2. `assertionMethod` - 3. `capabilityDelegation` - 4. `capabilityInvocation` +```sh +did:3:bafyreiffkeeq4wq2htejqla2is5ognligi4lvjhwrpqpl2kazjdoecmugi +``` -##### Example DID Document +## CRUD Operation Definitions -For `did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj` with no entires in the Revocation registry, +In this section the CRUD operations for a 3ID DID are defined. -```json -{ - "@context": [ - "", - ] - "id": "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", - "verificationMethod": [{ - "id": "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", - "type": "capabilityHash", - "controller": "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", - "multihash": "z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" - }], - "authentication": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], - "assertionMethod": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], - "capabilityDelegation": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], - "capabilityInvocation": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], -} -``` +### Create -#### Update +A `3` DID is created by simply creating a stream that conforms to the [`tile document`](https://github.com/ceramicnetwork/CIP/blob/master/CIPs/CIP-8/CIP-8.md) StreamType. The [`tile document`](https://github.com/ceramicnetwork/CIP/blob/master/CIPs/CIP-8/CIP-8.md) takes a DID as the *controller*, and it's recommended that a `did:key` is used. The *controller* is the DID which is allowed to update the stream. The *family* of the stream is set to `3id`, and the *deterministic* flag is set to `true`. -##### To add a verification method: +Now the content of the stream should consist of a JSON object with one property *publicKeys*. These public keys will be allowed to sign messages on behalf of the 3ID, or decrypt messages encrypted to the 3ID. The value of this property should be an object where the value is a [multicodec](https://github.com/multiformats/multicodec/) + multibase(*base58btc*) encoded public key, the key for any given key should be the last *15* characters of the encoded public key. -1. Create a new ReCap capability with an existing VM as the issuer, delegating `"3id/control"` to another DID (PKH or Key DID), and encode it as a CACAO. +The 3ID DID method supports any type of public key that can be encoded using multicodec which can easily be extended to support quantum resistant signature and encryption schemes in the future. - ***ReCap*** +#### Example - ```json - { - "att": { - "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj": { "3id/control": [] } - } - } - ``` +Below you can see an example of how to create a 3ID using the Ceramic javascript api. - - *When signing this would look something like this for the user:* +```js +const doc = await ceramic.createDocument({ + metadata: { + controllers: ['did:key:zQ3shQNcackrTByiYaPGso1Nt7b6r1gSMg4XXBmavzvTMqX1h'], // secp256k1 did:key + family: '3id' + }, + content: { + publicKeys: { + "XQCT2xJHsdY6iJH": "z6LSqKWh3XQ7AfsJuE2KR23cozEut8D5CXQCT2xJHsdY6iJH", // x22519 public key + "yh27jTt7Ny2Pwdy": "zQ3shrMGEKAjUTMmvDkcZ7Y3x9XnVjTH3myh27jTt7Ny2Pwdy", // secp256k1 public key + } + }, + deterministic: true +}) - ``` - example.com wants you to sign in with your Ethereum account: - 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 - - I further authorize https://example.com to perform the following - actions on my behalf: (1) "3id/control" for "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj". - - URI: did:pkh:eip155:1:0xa05bba39b223fe8d0a0e5c4f27ead9083cb22ee3 - Version: 1 - Chain ID: 1 - Nonce: n-0S6_WzA2Mj - Issued At: 2022-06-21T12:00:00.000Z - Resources: - - urn:recap:example:eyJkZWYiOlsicmVhZCJdLCJ0YXIiOnsibXkucmVzb3VyY2UuMSI6WyJhcHBlbmQiLCJkZWxldGUiXSwibXkucmVzb3VyY2UuMiI6WyJhcHBlbmQiXSwibXkucmVzb3VyY2UuMyI6WyJhcHBlbmQiXX19 - ``` +const didString = `did:3:${doc.id}` +``` -2. Load the *Revocation Registry* stream +### Read/Verify -3. Update (2) by adding the `cacao-mh` from (1) +Resolving a 3ID is quite straight forward. It is done by taking the StreamID from the method specific identifier, looking up the referred stream using Ceramic, and converting the content of the stream into a DID document. -***To remove a verification method:*** +#### Loading 3IDv1 stream -1. Load the *Revocation Registry* stream -2. Update (1) by removing the `cacao-mh` that is being revoked +To load a 3IDv1 document simply take the StreamID from the method specific identifier and load the stream from ceramic. -#### Deactivate +#### Loading 3IDv0 document -In order to deactivate a 3ID all capabilities will need to be revoked. +To load a 3IDv0 document, first take the CID from the method specific identifier and load the corresponding object from the IPFS network. The resolved object will contain a `publicKey` property which has an array of public key objects (see [Appendix A](#appendix-a)). -### Revocation Registry +Now find the key with an id that ends in `#signingKey` and convert it to a multicodec encoded key (in compressed format), then use it as a `did:key` and look up the ceramic document which has this key as the *controller* and *family* set to `3id`, using the *deterministic* flag. Below you can see the code to do this with the javascript Ceramic api. -3ID is based on a self-certifying revocation registry represented as a special type of Ceramic stream. In it any verification method belonging to the 3ID can be registered and revoked. Every update to the registry is recorded as a *Data Event*. When a new event is created is needs to include a valid delegation chain back to previous version of the registry. -```verilog -type Prinicipal Bytes // multidid -type CACAOHash Bytes // multihash -type Varsig Bytes // varsig -type RevocationEntry struct { - key CACAOHash - isRevoked Boolean -} representation tuple -// The registry should eventually be a HAMT or similar data structure -type Regsitry { CACAOHash : RevocationEntry } -type Snapshot struct { - registry &Regsitry - actions [RevocationEntry] -} +```js +const doc = await ceramic.createDocument({ + metadata: { + controllers: [didKey], // secp256k1 did:key + family: '3id' + }, + deterministic: true +}) ``` -#### Ceramic Stream +#### Converting the loaded Ceramic stream to the DID document -```verilog -type Event InitEvent | DataEvent | TimeEvent +Once we have the stream loaded, load the latest *AnchorCommit* in the stream (the latest commit that was anchored to a blockchain). Then get the content of the stream at this `AnchorCommit`, which will look something like this: -type InitEvent &Prinicipal // an inline CID containing raw principal bytes - -type DataEvent struct { - id &InitEvent - prv [&Event] // is prv needed if it's the first event after genesis? - prf [&CACAO] // capabilities used to emit this event - data &Snapshot - sig Varsig +```json +{ + "publicKeys": { + "j9uh8iKHSDSLat4": "zQ3shaLgXkpEXt7He5mogBxFfib5cE2kv9j9uh8iKHSDSLat4", + "qYfZN2QNDgjJpaL": "z6LSnTyV1nSWfMmfV1PoRmo3enhDnfqfFqYfZN2QNDgjJpaL" + } } +``` -type EthereumTx // +To convert this into a DID document first create an empty DID document: -type BlockchainTimestamp struct { - root Link - chainID String - txType String - txHash &EthereumTx -} - -type TimeEvent struct { - id &InitEvent - prv [&DataEvent] // should always be one CID - proof &BlockchainTimestamp - path String +```json +{ + "@context": "https://w3id.org/did/v1", + "id": "", + "verificationMethod": [], + "authentication": [], + "keyAgreement": [] } ``` -#### Streamid +Now iterate though the entires in the `publicKeys` object in the Ceramic stream and do the following: -Generating the Ceramic streamid can be done in three steps, +* If it's a `secp256k1` key: -1. Generate the multidid representation of the 3ID, + * Add a `Secp256k1VerificationKey2018` to the *verificationMethod* array: - ```solidity - := - ``` + ```js + { + id: "#", + type: "EcdsaSecp256k1Signature2019", + controller: "", + publicKeyBase58: "" + } + ``` -2. Encode the multidid as an inline CID, + * Add a `Secp256k1SignatureAuthentication2018` to the *authentication* array: - ```solidity - := - ``` + ```js + { + id: "#", + type: "EcdsaSecp256k1Signature2019", + controller: "", + publicKeyBase58: "" + } + ``` -3. Encode the Streamid +* If it's a `x25519` key: - ```solidity - := - ``` + * Add a `Curve25519EncryptionPublicKey` to the *verificationMethod* array: -#### Create a `DataEvent` + ```js + { + id: "#", + type: "X25519KeyAgreementKey2019", + controller: "", + publicKeyBase58: "" + } + ``` -New data events + * Add a `X25519KeyAgreementKey2019` to the *keyAgreement* array: -1. Attain a key with a valid capability chain to the most recent *previous data event(s)* + ```js + { + id: "#", + type: "X25519KeyAgreementKey2019", + controller: "", + publicKeyBase58: "" + } + ``` -2. Create one or more `RevocationEntry` objects and update the `State` from the +##### 3IDv0 genesis - previous data event(s): +Since the content of the Ceramic document for a 3IDv0 is empty at the *GenesisCommit* we create the DID document by taking the public keys in the 3IDv0 genesis object (see [Appendix A](#appendix-a)) and convert them to multicodec public keys (one `secp256k1` and one `x25519`). The key properties in the DID document should be constructed as above, with the *entry-key* being the last *15* characters of the multicodec encoded keys. - 1. Write the objects to a new array and store them on the `actions` field - 2. Also append them to the `registry` map +##### DID Document Metadata -3. Create the `DataEvent` struct, +When resolving the DID document [DID Document Metadata](https://w3c.github.io/did-core/#did-document-metadata) should be provided. When resolving a 3ID we should populate the following fields: - 1. Set `id` to the principal (an inline CID containing a multidid encoded 3ID), - 2. Add the capability chain used to the `prf` field - 3. Add the previous events to the `prv` field - 4. Add the updated state to the `data` field - 5. Create a `Varsig` over the `DataEvent` with the key from (1) and add the `sig` field +* `create` - should be populated using the blockchain timestamp from the first *AnchorCommit* +* `updated` - should be populated using the blockchain timestamp from the most recent *AnchorCommit* +* `versionId` - should be equal to the commit CID from the most recent *AnchorCommit* -#### Validating a `DataEvent` +#### Resolving using the `versionId` parameter -The certification of a `DataEvent` can be validated using the following algorithm, +When the `versionId` query parameter is given as a DID is resolved it means that we should try to resolve a specific version of the DID document. The resolution process is the same except that the *AnchorCommit* we use to get the content of the document should be equal to the DocID + CID from `versionId`. In addition we should construct the *DID Document Metadata* differently. -1. The varsig validates agains the *aud* `Principal` of the referenced CACAO +##### DID Document Metadata -2. The multihash of the CACAO CID (caphash) is one of: +* `create` - should be populated using the blockchain timestamp from the first *AnchorCommit* +* `updated` - should be populated using the blockchain timestamp from the resolved *AnchorCommit* +* `versionId` - should be equal to the commit CID from the resolved *AnchorCommit* +* `nextUpdate` - should be populated using the blockchain timestamp from the next *AnchorCommit* (if present) +* `nextVersionId` - should be equal to the commit CID from the next *AnchorCommit* (if present) - 1. CapHash is in the `Registry` and `isRevoked` is false - 2. CapHash is in the `Principal` and **not** in the `Registry` +### Update -3. The CACAO *ability* is one or both of: +The 3ID DID can be updated by changing the content of the Ceramic stream corresponding to the particular 3ID. Any number of public key can be added or removed from the content. Note that the *controller* of the Ceramic stream can be changed as well. This does not have any effect on the state of the DID document, but changes the DID which is in control of the 3ID document. - 1. `"3id/add"` - the `Registry` is only allowed to grow and, new values must have `isRevoked = false` -2. `"3id/remove"` - the `Registry` can either grow or stay the same size, all modified values must have `isRevoked = true` +### Deactivate -#### Consensus +The 3ID can be deactivated by removing all content in the Ceramic stream of the 3ID and replacing it with one property `deactivated` set to `true`. -In case of two conflicting events (two events share the same `prv` value) the event with the earliest `TimestampEvent` should be processed first. Note that this might lead to the latter event being invalid due to its delegation chain being revoked. Also, a new event emitted after the conflict must reference both branches in its `prv` and resolve any conflict of the `Registry`. +## Security Requirements -If there is no anchor for either event yet, the `DataEvent` with the lowest binary value of its CID will win. Note that if a `TimeEvent` appears this order might change. +3ID derives most of its security properties from the Ceramic protocol. Most notably *censorship resistance*, *decentralization*, and requiring a minimal amount of data to be synced to completely verify the integrity of a 3ID. For more details see the Ceramic [specification](https://github.com/ceramicnetwork/ceramic/blob/master/SPECIFICATION.md). -#### Verified timestamps +### Cryptographic Agility -For convenience, once a `TimeEvent` has been verified the data used to verify it can be stored as a receipt. This is helpful when resolving the registry at a particular point in time using the `?versionTime=` DID URL parameter. +As can be seen in the CRUD section, currently only `secp256k1` and `x25519` public keys are supported. This can be easily extended by using other multicodec encoded keys. The [multicodec table](https://github.com/multiformats/multicodec/blob/master/table.csv) already has support for BLS keys for example, so adding support for it would be trivial. Once good post quantum cryptography becomes more widely available extending 3ID to support that will also be fairly straight forward. -```verilog -type EthereumHeader // +## Privacy Requirements -type TimestampRecipt struct { - unixtime Integer // same as block.Time - event &TimestampEvent - block &EthereumHeader - path String // ipld path in the block to find event.txHash -} -``` +See [§ 10. Privacy Considerations](https://www.w3.org/TR/did-core/#privacy-considerations) in `did-core`. -#### Dereferencing the Registry +## Extensibility -The 3 DID resolver can [dereference](https://wiki.trustoverip.org/display/HOME/DID+URL+Resource+Parameter+Specification) the registry to a [CAR file](https://ipld.io/specs/transport/car/carv1/) which can be independently verified. This is achieved by using the `did:3:?resource=vnd.ipld.car` DID URL. Note that the `versionTime` may be used to resolve an earlier snapshot of the registry. + The 3ID DID Method could also easily be extended to support other features specified in [did-core](https://w3c.github.io/did-core/), e.g. service endpoints. -### Object Capabilities +## Reference Implementations -The 3 DID method relies heavily on object-capabilities as they way to add and remove verification methods, as well as delegating permissions. The root capability is `did/control`, any verification method with this capability has [independent control](https://www.w3.org/TR/did-core/#independent-control) over the DID. This means that they can take any action on behalf of this DID, `*/*` is thus a equivalent of `did/control`. The `did/vm-add` and `did/vm-remove` are actions that can be taken to update the 3ID stream and thus the DID document. In the future other more specific `did/...` capabilities my be specified to define more granular actions on the DID document. +* [3id-did-provider](https://github.com/ceramicstudio/js-3id-did-provider) - wallet side implementation of the 3ID DID method +* [3id-did-resolver](https://github.com/ceramicnetwork/js-ceramic/tree/develop/packages/3id-did-resolver) - 3ID DID method resolver -``` - ┌─────────────┐ - │ did/control │ - └──▲───▲───▲──┘ - ┌────────────┘ │ └────────┐ -┌─────┴──────┐ ┌───────┴───────┐ ┌──┴──┐ -│ did/vm-add │ │ did/vm-remove │ │ */* │ -└────────────┘ └───────────────┘ └─────┘ -``` +## Appendix A -#### Updating the 3ID stream +An example 3IDv0 genesis object -In order to make an update to the 3ID stream, one of the verification methods could delegate the following permission to a session key: ```json { - "att":{ - "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj": { - "did/vm-add": [], - "did/vm-remove": [] + "value": { + "id": "did:3:GENESIS", + "@context": "https://w3id.org/did/v1", + "publicKey": [ + { + "id": "did:3:GENESIS#signingKey", + "type": "Secp256k1VerificationKey2018", + "publicKeyHex": "0452fbcde75f7ddd7cff18767e2b5536211f500ad474c15da8e74577a573e7a346f2192ef49a5aa0552c41f181a7950af3afdb93cafcbff18156943e3ba312e5b2" + }, + { + "id": "did:3:GENESIS#encryptionKey", + "type": "Curve25519EncryptionPublicKey", + "publicKeyBase64": "DFxR24MNHVxEDAdL2f6pPEwNDJ2p0Ldyjoo7y/ItLDc=" + }, + { + "id": "did:3:GENESIS#managementKey", + "type": "Secp256k1VerificationKey2018", + "ethereumAddress": "0x3f0bb6247d647a30f310025662b29e6fa382b61d" } - // CID of the event to append to the 3ID stream - }, - "prf": [ - { "/": "bafybeigk7ly3pog6uupxku3b6bubirr434ib6tfaymvox6gotaaaaaaaaa" } - // The CID of the capability that grants the key control over the 3ID - // From this the 3ID can be found, resolve revreg to see if self cap is revoked - ] -} -``` - -#### Using a 3ID in Ceramic - -In order to act on behalf of a 3ID that controls a Ceramic stream, a delegation can be created by one of the verification methods in the 3ID. Note that the `prf` field must contain a link to the capability for the verification method. - -```json -{ - "tar":{ - "ceramic://*?model=zkfif...": { - "crud/mutate": [], - "crud/read": [] + ], + "authentication": [ + { + "type": "Secp256k1SignatureAuthentication2018", + "publicKey": "did:3:GENESIS#signingKey" } - }, - "prf": [ - { "/": "bafybeigk7ly3pog6uupxku3b6bubirr434ib6tfaymvox6gotaaaaaaaaa" } - // The CID of the capability that grants the key control over the 3ID - ] + ] + } } ``` -## Rationale - - - -While most DID methods include full public keys, or other DIDs as verification methods 3ID chooses to use hashes of object-capabilities as verification methods. One of the main use cases for 3ID is to connect multiple PKH DIDs into a single identifier on Ceramic. While doing so publically is fine for some use cases, the ability to do so privately is quite important for many. Using *capability hashes* enables more privacy since the DIDs that are delegated to doesn't strictly need to be revealed. It is worth noting that revealing the CACAO object when used is the simplest way to prove a capability chain. However, it is possible to create zero-knowledge proofs that only reveal the hash of the capability used and which session key was delegated to. - -### Cryptographic Agility - -The 3 DID method itself doesn't really limit what cryptography can be used. It boils down to what the system that interprets the actual object capabilities is capable of. In Ceramic this includes the following, but is not limited to, and can be extended in the future: - -* `ed25519` -* `secp256k1` -* `secp256r1` - -Once good post quantum cryptography becomes more widely available extending Ceramic to support that will also be fairly straight forward. - - -## Backwards Compatibility - - -Previous iterations of 3ID relied on the TileDocument stream type and an interpretation layer above that translated the tile contents to a DID document. That approach had numerious flaws the main one being the impossibility of privacy. This version of the spec deviates from the previous experiment in that there is a special stream type for the 3ID and that it fully relies on object-capabilities as verification methods. This is a great improvement but unfortunately it is not possible to make an upgrade in a backwards compatible manner. Instead all implementers are recommended to follow this specification only. - -## Privacy Requirements - -The 3 DID method provides a unique privacy enhancement over most other DID methods in that subject only need to reveal hashes of object-capabilities in order to use it. While the simplest way of implementing usage of the system would imply pulicly revealing these object-capabilities, it is indeed possible to create zero-knowledge proofs of the valididty of an object-capability without revealing its content. - -## Security Considerations - -3ID derives most of its security properties from the Ceramic protocol. Most notably *censorship resistance*, *decentralization*, and requiring a minimal amount of data to be synced to completely verify the integrity of a 3ID. For more details see the Ceramic [specification](https://github.com/ceramicnetwork/ceramic/blob/master/SPECIFICATION.md). - -## Reference Implementations - -Currently no reference implementation for 3ID exists. - -## Appendix A: Registrations - -This appendix contains all regsitrations necessary for the 3 DID method. - -### Verification method property - -**Property name:** `multihash` - -The multihash property is used to specify a multibase-encoded multihash. Usually this is a hash over an object-capability. - -* [Multihash specification](https://github.com/multiformats/multihash) -* [Multibase specification](https://github.com/multiformats/multibase) - -### Verification Method Type - -**Type name:** `capabilityHash` - -The capabilityHash verification method type indicates that the verification method is the hash of a CACAO. For a signature to be valid under a specific capabilityHash verification method, the proof must show that there is a valid delegation chain from the CACAO that corresponds with the given hash. In the most trivial case this can be achived by revealing the CACAO itself as part of the proof, a verifier can then check the hashed value of the CACAO. However, zero-knowledge proofs may be used to remove the need to reveal the CACAO, improving privacy for the DID subject. - -* [CAIP-74: CACAO - Chain Agnostic CApability Object](https://chainagnostic.org/CAIPs/caip-74) - -### Stream type code - -**Code:** `5` - -### Multidid code - -**Code:** `0x1b` - keccak-256 ## Copyright diff --git a/README.md b/README.md index 6862587..536ee27 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ An editor will ask if anyone objects to it being finalized. If the editor decide - `Accepted (Core)`: an CIP of type Core that has been accepted by the core devs to be included in a future network upgrade. - `Final (Core)`: an CIP of type Core that has already been released in a network upgrade. - `Final (non-Core)`: a non-core CIP that has met all criteria and is finished. +- `Superseded`: has been superseded by a new CIP, should also include a `Superseded By` field pointing to the new CIP. # Editors - Michael Sena ([@michaelsena](http://github.com/michaelsena)) From 0d5378072f11fc4e77a9e0ad9e1c12681d372c12 Mon Sep 17 00:00:00 2001 From: Joel Thorstensson Date: Thu, 13 Apr 2023 15:39:07 +0200 Subject: [PATCH 3/9] edists --- CIPs/{CIP-122.md => CIP-1XX.md} | 251 ++++---------------------------- 1 file changed, 30 insertions(+), 221 deletions(-) rename CIPs/{CIP-122.md => CIP-1XX.md} (52%) diff --git a/CIPs/CIP-122.md b/CIPs/CIP-1XX.md similarity index 52% rename from CIPs/CIP-122.md rename to CIPs/CIP-1XX.md index 4341838..802f556 100644 --- a/CIPs/CIP-122.md +++ b/CIPs/CIP-1XX.md @@ -1,218 +1,58 @@ --- cip: 122 -title: 3 DID Method +title: CapReg - Notary for object-capabilities author: Joel Thorstensson (@oed) -discussions-to: https://forum.ceramic.network/t/cip-122-3-did-method +discussions-to: https://forum.ceramic.network/t/cip-1xx-capreg status: Draft category: Standards type: Core -created: 2021-02-12 -updated: 2023-01-31 -replaces: 79 +created: 2023-04-11 +updated: 2023-04-11 --- ## Simple Summary -The 3 DID method enables users to compose multiple accounts into a single identifier. +The CapReg capability registry enables users to notarize and revoke any object-apability associated with their DID. ## Abstract -With a special type of Ceramic stream 3ID enables a revocation registry that can be used to add and remove verification methods from the 3 DID method as well as revoke any capability issued by the identifier. The revocation registry is based on hashes of object-capabilities encoded as CACAO. +With a special type of Ceramic stream the capability registry enables users to notarize and revoke object-capabilities issued by their DID. The registry is based on hashes of object-capabilities encoded as CACAO. ## Motivation -Currently in Ceramic the main accounts types are PKH DID. These are great because they enable existing wallets to be used directly with Ceramic. However, these accounts are inherently tied to a specific account and there is no way to rotate keys in a simple manner. The 3 DID method changes this by defining a DID method which works with object-capabilities and supports all DID CRUD operations. -Furthermore, the revocation regsitry of the 3 DID method enables the DID subject to revoke any object-capability issued by the 3ID. This can be useful in case of a key compromise, e.g. for a temporary session key. +Currently in Ceramic the main accounts types are PKH DID. These are great because they enable existing wallets to be used directly with Ceramic. Once a PKH DID is used to delegate permissions to a session key. That delegation will remain valid until the capability expires. This could be a problem in the case of a stolen session key or a malicious application. By introducing a capability registry these capabilities can be revoked at any time by the main DID (PKH DID in the case above, but this would work for any DID method). A system that uses these object capabilities could refer to the registry to verify that the capability has not been revoked before it was used. ## Specification -Specification goes here. +This specification describes the data structure of the capability registry, its validation and consensus logic, as well as how wallet UX would look like for someone using the registry. -### The did:3 identifier -> ``` -> did:3: -> ``` +### Capability Registry -The `` value is a `keccak-256` multihash over the CID of a CACAO object-capability, e.g. ReCap or UCAN. The value MUST be encoded as a multibase string, using `base58btc`. - -***Simple example:*** - -> ``` -> did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj -> ``` - -### CRUD Operation Definitions - -3IDs are created, updated, and deactivated by creating, notarizing, and revoking object-capabilities in the form of CACAOs. - -#### Create - -Create and sign a [SIWx](https://chainagnostic.org/CAIPs/caip-122) message where: - -- `address` - a blockchain address (e.g. `0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2`) -- `uri` - the PKH DID for the same address (e.g. `did:pkh:eip155:1:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2`) - -And resources contains the following ReCap object: - -```java -{ - "att": { - "did:3:new": { "3id/control": [] } - } -} -``` - -- *When signing this would look something like this for the user:* - - ``` - example.com wants you to sign in with your Ethereum account: - 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 - - I further authorize https://example.com to perform the following - actions on my behalf: (1) "3id/control" for "did:3:new". - - URI: did:pkh:eip155:1:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 - Version: 1 - Chain ID: 1 - Nonce: n-0S6_WzA2Mj - Issued At: 2022-06-21T12:00:00.000Z - Resources: - - urn:recap:example:eyJkZWYiOlsicmVhZCJdLCJ0YXIiOnsibXkucmVzb3VyY2UuMSI6WyJhcHBlbmQiLCJkZWxldGUiXSwibXkucmVzb3VyY2UuMiI6WyJhcHBlbmQiXSwibXkucmVzb3VyY2UuMyI6WyJhcHBlbmQiXX19 - ``` - -##### Create the DID - -```jsx -cacaoCID = ipld.put(CACAO(SIWx-message, signature)) -did = 'did:3:' + multihash(cacaoCID) -``` - -#### Read - -To read you must load a deterministic Ceramic stream to find any updates made to the 3ID. - -1. Load the revocation registry Ceramic stream - - 1. If the `?versionTime=` is specified load only the events `≤ timestamp` - -2. Read all entries where `isRevoked = false` - -3. For every CACAO multihash in the registry, as well as the 3ID identifier, - - 1. Add the following object to the `verificationMethod` property of the DID document, - - ```json - { - "id": "#", - "type": "capabilityHash", - "controller": "did:3:", - "multihash": "" - } - ``` - - 2. Add `"#"` to the following fields, - - 1. `authentication` - 2. `assertionMethod` - 3. `capabilityDelegation` - 4. `capabilityInvocation` - -##### Example DID Document - -For `did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj` with no entires in the Revocation registry, - -```json -{ - "@context": [ - "", - ] - "id": "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", - "verificationMethod": [{ - "id": "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", - "type": "capabilityHash", - "controller": "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj", - "multihash": "z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" - }], - "authentication": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], - "assertionMethod": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], - "capabilityDelegation": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], - "capabilityInvocation": [ "#z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj" ], -} -``` - -#### Update - -##### To add a verification method: - -1. Create a new ReCap capability with an existing VM as the issuer, delegating `"3id/control"` to another DID (PKH or Key DID), and encode it as a CACAO. - - ***ReCap*** - - ```json - { - "att": { - "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj": { "3id/control": [] } - } - } - ``` - - - *When signing this would look something like this for the user:* - - ``` - example.com wants you to sign in with your Ethereum account: - 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 - - I further authorize https://example.com to perform the following - actions on my behalf: (1) "3id/control" for "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj". - - URI: did:pkh:eip155:1:0xa05bba39b223fe8d0a0e5c4f27ead9083cb22ee3 - Version: 1 - Chain ID: 1 - Nonce: n-0S6_WzA2Mj - Issued At: 2022-06-21T12:00:00.000Z - Resources: - - urn:recap:example:eyJkZWYiOlsicmVhZCJdLCJ0YXIiOnsibXkucmVzb3VyY2UuMSI6WyJhcHBlbmQiLCJkZWxldGUiXSwibXkucmVzb3VyY2UuMiI6WyJhcHBlbmQiXSwibXkucmVzb3VyY2UuMyI6WyJhcHBlbmQiXX19 - ``` - -2. Load the *Revocation Registry* stream - -3. Update (2) by adding the `cacao-mh` from (1) - -***To remove a verification method:*** - -1. Load the *Revocation Registry* stream -2. Update (1) by removing the `cacao-mh` that is being revoked - -#### Deactivate - -In order to deactivate a 3ID all capabilities will need to be revoked. - -### Revocation Registry - -3ID is based on a self-certifying revocation registry represented as a special type of Ceramic stream. In it any verification method belonging to the 3ID can be registered and revoked. Every update to the registry is recorded as a *Data Event*. When a new event is created is needs to include a valid delegation chain back to previous version of the registry. +The capability registry is based on a self-certifying data structure represented as a special type of Ceramic stream. Each DID has uniquely *one* capability registry. Any object capability issued by this DID can be notarized and revoked in the registry. Every update to the registry is recorded as a *Data Event*. ```verilog type Prinicipal Bytes // multidid type CACAOHash Bytes // multihash type Varsig Bytes // varsig -type RevocationEntry struct { - key CACAOHash - isRevoked Boolean +type Entry struct { + key CACAOHash + revoked Boolean // true if the capability has been revoked + ocap optional Link // optionally include the CID of the capability } representation tuple -// The registry should eventually be a HAMT or similar data structure -type Regsitry { CACAOHash : RevocationEntry } +// The registry should eventually be a HAMT or verkle-tree data structure +type Regsitry { CACAOHash : Entry } type Snapshot struct { registry &Regsitry - actions [RevocationEntry] + actions [Entry] } ``` @@ -233,7 +73,7 @@ type DataEvent struct { type EthereumTx // -type BlockchainTimestamp struct { +type BlockchainTimestamp struct { // https://chainagnostic.org/CAIPs/caip-168 root Link chainID String txType String @@ -250,13 +90,9 @@ type TimeEvent struct { #### Streamid -Generating the Ceramic streamid can be done in three steps, - -1. Generate the multidid representation of the 3ID, +Generating the streamid can be done in three steps, - ```solidity - := - ``` +1. Generate the multidid representation of the DID (see [Multidid specification]()). 2. Encode the multidid as an inline CID, @@ -276,7 +112,7 @@ New data events 1. Attain a key with a valid capability chain to the most recent *previous data event(s)* -2. Create one or more `RevocationEntry` objects and update the `State` from the +2. Create one or more `Entry` objects and update the `State` from the previous data event(s): @@ -299,13 +135,13 @@ The certification of a `DataEvent` can be validated using the following algorith 2. The multihash of the CACAO CID (caphash) is one of: - 1. CapHash is in the `Registry` and `isRevoked` is false + 1. CapHash is in the `Registry` and `revoked` is false 2. CapHash is in the `Principal` and **not** in the `Registry` 3. The CACAO *ability* is one or both of: - 1. `"3id/add"` - the `Registry` is only allowed to grow and, new values must have `isRevoked = false` -2. `"3id/remove"` - the `Registry` can either grow or stay the same size, all modified values must have `isRevoked = true` + 1. `"3id/add"` - the `Registry` is only allowed to grow and, new values must have `revoked = false` +2. `"3id/remove"` - the `Registry` can either grow or stay the same size, all modified values must have `revoked = true` #### Consensus @@ -328,22 +164,18 @@ type TimestampRecipt struct { } ``` -#### Dereferencing the Registry - -The 3 DID resolver can [dereference](https://wiki.trustoverip.org/display/HOME/DID+URL+Resource+Parameter+Specification) the registry to a [CAR file](https://ipld.io/specs/transport/car/carv1/) which can be independently verified. This is achieved by using the `did:3:?resource=vnd.ipld.car` DID URL. Note that the `versionTime` may be used to resolve an earlier snapshot of the registry. - ### Object Capabilities The 3 DID method relies heavily on object-capabilities as they way to add and remove verification methods, as well as delegating permissions. The root capability is `did/control`, any verification method with this capability has [independent control](https://www.w3.org/TR/did-core/#independent-control) over the DID. This means that they can take any action on behalf of this DID, `*/*` is thus a equivalent of `did/control`. The `did/vm-add` and `did/vm-remove` are actions that can be taken to update the 3ID stream and thus the DID document. In the future other more specific `did/...` capabilities my be specified to define more granular actions on the DID document. ``` ┌─────────────┐ - │ did/control │ - └──▲───▲───▲──┘ - ┌────────────┘ │ └────────┐ -┌─────┴──────┐ ┌───────┴───────┐ ┌──┴──┐ -│ did/vm-add │ │ did/vm-remove │ │ */* │ -└────────────┘ └───────────────┘ └─────┘ + │ crud/* │ + └──▲──▲───▲──┘ + ┌────────────┘ │ +┌─────┴─────┐ ┌───────┴──────┐ +│ crud/update │ │ curd/remove │ +└───────────┘ └──────────────┘ ``` #### Updating the 3ID stream @@ -422,33 +254,10 @@ Currently no reference implementation for 3ID exists. ## Appendix A: Registrations -This appendix contains all regsitrations necessary for the 3 DID method. - -### Verification method property - -**Property name:** `multihash` - -The multihash property is used to specify a multibase-encoded multihash. Usually this is a hash over an object-capability. - -* [Multihash specification](https://github.com/multiformats/multihash) -* [Multibase specification](https://github.com/multiformats/multibase) - -### Verification Method Type - -**Type name:** `capabilityHash` - -The capabilityHash verification method type indicates that the verification method is the hash of a CACAO. For a signature to be valid under a specific capabilityHash verification method, the proof must show that there is a valid delegation chain from the CACAO that corresponds with the given hash. In the most trivial case this can be achived by revealing the CACAO itself as part of the proof, a verifier can then check the hashed value of the CACAO. However, zero-knowledge proofs may be used to remove the need to reveal the CACAO, improving privacy for the DID subject. - -* [CAIP-74: CACAO - Chain Agnostic CApability Object](https://chainagnostic.org/CAIPs/caip-74) - ### Stream type code **Code:** `5` -### Multidid code - -**Code:** `0x1b` - keccak-256 - ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From db1779b3012c8d4adfe9069b72fc11419829cf33 Mon Sep 17 00:00:00 2001 From: Joel Thorstensson Date: Thu, 20 Apr 2023 16:21:19 +0200 Subject: [PATCH 4/9] CapReg partial --- CIPs/CIP-1XX.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CIPs/CIP-1XX.md b/CIPs/CIP-1XX.md index 802f556..e10af20 100644 --- a/CIPs/CIP-1XX.md +++ b/CIPs/CIP-1XX.md @@ -1,13 +1,13 @@ --- cip: 122 -title: CapReg - Notary for object-capabilities +title: CapReg - object-capability registry author: Joel Thorstensson (@oed) discussions-to: https://forum.ceramic.network/t/cip-1xx-capreg status: Draft category: Standards type: Core -created: 2023-04-11 -updated: 2023-04-11 +created: 2023-04-20 +updated: 2023-04-20 --- ## Simple Summary @@ -19,7 +19,7 @@ The CapReg capability registry enables users to notarize and revoke any object-a ## Abstract -With a special type of Ceramic stream the capability registry enables users to notarize and revoke object-capabilities issued by their DID. The registry is based on hashes of object-capabilities encoded as CACAO. +Using a simple Ceramic stream, the capability registry enables users to notarize and revoke object-capabilities issued by their DID. The registry is based on hashes of object-capabilities encoded as CACAO. ## Motivation @@ -65,7 +65,7 @@ type InitEvent &Prinicipal // an inline CID containing raw principal bytes type DataEvent struct { id &InitEvent - prv [&Event] // is prv needed if it's the first event after genesis? + prv [&Event] // optional CID pointer to previous event prf [&CACAO] // capabilities used to emit this event data &Snapshot sig Varsig From 1f4565922d4a57cb6db217595b62ba78fef98d64 Mon Sep 17 00:00:00 2001 From: Joel Thorstensson Date: Fri, 28 Apr 2023 11:04:12 +0200 Subject: [PATCH 5/9] CapReg update --- CIPs/CIP-1XX.md | 97 +++++++++++-------------------------------------- 1 file changed, 21 insertions(+), 76 deletions(-) diff --git a/CIPs/CIP-1XX.md b/CIPs/CIP-1XX.md index e10af20..8cafdf5 100644 --- a/CIPs/CIP-1XX.md +++ b/CIPs/CIP-1XX.md @@ -1,13 +1,13 @@ --- -cip: 122 +cip: 1XX title: CapReg - object-capability registry author: Joel Thorstensson (@oed) discussions-to: https://forum.ceramic.network/t/cip-1xx-capreg status: Draft category: Standards type: Core -created: 2023-04-20 -updated: 2023-04-20 +created: 2023-04-28 +updated: 2023-04-28 --- ## Simple Summary @@ -65,7 +65,7 @@ type InitEvent &Prinicipal // an inline CID containing raw principal bytes type DataEvent struct { id &InitEvent - prv [&Event] // optional CID pointer to previous event + prev [&Event] // optional CID pointer to previous event prf [&CACAO] // capabilities used to emit this event data &Snapshot sig Varsig @@ -82,7 +82,7 @@ type BlockchainTimestamp struct { // https://chainagnostic.org/CAIPs/caip-168 type TimeEvent struct { id &InitEvent - prv [&DataEvent] // should always be one CID + prev [&DataEvent] // should always be one CID proof &BlockchainTimestamp path String } @@ -100,7 +100,7 @@ Generating the streamid can be done in three steps, := ``` -3. Encode the Streamid +3. Encode the Streamid (see Appending A for `stream-type`) ```solidity := @@ -123,7 +123,7 @@ New data events 1. Set `id` to the principal (an inline CID containing a multidid encoded 3ID), 2. Add the capability chain used to the `prf` field - 3. Add the previous events to the `prv` field + 3. Add the previous event(s) to the `prev` field 4. Add the updated state to the `data` field 5. Create a `Varsig` over the `DataEvent` with the key from (1) and add the `sig` field @@ -131,21 +131,19 @@ New data events The certification of a `DataEvent` can be validated using the following algorithm, -1. The varsig validates agains the *aud* `Principal` of the referenced CACAO +1. The varsig validates agains the *aud* `Principal` of the referenced CACAOs 2. The multihash of the CACAO CID (caphash) is one of: 1. CapHash is in the `Registry` and `revoked` is false 2. CapHash is in the `Principal` and **not** in the `Registry` -3. The CACAO *ability* is one or both of: +3. The CACAO *ability* is crud on the CapReg streamid - 1. `"3id/add"` - the `Registry` is only allowed to grow and, new values must have `revoked = false` -2. `"3id/remove"` - the `Registry` can either grow or stay the same size, all modified values must have `revoked = true` #### Consensus -In case of two conflicting events (two events share the same `prv` value) the event with the earliest `TimestampEvent` should be processed first. Note that this might lead to the latter event being invalid due to its delegation chain being revoked. Also, a new event emitted after the conflict must reference both branches in its `prv` and resolve any conflict of the `Registry`. +In case of two conflicting events (two events share the same `prev` value) the event with the earliest `TimestampEvent` should be processed first. Note that this might lead to the latter event being invalid due to its delegation chain being revoked. Also, a new event emitted after the conflict must reference both branches in its `prev` and resolve any conflict of the `Registry`. If there is no anchor for either event yet, the `DataEvent` with the lowest binary value of its CID will win. Note that if a `TimeEvent` appears this order might change. @@ -166,91 +164,38 @@ type TimestampRecipt struct { ### Object Capabilities -The 3 DID method relies heavily on object-capabilities as they way to add and remove verification methods, as well as delegating permissions. The root capability is `did/control`, any verification method with this capability has [independent control](https://www.w3.org/TR/did-core/#independent-control) over the DID. This means that they can take any action on behalf of this DID, `*/*` is thus a equivalent of `did/control`. The `did/vm-add` and `did/vm-remove` are actions that can be taken to update the 3ID stream and thus the DID document. In the future other more specific `did/...` capabilities my be specified to define more granular actions on the DID document. - -``` - ┌─────────────┐ - │ crud/* │ - └──▲──▲───▲──┘ - ┌────────────┘ │ -┌─────┴─────┐ ┌───────┴──────┐ -│ crud/update │ │ curd/remove │ -└───────────┘ └──────────────┘ -``` - -#### Updating the 3ID stream - -In order to make an update to the 3ID stream, one of the verification methods could delegate the following permission to a session key: - -```json -{ - "att":{ - "did:3:z9CEZ1N1gbFK8J3rxVw3o6M5wygjoNFRSaEtkoGZw5fmbj": { - "did/vm-add": [], - "did/vm-remove": [] - } - // CID of the event to append to the 3ID stream - }, - "prf": [ - { "/": "bafybeigk7ly3pog6uupxku3b6bubirr434ib6tfaymvox6gotaaaaaaaaa" } - // The CID of the capability that grants the key control over the 3ID - // From this the 3ID can be found, resolve revreg to see if self cap is revoked - ] -} -``` - -#### Using a 3ID in Ceramic - -In order to act on behalf of a 3ID that controls a Ceramic stream, a delegation can be created by one of the verification methods in the 3ID. Note that the `prf` field must contain a link to the capability for the verification method. +CapReg relies heavily on object-capabilities as they way to add and remove CACAO hashes in the registry. Write access to CapReg can be delegated in the same way as delegting access to any other stream in Ceramic. Example using ReCap: ```json { "tar":{ - "ceramic://*?model=zkfif...": { - "crud/mutate": [], - "crud/read": [] + "ceramic://": { + "crud/create": [{}], + "crud/delete": [{}] } - }, - "prf": [ - { "/": "bafybeigk7ly3pog6uupxku3b6bubirr434ib6tfaymvox6gotaaaaaaaaa" } - // The CID of the capability that grants the key control over the 3ID - ] + } } ``` +As an extension, it would also be worth exploring the possibility of creating a zero-knowlege proof that proves that a specific CACAO hash is allowed to be added to the registry without revealing what the content of the CACAO itself. Simply the fact that the CACAO is valid should be enough to add it to the registry. + ## Rationale -While most DID methods include full public keys, or other DIDs as verification methods 3ID chooses to use hashes of object-capabilities as verification methods. One of the main use cases for 3ID is to connect multiple PKH DIDs into a single identifier on Ceramic. While doing so publically is fine for some use cases, the ability to do so privately is quite important for many. Using *capability hashes* enables more privacy since the DIDs that are delegated to doesn't strictly need to be revealed. It is worth noting that revealing the CACAO object when used is the simplest way to prove a capability chain. However, it is possible to create zero-knowledge proofs that only reveal the hash of the capability used and which session key was delegated to. - -### Cryptographic Agility - -The 3 DID method itself doesn't really limit what cryptography can be used. It boils down to what the system that interprets the actual object capabilities is capable of. In Ceramic this includes the following, but is not limited to, and can be extended in the future: +CapReg enables any DID to delegate full or partial permission to any other DID without having to worry about the capability getting lost since capabilities can now be revoked. The design requires some special logic for the state transition of the event stream to ensure that the capability is valid when the stream was updated. While Ceramic generally strives towards not including state transtion logic in event streams, for this particular case it seems difficult to avoid. -* `ed25519` -* `secp256k1` -* `secp256r1` - -Once good post quantum cryptography becomes more widely available extending Ceramic to support that will also be fairly straight forward. +While using capabilities in public is fine for some use cases, the ability to do so privately is quite important for many. Using *capability hashes* enables more privacy since the DIDs that are delegated to don't strictly need to be revealed. It is worth noting that revealing the CACAO object when used is the simplest way to prove a capability chain. However, it is possible to create zero-knowledge proofs that only reveal the hash of the capability used and the session key which was delegated to. ## Backwards Compatibility -Previous iterations of 3ID relied on the TileDocument stream type and an interpretation layer above that translated the tile contents to a DID document. That approach had numerious flaws the main one being the impossibility of privacy. This version of the spec deviates from the previous experiment in that there is a special stream type for the 3ID and that it fully relies on object-capabilities as verification methods. This is a great improvement but unfortunately it is not possible to make an upgrade in a backwards compatible manner. Instead all implementers are recommended to follow this specification only. - -## Privacy Requirements - -The 3 DID method provides a unique privacy enhancement over most other DID methods in that subject only need to reveal hashes of object-capabilities in order to use it. While the simplest way of implementing usage of the system would imply pulicly revealing these object-capabilities, it is indeed possible to create zero-knowledge proofs of the valididty of an object-capability without revealing its content. - -## Security Considerations - -3ID derives most of its security properties from the Ceramic protocol. Most notably *censorship resistance*, *decentralization*, and requiring a minimal amount of data to be synced to completely verify the integrity of a 3ID. For more details see the Ceramic [specification](https://github.com/ceramicnetwork/ceramic/blob/master/SPECIFICATION.md). +n/a ## Reference Implementations -Currently no reference implementation for 3ID exists. +Currently no reference implementation for CapReg currently exists. ## Appendix A: Registrations From 239fc74a6ca0b8b1b6f43883d59eb3f0c5c09331 Mon Sep 17 00:00:00 2001 From: Joel Thorstensson Date: Fri, 28 Apr 2023 11:07:19 +0200 Subject: [PATCH 6/9] add link --- CIPs/CIP-1XX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIPs/CIP-1XX.md b/CIPs/CIP-1XX.md index 8cafdf5..d47fdde 100644 --- a/CIPs/CIP-1XX.md +++ b/CIPs/CIP-1XX.md @@ -2,7 +2,7 @@ cip: 1XX title: CapReg - object-capability registry author: Joel Thorstensson (@oed) -discussions-to: https://forum.ceramic.network/t/cip-1xx-capreg +discussions-to: https://forum.ceramic.network/t/cip-127-capreg-object-capability-registry status: Draft category: Standards type: Core From f53fddd833fff51028b0bc22d1db4a7fdc837065 Mon Sep 17 00:00:00 2001 From: Joel Thorstensson Date: Fri, 28 Apr 2023 11:08:08 +0200 Subject: [PATCH 7/9] assign number --- CIPs/{CIP-1XX.md => CIP-127.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CIPs/{CIP-1XX.md => CIP-127.md} (100%) diff --git a/CIPs/CIP-1XX.md b/CIPs/CIP-127.md similarity index 100% rename from CIPs/CIP-1XX.md rename to CIPs/CIP-127.md From 9dd1698bbf09cc0e84977feda277c9ff5e4432cb Mon Sep 17 00:00:00 2001 From: Joel Thorstensson Date: Fri, 28 Apr 2023 11:09:08 +0200 Subject: [PATCH 8/9] assign number again --- CIPs/CIP-127.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIPs/CIP-127.md b/CIPs/CIP-127.md index d47fdde..a265fa7 100644 --- a/CIPs/CIP-127.md +++ b/CIPs/CIP-127.md @@ -1,5 +1,5 @@ --- -cip: 1XX +cip: 127 title: CapReg - object-capability registry author: Joel Thorstensson (@oed) discussions-to: https://forum.ceramic.network/t/cip-127-capreg-object-capability-registry From a5723ddf710f07f92b6278a9e620527ced220fa7 Mon Sep 17 00:00:00 2001 From: Joel Thorstensson Date: Wed, 24 May 2023 07:03:10 +0100 Subject: [PATCH 9/9] Edit CIP metadata --- CIPs/{CIP-127.md => cip-127.md} | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename CIPs/{CIP-127.md => cip-127.md} (99%) diff --git a/CIPs/CIP-127.md b/CIPs/cip-127.md similarity index 99% rename from CIPs/CIP-127.md rename to CIPs/cip-127.md index a265fa7..8ce3661 100644 --- a/CIPs/CIP-127.md +++ b/CIPs/cip-127.md @@ -4,8 +4,7 @@ title: CapReg - object-capability registry author: Joel Thorstensson (@oed) discussions-to: https://forum.ceramic.network/t/cip-127-capreg-object-capability-registry status: Draft -category: Standards -type: Core +category: RFC created: 2023-04-28 updated: 2023-04-28 ---