Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

Initial implementation #1

Merged
merged 3 commits into from
Mar 25, 2022
Merged

Initial implementation #1

merged 3 commits into from
Mar 25, 2022

Conversation

clehner
Copy link
Contributor

@clehner clehner commented Mar 22, 2022

This implements and documents a proof type for representing a CACAO as a ZCAP.

The implemented proof type may be used in ssi. It uses cacao-rs for CACAO functionality. Functionality is included to convert a CACAO to ZCAP and back, which is used as part of the proof verification. A vocabulary document is included to document the CACAO-ZCAP property mappings and new RDF terms.

This uses some updates proposed to the ZCAP spec in w3c-ccg/zcap-spec#39 (My summary here: w3c-ccg/zcap-spec#39 (comment))); namely, using urn:zcap:root:... for the root/target document id. invoker is kept instead of the proposed controller (which would be better), since ssi still uses invoker (issue: spruceid/ssi#411).

The proof properties and associated document properties are mapped to and from CACAO properties in a mostly-straightforward way. An earlier version parsed the CACAO statement string into a data structure, but this version passes it into the ZCAP as-is.

Rust docs: https://demo.didkit.dev/2022/03/22/cacao-zcap-rustdoc/cacao_zcap/

Depends on: spruceid/ssi#410, spruceid/cacao-rs#2, spruceid/cacao-rs#9, spruceid/cacao-rs#10

Limitation: instead of a verification method DID URL in the invoker property as mapped from the "aud" CACAO property, the DID is used. This is because of an error parsing DID URLs with the iri_string library used in cacao-rs (noted in spruceid/cacao-rs#2 (comment)). If invoker is changed to controller (spruceid/ssi#411), this parsing issue will not matter. (But reducing it to a test case and possibly opening an issue on the iri_string library would be a good TODO).

@clehner clehner marked this pull request as ready for review March 23, 2022 13:42
@clehner clehner requested review from awoie and chunningham March 23, 2022 16:32
Copy link

@awoie awoie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left one comment on transformation.

Comment on lines 6 to 13
URI: did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp
Version: 1
Chain ID: 1
Nonce: h8yQTdScwt9pTyaQa
Issued At: 2022-03-14T13:30:42.763Z
Expiration Time: 2022-03-14T13:32:42.763Z
Request ID: urn:uuid:5fa2f8cc-fea0-4280-b98c-99f0acecf0e1
Resources:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general that looks good to me. I was wondering what happens if someone also uses request-id, chain-id, not-before and other resources in the SIWE. I guess the did:pkh would allow us to get the chain-id but when verifying the signature how can we get request-id, not-before and remaining resources if those fields are not included in the proof? Would it make sense to just add those fields?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SIWE request-id (Request ID) is passed into the zcap as id currently. We could try to change this to use a CID computed from the CACAO's IPLD representation (spruceid/cacao-rs#4); in that case request-id could maybe be passed into the zcap as a new property (e.g. siweRequestId).

SIWE chain-id (Chain ID) is incorporated into the PKH DID in CACAO iss as part of the SIWE->CACAO transformation; that DID then goes into the verificationMethod property of the zcap proof.

SIWE not-before (Not Before) I propose mapping to the validFrom property from the Credentials namespace. (Test vector updated: c9fd397). This validFrom term is included in VC Data Model v1.0/1.1 context, although it's not mentioned in the namespace document or defined normatively in VC Data Model, only mentioned in a note (https://www.w3.org/TR/2022/REC-vc-data-model-20220303/#h-note-13) and in some currently-opened issues. (Note there is also a validFrom property defined under schema.org, https://schema.org/validFrom, which is used in CCG's Traceability vocabulary). I didn't find a "notBefore" term in any contexts currently in ssi, but validFrom seems close in meaning to the "nbf" (Not Before) JWT Claim; correspondence of those was suggested in w3c/vc-data-model#809 (comment).

The first resource is expected to be the invocation target URL; that is converted into a urn:zcap:root: URI (the root zcap id / target document id) as the first item of the proof capabilityChain array, as described in w3c-ccg/zcap-spec#39. Subsequent resources are assumed to be delegation ids, and are passed through into the proof capabilityChain array following the root zcap id.

Copy link

@awoie awoie Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, that sounds good to me. i think it would be good to follow the CID approach for id. i'm not sure if request-id is always a URI. what do you think?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in case id has to be a URI, we could then represent the CID as an ipfs:// like you suggested on the call today?

Copy link
Contributor Author

@clehner clehner Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request-id is not required to be a URI by EIP-4361 (SIWE) or by the CACAO CAIP, or by the cacao-rs implementation. If continuing to use it that way here (as the zcap id), additional validation should probably be added.

In w3c-ccg/zcap-spec#39 it is proposed that zcap ids be UUID URNs; the test vector here uses that, but there is not validation of that implemented here. I'm asking about using content-hash ids rather than UUIDs: w3c-ccg/zcap-spec#39 (comment)

I think using the CACAO IPLD CID for the id could be good. The ipfs scheme seems relevant for this; I'm having trouble finding it's specification, however, and it would represent more than just a CID: ipfs/specs#248; I don't see mention of a URI scheme under https://ipld.io/specs/ . ipfs://<CID> seems to be a de-facto usage; although it was noted that :// may be improper use: ipfs/kubo#1678 (comment).

If id has to be a UUID, and we want use a CID and not require that request-id be a UUID, maybe the CID could be transformed into a UUID. If truncation is needed, that's okay, since the reverse mapping is not needed (since the CID does not appear in the CACAO but is computed from it; verification could still be done).

Another complication is that I realized I made a mistake with regards to w3c-ccg/zcap-spec#39; the parent delegation (last value in in capabilityChain) is supposed to be included by value instead of by reference (unless it is the root id, as is the case for a first delegated zcap). Encoding a whole ZCAP or CACAO into a resource URI might be impractical. I'm asking about using content-hash ids for parent delegations rather than including them directly: w3c-ccg/zcap-spec#39 (comment). If parent delegation objects have to be embedded in the zcap (rather than referenced by content hash), CACAO-ZCAP would still work for first delegations, but further delegations could only be ZCAPs (not CACAOs) - unless we define a way to include the parent CACAO/ZCAP by value in a CACAO (e.g. using a data URI in the resources array).

Copy link

@awoie awoie Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think ipfs:// has not been registered yet but it seems someone filed the application: https://github.com/jonnycrunch/ipfs-uri-scheme/blob/master/application.md

Update: ok, seems no application was filed since the spec contains placeholder text :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside about IPFS URI scheme

The ipfs URI scheme was registered, as I understand it, by Frédéric Wang from Igalia, on behalf of Protocol Labs (specifically with Dietrich, at least that is who was in contact with the SSB community about theirs). They did this along with other "DWeb" schemes (ssb, dat, hyper, dweb, ipns). Also they helped get these schemes whitelisted in Firefox and Chromium.
https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml#uri-schemes-1
The assignment page https://www.iana.org/assignments/uri-schemes/prov/ipfs does not link to jonnycrunch's draft but contains a link to https://ipfs.io, https://github.com/ipfs/specs, and https://docs-beta.ipfs.io/how-to/address-ipfs-on-web/#dweb-addressing-in-brief (404). I suppose if jonnycrunch's draft proceeds, they could get it added to https://github.com/ipfs/specs, and then have the IANA page updated to point to that. In my opinion the IANA page should link to that draft right now, as it's more helpful then the current links which do not specify the scheme.

Feedback about using content hash ids in ZCAP is that the extra complexity is not wanted: w3c-ccg/zcap-spec#39 (comment)

Copy link
Contributor

@chunningham chunningham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice, looks good to me, well organised

nonce: nonce_opt,
domain: domain_opt,
..
} = proof;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this fn is more for roundtripping than generalised processing, but do you think its possible in principle to allow any kind of LDP here, and transliterate the LDP-type-specific fields (e.g. JWKs for did:pkh proofs) into extra fields in the cacao signature object?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

realising now that round-tripping will strip the context and make that a problem

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed that the fields of the CACAO field were fixed. At least the fields representable in SIWE are fixed.
If additional CACAO fields can be added, without regard to SIWE, then yes we could represent additional LDP fields there.
There would be some question of how to do so. e.g. as JSON (generically, or with a registry of mappings), using JSON-LD processing (is there a IPLD-LD?), or as RDF (here's a thread about adding N-Quads in multicodec for IPLD: multiformats/multicodec#180).
Also, would a new CACAO payload type and signature type need to be defined for this; or would we expect non-SIWE signature/payload types to allow adding arbitrary additional fields.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think any extra CACAO fields are needed, I would assume we define a new CACAO signature type which uses the m: SignatureMeta field in the signature struct to hold the extra fields (first instinct is to transliterate the json into cbor).

/// <https://w3id.org/security#expires>
/// mapped to CACAO "exp" value
#[serde(skip_serializing_if = "Option::is_none")]
pub expires: Option<String>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we enforce correct timestamps at the type level?

Copy link
Contributor Author

@clehner clehner Mar 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should.

Some possible options...

  • siwe::TimeStamp (String, DateTime<FixedOffset>) - used in siwe-rs, and in cacao-rs in update siwe deps and integration cacao-rs#6
  • DateTime<Utc> - used in ssi::vc::Proof::created
  • ssi::vc::VCDateTime (DateTime<FixedOffset>, bool use_z) - used in ssi::vc::Credential::issuance_date and expiration_date

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be nice to standardise the type we use for time rep in all crates, I imagine the requirements are:

  • sensible time comparison without conversion (i.e. PartialOrd<DateTime<Utc>>)
  • preserve serialisation-specific info when round-tripping (specifically timezone offset and milli/micro/nanosecond precision)

siwe::TimeStamp is ok but would prefer perhaps to not carry around an extra String if we don't need? If ssi::vc::VCDateTime suffices (w.r.t. point 2) I think that would also be ok. Nothing wrong with bringing that into siwe/cacao-rs if needed IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Continuing at #4.
I think VCDateTime would cover it. We may need more test cases...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants