decentralized-identity / edv-spec

Encrypted Data Vault Spec
https://identity.foundation/edv-spec
Apache License 2.0
13 stars 5 forks source link

Add ZCAP examples #46

Open msporny opened 4 years ago

msporny commented 4 years ago

We need to add ZCAP examples to the Authorization section in the specification in order to discuss what this stuff looks like.

We should start with just a simple example for document creation.

Then we should document all of the ZCAPs that exist today in EDVs as well as what HTTP Signature invocation looks like for a ZCAP.

/cc @aljones15

aljones15 commented 4 years ago

Just to make sure I add the examples here:

https://github.com/aljones15/secure-data-store/blob/57f91bf9f3061c070dbad04156480f44bdacc32e/index.html#L349-L360

or here: https://github.com/aljones15/secure-data-store/blob/57f91bf9f3061c070dbad04156480f44bdacc32e/index.html#L3039-L3054

aljones15 commented 4 years ago
{
  "@context": "https://w3id.org/security/v2",
  "id": "urn:zcap:z1A2PQ4RQKnnxhZBJTtACsx4C",
  // the invoker is the user that will invoke this zcap
  "invoker": "did:key:z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo",
  "parentCapability": "https://foo.com/edvs/z19rnXA8d4TPLPHoSFwnQk256/zcaps/documents/z19pj5XguLxKdXjxj38o7mDj3",
  "allowedAction": [
    "read",
    "write"
  ],
  // the invocationTarget is the resource this zcap protects
  "invocationTarget": {
    "type": "urn:edv:document",
    "id": "https://foo.com/edvs/z19rnXA8d4TPLPHoSFwnQk256/documents/z19pj5XguLxKdXjxj38o7mDj3"
  },
  "proof": {
    "type": "Ed25519Signature2018",
    "created": "2020-10-07T21:59:06Z",
    "verificationMethod": "did:key:z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo#z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo",
    "proofPurpose": "capabilityDelegation",
    "capabilityChain": [
      "https://foo.com/edvs/z19rnXA8d4TPLPHoSFwnQk256/zcaps/documents/z19pj5XguLxKdXjxj38o7mDj3"
    ],
    "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..U4l113P2bhQ8J8tYV133lbWcwl86Lz3bGv_9z6lXZsCg8lVDLiJBGr2GUDBJrtQqAzYRQIFPE_BVakKnSi5pCg"
  }
}

This is a non-delegatable read/write zcap for an edv document. To make it delegatable change invoker to controller or add a delegator field.

aljones15 commented 4 years ago

These are the headers that contain a zcap for reading a document from an edv:

Host: foo.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: application/ld+json, application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
capability-invocation: zcap capability="H4sIAAAAAAAAA61Sy3KbMBT9F7qNgyGAbVY1D79iHGPjOE6n01GEAGEZUSHAkMm_VziJO9NdO11KOveel16lr5BmHJ25ZEoJ53lhynJ9h8NbymK5QLBkmDdypUo3Eg4FpmSZ2UKQm60yos4aGcwAFVTDPM0dVTuncCmQ3UpGCUFMTIQ4NI-oMVvDO-YWddezIc3u63vuxPHjOPccrHntsV1b62yq7q2J4-onujBWYg9DEWIog2jeUeeMRpigHgqrXkhheUIZFyBACK1ROIYc00wyv4kpEErfhd6sohB0twFgMRIOX989fPok4pkktOCmMtC0O1ksLmThK2v09mmy0YF9qIdOVDZlMMkD-ZPzgqk3fL9M9jvllPxMlZ0RxAfVaoUc3uToIyexz7wKfbuRciDMcBvk4AUTEeu_S-kaKH4LErQiHBp1Dj_43VDVdWW0xXEGeMmQ2leGXTMiHI66ENS-2u8p_V5_EKiKqQ9M3XgWgAoxHOH32DzEExr-UWF0eFmfdxTyNrg7H3x76vqzwjNArSWB7WtjPD7FZ-04W4Qx_fK3A59G1iXLadH5gNe0HERQfNHV-bhe2wnAl9r_U5Ti46R1IZhRs0hephA_4MXk2d0E_nZezE9zdWXPjefTpIDqTpxXDXjy8QMp8CE99OdEGd3e1l7D74dNutkvt4obpU7DIJkOoAVSvBkel6tZrPvlkWw3umrFzsNuaPeagQeq0Y8gjev20Vd0MEuNaGlUluE-Gc1yZ_nS29svqbWA9a4DAAA",action="read"
authorization: Signature keyId="did:key:z6MkpBoEPH8onKwKtDggVApMDi4MzkzPBPnG2WBFDE5moJ6N#z6MkpBoEPH8onKwKtDggVApMDi4MzkzPBPnG2WBFDE5moJ6N",headers="(key-id) (created) (expires) (request-target) host capability-invocation",signature="9S3Gg4rsn6gjr2qFrcFaU4RgQjdsEygkaTw8TS4vXx+unhw40mWLe0RYrGZ77Tuf77Q+EqRF5pCcTB24FdivDg==",created="1602108466080",expires="1602109066080"
Connection: keep-alive
Referer: https://foo.com:17443/search

These are the headers for writing to an edv document (this a doc being updated):

Host: foo.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: application/ld+json, application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/json
capability-invocation: zcap capability="H4sIAAAAAAAAA7WSS3PaMBSF_4u7beInxnhVYx7BgcQGkwKdTkZIii0QliMJbJzhv1dO2kyWnXS6lHTm3vOdoxeNIM3XjrzwGwhKvzEDK06ceXJbFHW-6UepDEJRO6H2VfsGWSFxLZU-l7IUvq5XNkHXjGe6wPDIiTzrJ0spSXFie8yVEBHk7_HZb9zZ_mm9jeslg7JJ7XqdhONhciNmLqicPA0TJyDBIaud_U2EMqaGlIDjQoagBFtC1egPaymDgOZMSN_sOo6tY3QSemP2eLEKPOSk8TS-YYtRVSR7q-PqLZnQEYPHg5r4qix3nVV2nNa3aLWrd7bHuofBzlZbAaWswiiAkrBC839oHAOk7itFh7Wfb2wQtK8p4BlWabxo8lzi3ykqK_6fTW0S6PO2_8bwReXEGXv64GKIrE7H7C1IVgB55NgyTE85gQpE4taOZVjGlWlcGd3UMv1OzzfcjRKcMCdP5A1thmXO0D_09-Uzhbcg8ZGXTLQc8L35AaY4e_XVcrxfhzkgrxX992-hat9VQnnC5yjfjiG5J9FoM5ynyWIiJoeJdRdO3M1hJKC1VOe7M1gl5J4Kst6tjQk1e9fXS4eaph1b2zzxIk-uH0zbptvvsKKeO23s7fj02GtcutqIMPPow2BKov6YW-PloB9xmTwHzXqeTEbx8LH_APa3xYJ0yjDTLpdf07qDz8IDAAA",action="write"
digest: mh=uEiDw_JHpqV_pYl8fC1pbq8yxJIPfSLDlugsGKcGvRwA2Xg
authorization: Signature keyId="did:key:z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo#z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo",headers="(key-id) (created) (expires) (request-target) host capability-invocation content-type digest",signature="58+A2bcnDBZxVsTFAEe0czZTR424Z6bxArYDBFXQO3vt3d1vMZqhM3zlDXMpGe7Q3tR7/7KPvxsVt2d3tf9SCA==",created="1602108770539",expires="1602109370539"
Content-Length: 2211
Origin: https://foo.com
Connection: keep-alive
Referer: https://foo.com/
msporny commented 4 years ago

Example of a digitally signed, non-delegatable read/write ZCAP for an EDV document:

{
  "@context": "https://w3id.org/security/v2",
  "id": "urn:zcap:z1A2PQ4RQKnnxhZBJTtACsx4C",
  "invoker": "did:key:z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo",
  "parentCapability": "https://foo.com/edvs/z19rnXA8d4TPLPHoSFwnQk256/zcaps/documents/z19pj5XguLxKdXjxj38o7mDj3",
  "allowedAction": ["read", "write"],
  "invocationTarget": {
    "type": "urn:edv:document",
    "id": "https://foo.com/edvs/z19rnXA8d4TPLPHoSFwnQk256/documents/z19pj5XguLxKdXjxj38o7mDj3"
  },
  "proof": {
    "type": "Ed25519Signature2020",
    "created": "2020-10-07T21:59:06Z",
    "verificationMethod": "did:key:z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo#z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo",
    "proofPurpose": "capabilityDelegation",
    "capabilityChain": [
      "https://foo.com/edvs/z19rnXA8d4TPLPHoSFwnQk256/zcaps/documents/z19pj5XguLxKdXjxj38o7mDj3"
    ],
    "proofValue": "zU4l113P2bhQ8J8tYV133lbWcwl86Lz3bGv9z6lXZsCgrtQqAzYRQIFPEBVakKnSi5pCg"
  }
}

Example of invoking a non-delegatable ZCAP to read an EDV document:

Host: foo.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: application/ld+json, application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
capability-invocation: zcap capability="H4sIAAAAAAAAA61Sy3KbMBT9F7qN...a4DAAA",action="read"
authorization: Signature keyId="did:key:z6MkpBoEPH8onKwKtDggVApMDi4MzkzPBPnG2WBFDE5moJ6N#z6MkpBoEPH8onKwKtDggVApMDi4MzkzPBPnG2WBFDE5moJ6N",headers="(key-id) (created) (expires) (request-target) host capability-invocation",signature="9S3Gg4rsn6gjr2qFrcFaU4RgQjdsEygkaTw8TS4vXx+unhw40mWLe0RYrGZ77Tuf77Q+EqRF5pCcTB24FdivDg==",created="1602108466080",expires="1602109066080"
Connection: keep-alive
llorllale commented 4 years ago

what HTTP Signature invocation looks like for a ZCAP

We should also point to the spec that is defining this while we're at it: https://tools.ietf.org/html/draft-ietf-httpbis-message-signatures-00

llorllale commented 4 years ago

We also seem to be assuming all zCAPs are json-ld structures. I cannot find the context for this vocabulary.

llorllale commented 4 years ago

@msporny @aljones15 what is being encoded into capability and what is the encoding?

dlongley commented 4 years ago

@llorllale,

The capability parameter for the header seen here:

capability-invocation: zcap capability="H4sIAAAAAAAAA61Sy3KbMBT9F7qN...a4DAAA",action="read"

Is generated via pseudo-code like this:

capability = base64urlEncode(gzip(JSON.stringify(zcap)));

So, take the JSON representation of the zcap, gzip it, and then base64url encode it.

dlongley commented 4 years ago

@llorllale,

I cannot find the context for this vocabulary.

The context used is here: https://w3id.org/security/v2

llorllale commented 4 years ago

@dlongley

@llorllale,

The capability parameter for the header seen here:

capability-invocation: zcap capability="H4sIAAAAAAAAA61Sy3KbMBT9F7qN...a4DAAA",action="read"

Is generated via pseudo-code like this:

capability = base64urlEncode(gzip(JSON.stringify(zcap)));

So, take the JSON representation of the zcap, gzip it, and then base64url encode it.

thanks. No wonder I couldn't decode it.

llorllale commented 4 years ago

I guess we need to define somewhere the value of invocationTarget.type ("urn:edv:document" in the example above)

llorllale commented 4 years ago

I guess we also need to agree on the set of HTTP headers and header parameters we'll be using.

llorllale commented 4 years ago

Why do we need to inline this authorization zcap into every request?

The DataVaultConfiguration model already has delegator.

The keyId parameter for Signature should be sufficient information to gather the capabilities granted to the invoker.

Part of the definition for delegator:

The root entities or cryptographic key(s) that are authorized to delegate authorization capabilities to modify the data vault's configuration or read or write to it.

I interpret this as the delegator being given access to modify the data vault's config, and/or just read or write to the data vault. In other words, the delegator has been granted access to some subset of the data vault, which may or may not include the vault's configuration.

If the above is true then there is no need to inline the authorization in every request. The invoker merely authenticates themselves as one of the delegates and invokes the action.

agropper commented 4 years ago

Can we have a ZCAP example of the Alice to Bob use-case in this very short 2017 paper by Drummond, Mark Miller and me called Identity Hubs Capabilities Perspective? The paper talks of OAuth and UMA but I'm told that ZCAPS can also do this.

The mapping to a secure data store would be:

  1. Alice has a smart and secure email server as her agent.
  2. Alice is a customer of Lab and identified by her email address. She labels the blood sample with that email.
  3. Alice authenticates to a SDS operated by Lab by responding to an authentication challenge via emailed magic link.
  4. Alice receives a capability to read 4 blood tests via her email. The capability is stored by her agent, the SDS client.
  5. Bob presents to Alice's agent / email server / AS with some credentials that the AS maps into an attenuated capability at Lab.
  6. Alice's AS sends Bob's client a capability for two tests at the Lab's SDS.
  7. Bob's client reads two tests.

This seems like the simplest possible secure data store example that involves an attenuated capability. There's a storage server (the Lab) and one client (Alice's agent) as well as second client, Bob's that will invoke the capability at Lab.

How do we turn this into the ZCAP-LD standard?

llorllale commented 4 years ago

I'll answer my own question:

Why do we need to inline this authorization zcap into every request?

If we don't, and we require the vault's controller to authorize the third party by contacting the EDV, we're effectively implementing an ACL, which is a different security model with different trade-offs.

Now the question is - why does the EDV DataVaultConfiguration model define controller and delegator in the first place? These two attributes form the core of a particular authorization strategy yet EDVs may choose to implement different strategies.

llorllale commented 4 years ago

@msporny @dlongley @aljones15 it would be helpful if you guys could also share the DataVaultConfiguration associated with those example requests above. I'm particularly interested in how the delegator field relates to these examples.

aljones15 commented 4 years ago

I'll answer my own question:

Why do we need to inline this authorization zcap into every request?

If we don't, and we require the vault's controller to authorize the third party by contacting the EDV, we're effectively implementing an ACL, which is a different security model with different trade-offs.

Now the question is - why does the EDV DataVaultConfiguration model define controller and delegator in the first place? These two attributes form the core of a particular authorization strategy yet EDVs may choose to implement different strategies.

If a zcap has a delegator it can be delegated to another user/key. So in the Alice and Bob example, if Alice receives 4 zcaps for her tests, and she is the invoker and delegator for those zcaps she can then delegate 2 of those zcaps to Bob. When she delegates she can further restrict the zcaps Bob receives, by either changing the allowedAction (for instance only allowing Bob the action read) or by declaring Bob the invoker, but not the delegator (Bob can read, but can not delegate his read only zcaps).

Alice Zcaps:

{
  "@context": "https://w3id.org/security/v2",
  "id": "urn:zcap:z1A2PQ4RQKnnxhZBJTtACsx4C",
  "invoker": "did:key:alice",
  "delegator": "did:key:alice",
  "parentCapability": "https://foo.com/edvs/z19rnXA8d4TPLPHoSFwnQk256/zcaps/documents/z19pj5XguLxKdXjxj38o7mDj3",
  "allowedAction": ["read", "write"],
  "invocationTarget": {
    "type": "urn:edv:blood:test",
    "id": "https://foo.com/edvs/z19rnXA8d4TPLPHoSFwnQk256/documents/z19pj5XguLxKdXjxj38o7mDj3"
  },
  "proof": {
    "type": "Ed25519Signature2020",
    "created": "2020-10-07T21:59:06Z",
    "verificationMethod": "did:key:alice#z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo",
    "proofPurpose": "capabilityDelegation",
    "capabilityChain": [
      "https://foo.com/edvs/z19rnXA8d4TPLPHoSFwnQk256/zcaps/documents/z19pj5XguLxKdXjxj38o7mDj3"
    ],
    "proofValue": "zU4l113P2bhQ8J8tYV133lbWcwl86Lz3bGv9z6lXZsCgrtQqAzYRQIFPEBVakKnSi5pCg"
  }
}

zcap delegated to Bob:

{
  "@context": "https://w3id.org/security/v2",
  "id": "urn:zcap:z1A2PQ4RQKnnxhZBJTtACsx4C",
  "invoker": "did:key:bob",
  "parentCapability": "urn:zcap:z1A2PQ4RQKnnxhZBJTtACsx4C",
  "allowedAction": ["read"],
  "invocationTarget": {
    "type": "urn:edv:blood:test",
    "id": "https://foo.com/edvs/z19rnXA8d4TPLPHoSFwnQk256/documents/z19pj5XguLxKdXjxj38o7mDj3"
  },
  "proof": {
    "type": "Ed25519Signature2020",
    "created": "2020-10-07T21:59:06Z",
    // I might be wrong here the verificationMethod might be Bob's key in this case.
    "verificationMethod": "did:key:alice#z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo",
    "proofPurpose": "capabilityDelegation",
    "capabilityChain": [
      "https://foo.com/edvs/z19rnXA8d4TPLPHoSFwnQk256/zcaps/documents/z19pj5XguLxKdXjxj38o7mDj3"
    ],
    "proofValue": "zU4l113P2bhQ8J8tYV133lbWcwl86Lz3bGv9z6lXZsCgrtQqAzYRQIFPEBVakKnSi5pCg"
  }
}
llorllale commented 4 years ago

@aljones15 shouldn't parentCapability and capabilityChain in the second example point to Alice's zcap?

aljones15 commented 4 years ago

@aljones15 shouldn't parentCapability and capabilityChain in the second example point to Alice's zcap?

I believe you are correct (and this is why I really shouldn't be posting these). I just checked my implementation in another project and yeah you are right. I guess that's why copy and paste is not a best practice =)

agropper commented 4 years ago

Thank you @aljones15 --- Where in your example, is Bob's scope is reduced to only two of the tests?

Can we reconcile this ZCAP example with the IETF draft of GNAP? In particular, section 1.3, shows an RS that could be and SDS, an RC that could be the Client to the SDS, and an AS that can issue the attenuated capability to the RC.

aljones15 commented 4 years ago

Thank you @aljones15 --- Where in your example, is Bob's scope is reduced to only two of the tests?

Can we reconcile this ZCAP example with the IETF draft of GNAP? In particular, section 1.3, shows an RS that could be and SDS, an RC that could be the Client to the SDS, and an AS that can issue the attenuated capability to the RC.

It is probably better if future comments are not addressed to me =) I'm in implementation not architecture and I have not read any of the specs revolving around zcaps in about 6 months and I have not read the GNAP paper at all actually (it does look interesting). With my example I decided to make one notable change. Instead of Alice receiving one capability for 4 tests I choose a more fine grained approach: Alice receives 4 capabilities each one for a single test. This allows Alice to better control who gets to see her tests. Alice is the Resource Owner in this case (she owns the EDV the tests are in). Alice only delegates the zcaps for 2 of the tests to Bob. The zcaps for the other 2 two tests remain private and Bob should not be able to access them.

just so you know it is possible to issue a zcap that grants access to all 4 tests in one zcap and then it is also possible to delegate that zcap to another user restricting their access further, I just choose the 4 zcap method as we usually have one zcap per document in an EDV and that fine grained control has worked well in existing projects.

agropper commented 4 years ago

Giving Alice a separate capability for each possible attenuation is impractical. In many cases, maybe most cases, the resource Alice controls will be described by a standard data model or a published schema. Therefore, the capability / attenuation will need to be described in terms of that data model. This might not be a problem if allowedAction can be derived from a data model published or referenced by the SDS.

Separately, if Alice authenticates to the SDS using a did that includes a service endpoint for her client / agent/ AS, how would that be coded in the ZCAP example?

aljones15 commented 4 years ago

Giving Alice a separate capability for each possible attenuation is impractical. In many cases, maybe most cases, the resource Alice controls will be described by a standard data model or a published schema. Therefore, the capability / attenuation will need to be described in terms of that data model. This might not be a problem if allowedAction can be derived from a data model published or referenced by the SDS.

Separately, if Alice authenticates to the SDS using a did that includes a service endpoint for her client / agent/ AS, how would that be coded in the ZCAP example?

I believe I have gotten out of my depth with these questions so I will refer you to @msporny and @dlongley for further answers. I do agree that one zcap for each of Alice's tests would become hard to manage and costly in the long run. It is possible to have a single capability with multiple allowedActions such as [read-test-one, read-test-two, read-test-three, read-test-four] when delegating a new capability to Bob, Alice would simply delegate the actions for the test she wants Bob to be able to read. There might be better ways of handling the single capability use case that @msporny or @dlongley could explain.

I'm not going to touch the Authentication use case, but I hope the above explanation of a single capability helps.

agropper commented 4 years ago

After today's SDS call, I'm not sure whether to continue this discussion here or in decentralized-identity/confidential-storage#104. Continuing here.

My perspective is just what will give the data subject, Alice, the most agency when dealing with service providers that also do storage (RS) and with Bob. I have no preconceived notion of layers.

As I understand the EDV perspective on the RS:

It seems the RS must offer fine-grained scopes otherwise Alice will be forced to make a copy of the resource to somewhere that does. This is impractical and introduces major synchronization issues.

llorllale commented 3 years ago

@aljones15 what are the signing algorithms in these examples?

These are the headers that contain a zcap for reading a document from an edv:

Host: foo.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: application/ld+json, application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
capability-invocation: zcap capability="H4sIAAAAAAAAA61Sy3KbMBT9F7qNgyGAbVY1D79iHGPjOE6n01GEAGEZUSHAkMm_VziJO9NdO11KOveel16lr5BmHJ25ZEoJ53lhynJ9h8NbymK5QLBkmDdypUo3Eg4FpmSZ2UKQm60yos4aGcwAFVTDPM0dVTuncCmQ3UpGCUFMTIQ4NI-oMVvDO-YWddezIc3u63vuxPHjOPccrHntsV1b62yq7q2J4-onujBWYg9DEWIog2jeUeeMRpigHgqrXkhheUIZFyBACK1ROIYc00wyv4kpEErfhd6sohB0twFgMRIOX989fPok4pkktOCmMtC0O1ksLmThK2v09mmy0YF9qIdOVDZlMMkD-ZPzgqk3fL9M9jvllPxMlZ0RxAfVaoUc3uToIyexz7wKfbuRciDMcBvk4AUTEeu_S-kaKH4LErQiHBp1Dj_43VDVdWW0xXEGeMmQ2leGXTMiHI66ENS-2u8p_V5_EKiKqQ9M3XgWgAoxHOH32DzEExr-UWF0eFmfdxTyNrg7H3x76vqzwjNArSWB7WtjPD7FZ-04W4Qx_fK3A59G1iXLadH5gNe0HERQfNHV-bhe2wnAl9r_U5Ti46R1IZhRs0hephA_4MXk2d0E_nZezE9zdWXPjefTpIDqTpxXDXjy8QMp8CE99OdEGd3e1l7D74dNutkvt4obpU7DIJkOoAVSvBkel6tZrPvlkWw3umrFzsNuaPeagQeq0Y8gjev20Vd0MEuNaGlUluE-Gc1yZ_nS29svqbWA9a4DAAA",action="read"
authorization: Signature keyId="did:key:z6MkpBoEPH8onKwKtDggVApMDi4MzkzPBPnG2WBFDE5moJ6N#z6MkpBoEPH8onKwKtDggVApMDi4MzkzPBPnG2WBFDE5moJ6N",headers="(key-id) (created) (expires) (request-target) host capability-invocation",signature="9S3Gg4rsn6gjr2qFrcFaU4RgQjdsEygkaTw8TS4vXx+unhw40mWLe0RYrGZ77Tuf77Q+EqRF5pCcTB24FdivDg==",created="1602108466080",expires="1602109066080"
Connection: keep-alive
Referer: https://foo.com:17443/search

These are the headers for writing to an edv document (this a doc being updated):

Host: foo.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: application/ld+json, application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/json
capability-invocation: zcap capability="H4sIAAAAAAAAA7WSS3PaMBSF_4u7beInxnhVYx7BgcQGkwKdTkZIii0QliMJbJzhv1dO2kyWnXS6lHTm3vOdoxeNIM3XjrzwGwhKvzEDK06ceXJbFHW-6UepDEJRO6H2VfsGWSFxLZU-l7IUvq5XNkHXjGe6wPDIiTzrJ0spSXFie8yVEBHk7_HZb9zZ_mm9jeslg7JJ7XqdhONhciNmLqicPA0TJyDBIaud_U2EMqaGlIDjQoagBFtC1egPaymDgOZMSN_sOo6tY3QSemP2eLEKPOSk8TS-YYtRVSR7q-PqLZnQEYPHg5r4qix3nVV2nNa3aLWrd7bHuofBzlZbAaWswiiAkrBC839oHAOk7itFh7Wfb2wQtK8p4BlWabxo8lzi3ykqK_6fTW0S6PO2_8bwReXEGXv64GKIrE7H7C1IVgB55NgyTE85gQpE4taOZVjGlWlcGd3UMv1OzzfcjRKcMCdP5A1thmXO0D_09-Uzhbcg8ZGXTLQc8L35AaY4e_XVcrxfhzkgrxX992-hat9VQnnC5yjfjiG5J9FoM5ynyWIiJoeJdRdO3M1hJKC1VOe7M1gl5J4Kst6tjQk1e9fXS4eaph1b2zzxIk-uH0zbptvvsKKeO23s7fj02GtcutqIMPPow2BKov6YW-PloB9xmTwHzXqeTEbx8LH_APa3xYJ0yjDTLpdf07qDz8IDAAA",action="write"
digest: mh=uEiDw_JHpqV_pYl8fC1pbq8yxJIPfSLDlugsGKcGvRwA2Xg
authorization: Signature keyId="did:key:z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo#z6MkfYbPxUoctzT3xYQCGEQHsM6aw4hTCQ4AiAmgx4kHJdgo",headers="(key-id) (created) (expires) (request-target) host capability-invocation content-type digest",signature="58+A2bcnDBZxVsTFAEe0czZTR424Z6bxArYDBFXQO3vt3d1vMZqhM3zlDXMpGe7Q3tR7/7KPvxsVt2d3tf9SCA==",created="1602108770539",expires="1602109370539"
Content-Length: 2211
Origin: https://foo.com
Connection: keep-alive
Referer: https://foo.com/
llorllale commented 3 years ago

I also notice the examples seem to be following the prior Cavage drafts and not the new HTTPbis one (ie. use of the Authorization header).

msporny commented 3 years ago

@aljones15 what are the signing algorithms in these examples?

The signing algorithm is determined by the type of key being used to avoid the sort of attacks that are used on the JOSE stack (allowing the attacker to choose the signing algorithm... like the JOSE 'none' value, which led to a number of terrible security breaches).

It's been slow going trying to convince IETF that this is the right approach... but we're making progress. It does seem like something is missing from the authorization field... like the HTTP Header normalization algorithm... don't have time to look into it right now. My expectation is that once the http-signatures stuff settles at IETF that there will be a versioning mechanism introduced that would resolve this issue.

msporny commented 3 years ago

I just checked, looks like we're not including the algorithm="hs2019" field per the latest HTTP Signatures spec, which is not good (granted, this was just introduce a while ago and we don't have consensus on the direction yet). This needs to be fixed.

aljones15 commented 3 years ago

@aljones15 what are the signing algorithms in these examples?

For the Authorization headers it is an HTTP Signature. signature="9S3Gg4rsn6gjr2qFrcFaU4RgQjdsEygkaTw8TS4vXx+unhw40mWLe0RYrGZ77Tuf77Q+EqRF5pCcTB24FdivDg==",signature="58+A2bcnDBZxVsTFAEe0czZTR424Z6bxArYDBFXQO3vt3d1vMZqhM3zlDXMpGe7Q3tR7/7KPvxsVt2d3tf9SCA==

headers="(key-id) (created) (expires) (request-target) host capability-invocation content-type digest",

I'm pretty confident you are aware of how HTTP Sigs work, but if not this is a high level overview: The key parameter contains the names of various HTTP headers. Headers in () are pseudo-headers and do not refer to actual HTTP headers in the request, but all of the other headers do. Those values are then used to make a string which is hashed and then passed to the key's sign function. The resulting signature is base64 encoded.

The keys used to generate these signatures and the zcaps are ed25519 keys.

OR13 commented 3 years ago

This seems like great progress.

In the interest of moving us towards code that can be used to generate test vectors for edvs, I would like help getting some simple structures commited to the repo for constructing / invoking capabilities

OR13 commented 3 years ago

I added some code here: https://github.com/decentralized-identity/secure-data-store/pull/116

But am seeing strange errors regarding base64url.encode not being defined.

agropper commented 3 years ago

I'm looking for co-leads for a discussion of authorization at IIW. Ideally, the co-leads would be familiar with both ZCAP-LD and GNAP. Here's how I would frame the issue as it stands:

Stipulate: Our authorization goal for a confidential resource (CR) is:

Example 1 and 2:

Alyssa adds attenuation:

Caveats and Semantic Drift:

...some mutual understanding of terminology must be understood between the entity adding a caveat and the target evaluating (or any other parties observing) the invocation.

When correlation is desired, as with VCs: