Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HttpSig #125

Merged
merged 50 commits into from
Mar 1, 2021
Merged
Changes from 1 commit
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
e686fea
Update HttpSig with Credentials
bblfish Feb 4, 2021
d563df7
Credentials piece
bblfish Feb 4, 2021
91a7f45
improvements to text
bblfish Feb 4, 2021
18d8d76
minor fix
bblfish Feb 4, 2021
535c436
improve grammar
bblfish Feb 4, 2021
c57a3c2
improve language on policies
bblfish Feb 4, 2021
bdee29f
clarify requirement on TLS and other
bblfish Feb 9, 2021
6286ac0
Update HttpSignature.md
bblfish Feb 9, 2021
7d7153a
Update HttpSignature.md
bblfish Feb 9, 2021
43c3989
Update HttpSignature.md
bblfish Feb 9, 2021
bfe1677
improve language on policies
bblfish Feb 4, 2021
745a783
Merge branch 'HttpSig' of github.com:bblfish/authentication-panel int…
bblfish Feb 10, 2021
817141f
put every sentence on newline for easier diffs
bblfish Feb 10, 2021
b014890
Introduce SSI Governance language
bblfish Feb 10, 2021
7ae6154
minor tweak to Sequence diagram
bblfish Feb 10, 2021
2ae6c3a
Update HttpSignature.md
bblfish Feb 11, 2021
fe2f8b2
Link to did key URL discussion, and fix clarify `>` text
bblfish Feb 11, 2021
4dcf550
Improve text. Add reference and examples for did:key: URLs
bblfish Feb 13, 2021
2fb7d20
Link to Univeral Wallet and Verifiable Credential spec
bblfish Feb 13, 2021
d360c9f
Update HttpSignature.md
bblfish Feb 14, 2021
526b490
Illustrate protocol with Authorization headers
bblfish Feb 14, 2021
9965ff9
change Http-Sig method to HttpSig
bblfish Feb 14, 2021
eba19d1
Merge branch 'HttpSig' of github.com:bblfish/authentication-panel int…
bblfish Feb 14, 2021
636c47d
Update HttpSignature.md
bblfish Feb 14, 2021
c8c3d7e
Update HttpSignature.md
bblfish Feb 14, 2021
6236b81
fix suggested by TallTed
bblfish Feb 14, 2021
9364c93
Merge branch 'HttpSig' of github.com:bblfish/authentication-panel int…
bblfish Feb 14, 2021
f428718
fix some spelling mistakes found by vimr
bblfish Feb 14, 2021
6f3ded4
Update HttpSignature.md
bblfish Feb 17, 2021
89bb2ca
Update HttpSignature.md
bblfish Feb 17, 2021
a9d617b
Update HttpSignature.md
bblfish Feb 17, 2021
b791faa
add executive summary
bblfish Feb 22, 2021
500c9a5
Unify refs to "Signing Http Messages" as HTTP-Sig
bblfish Feb 22, 2021
b8c9a47
HTTP-Sig the RFC was too similar to HttpSig the protocol
bblfish Feb 22, 2021
4f190ea
fix typo and clarify
bblfish Feb 22, 2021
f285937
The Summary is not high level enough for executives
bblfish Feb 24, 2021
b04dd9a
Update HttpSignature.md
bblfish Feb 24, 2021
7186efa
changes from feedback by Jos
bblfish Feb 25, 2021
6dd9563
Merge branch 'HttpSig' of github.com:bblfish/authentication-panel int…
bblfish Feb 25, 2021
7fe5fca
minor
bblfish Feb 25, 2021
4c2b449
Update HttpSignature.md
bblfish Feb 25, 2021
788e13f
Update HttpSignature.md
bblfish Feb 25, 2021
f33de24
Update HttpSignature.md
bblfish Feb 25, 2021
d158f1c
Update HttpSignature.md
bblfish Feb 25, 2021
01ea0f3
show some examples with did:key
bblfish Feb 25, 2021
1a33f02
Small improvement.
bblfish Feb 25, 2021
693d579
typo
bblfish Feb 25, 2021
121b223
Update HttpSignature.md
bblfish Feb 25, 2021
3be6550
Update HttpSignature.md
bblfish Mar 1, 2021
545a452
changes in response to feedback by @csarven
bblfish Mar 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 47 additions & 42 deletions HttpSignature.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,23 @@
The work is based on [draft-cavage-http-signature-12](https://tools.ietf.org/html/draft-cavage-http-signatures-12), which evolved and gained adoption since 2013, being tested by a [large number of implementations](https://github.com/w3c-dvcg/http-signatures/issues/1), and this is set to grow by being taken up by the IETF.

HTTP Signature has the advantages of being very simple and being specified directly at the HTTP layer, bypassing the problem of client authentication at the TLS layer.
(Note: all communication here is assumed to run over TLS.) The protocol allows a client to authenticate by signing any of several HTTP headers with any one of its private keys.
(Note: all communication here is assumed to run over TLS.)

The protocol allows a client to authenticate by signing any of several HTTP headers with any one of its private keys.
In order for the server to verify this signature, it needs to know the matching public key.
This information must be transmitted by the client, in the form of an opaque string known as a `keyId` (see [§2.1.1 keyId](https://tools.ietf.org/html/draft-cavage-http-signatures-11#section-2.1.1)).
This string must enable the server to look up the key; how this look-up is done is not specified by the protocol.

This `Http-Sig` protocol extension allows the `keyId` to be interpreted as a URL.
The proposal here is to use an `https` URL identifier ending with a fragment for the `keyId`.
This proposal extension is compatible with the keyId using other URI schemes such as [DID](https://www.w3.org/TR/did-core/)s.
The main use case is to allow the use of an `https` URL identifier ending with a fragment for the `keyId`, but it would also allow other URI schemes such as [DID](https://www.w3.org/TR/did-core/)s.

In order for a server to discover the key, it can fetch the `keyId Document`, whose URL is given by the `keyId` URL without the fragment identifier (see [§3 of RFC 3986: Uniform Resource Identifier (URI): Generic Syntax](https://tools.ietf.org/html/rfc3986?#section-3)).
By allowing URLs to be used in the `keyId` field, we make it possible for the server to discover the key by fetching the `keyId Document`, whose URL is given by the [resolved](https://tools.ietf.org/html/rfc3986#section-5) `keyId` URL without the fragment identifier (see [§3 of RFC 3986: Uniform Resource Identifier (URI): Generic Syntax](https://tools.ietf.org/html/rfc3986?#section-3)).

## Extending `HTTP-Sig` with URLs

Here we consider the minimum extension of `HTTP-Sig` with
`keyId`s that are URLs.
We point to the advantages of this
in terms of enabling client creation, editing, and deleting of keys.
We then show how this ties into the larger Access
Control Protocol used by Solid.
Here we consider the minimum extension of `HTTP-Sig` with `keyId`s that are URLs.
We point to the advantages of this in terms of enabling client creation, editing and deleting of keys.
bblfish marked this conversation as resolved.
Show resolved Hide resolved
We then show how this ties into the larger Access Control Protocol used by Solid.

### The Sequence Diagram

Expand All @@ -43,34 +41,45 @@ App Document Server
| | |
| |<-----------------(4) GET keyId----|
| |-(5) return keyId doc------------->|
| -verify sig |
| -verify wACL|
| - verify sig |
| - verify ACL |
| |
|<---------------------------------------------(6) answer resource---|
```

The main protocol difference from `Http-Sig` is the request by the resource server for the `keyId document` in (4).
If this document is cached and still valid, it will not require an extra request on the Web.
In (2) the Resource server responds to a request by sending a 401 or 402 response with the `WWW-Auth` Sig header.
It should also add a `Link:` relation to an Access-Control resource which describes which resources can have access.
bblfish marked this conversation as resolved.
Show resolved Hide resolved
(Without such a Link the client would only be able to guess what key to send.)
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps an alternative would be to include keyId in the field-value of WWW-Authenticate. Bonus: 1) efficient; one less connection 2) flexible; no need to hop through a specific access control system.

Copy link
Member Author

@bblfish bblfish Mar 1, 2021

Choose a reason for hiding this comment

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

The WWW-Authenticate: HttpSig header is sent by the server to the client. The HttpSig method is meant to indicate to the client that it can use "Signing Http Messages" with the keyId used as URL.
It could send the content of the ACL in the body so not requiring an extra connection (or with HTTP/2 the server can send it ahead of being asked).

With [HTTP/2 server Push](https://tools.ietf.org/html/rfc7540#section-8.2), the server could immediately push the content of the linked-to Access Control document to the client, assuming reasonably that the client would have connected with the right key had it allready known the content.
bblfish marked this conversation as resolved.
Show resolved Hide resolved
It may also be possible to send the ACL rules directly in the body (Todo: research) of the response.
Copy link
Member

Choose a reason for hiding this comment

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

Possibly. If so, should probably be wrapped in Problem Details in response body eg solid/specification#28


The Access Control rule could be as simple as stating that the user needs to be authenticated with a key, but any number of more complicated use cases are possible, as described in the [Use Cases and Requirements Document](https://solid.github.io/authorization-panel/wac-ucr/).

If the client can find a key that satisfies the Access Control Rules then it can use the private key to sign the headers in (3) as specified by [Signing HTTP Messages](https://w3c-ccg.github.io/did-method-key/) and pass a link to the key in the `keyId` field as a URL.

The main protocol difference from `Http-Sig` is the potential request by the resource server for the `keyId document` in (4) to get that key.
This may not necessarily lead to a new network connection being opened to the outside world in the following cases:
* The `keyId` URL is local to the resource server,
* The `keyId` URL is a [did:key](https://w3c-ccg.github.io/did-method-key/) URL, ie contains all the data of a public key,
bblfish marked this conversation as resolved.
Show resolved Hide resolved
* The `keyId` URL refers to an external resource, but the resource server has a fresh cached copy of it.
Copy link
Member

Choose a reason for hiding this comment

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

Haven't fully thought this through (and it is late late night..) but there may be some dependency/expectation that the URI is persistent in that a particular key (resource) is allocated to the URI. If the key resource ever changes but the resource server still uses the cached copy, client may not ever be able to authenticate until cache is cleared. So, either a good practice is encouraged (which is not different than the general best practice of URI Persistence as per AWWW) or there needs to be a way to bust the cache... or don't cache. Todo: more thinking/implementing.

Copy link
Member Author

@bblfish bblfish Mar 1, 2021

Choose a reason for hiding this comment

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

Yes, I think that type of problem works itself out with experience, and the process followed by the server will depend on how serious the threat is. It the key on the server or with the P2P connection option on the client, these things get to be a lot simpler. With did:keys the key comes along with the message.

This can be the case of cached `https` URL documents but also for `did:...` documents stored on some form of blockchain which the server has access to offline.
* The `keyId` is a relative URL on the client, which the server can GET using the P2P extension to HTTP (more on that below).

Another extension required by the [Solid use cases](https://solid.github.io/authorization-panel/wac-ucr/) is that the response (2) must contain a link to an Access Control Document.
This is needed by Solid (Social Linked Data) clients, as these are modeled on web browsers; they are not tied to reading/writing data from one domain, but are able to start from any web server, and are able to follow links around the web.
## Solid Use Case

In order to understand why we may want keys that are not local to the resource server we need to make a small disgression and explain the principal Solid use case.
bblfish marked this conversation as resolved.
Show resolved Hide resolved
We start by noticing that Solid (Social Linked Data) clients are modeled on web browsers.
They are not tied to reading/writing data from one domain, but are able to start from any web server, and are able to follow links around the web.
As a result, they cannot know in advance of arriving at a resource, what type of authentication will be needed there.
Furthermore they may be quite keen to create cross site identities and link them up, as that can allow decentralised conversations to happen and for people to build reputations across web sites.
bblfish marked this conversation as resolved.
Show resolved Hide resolved

We can illustrate this by the following diagram showing the topology of the data a solid client may need to read.
Starting from Tim Berners-Lee's [WebID](https://www.w3.org/2005/Incubator/webid/spec/identity/), a client may need to follow the links spanning web servers (represented as boxes).

![TimBLs foaf profile](https://raw.githubusercontent.com/wiki/banana-rdf/banana-rdf/img/WebID-foafKnows.jpg)

Starting from one resource, such as TimBL's WebID, a client should be able to follow links to other resources, some of which will be protected in various ways, requiring different forms of proof.

As a result a client needs to know on reaching a resource what keys to show.
The [Web Access Control Spec](https://solid.github.io/web-access-control-spec/)
allows this to be done by requiring the Solid Server to add a `Link` header pointing
to the Access Control rules.
With [HTTP/2 server Push](https://tools.ietf.org/html/rfc7540#section-8.2), the server could immediately push the content of the linked-to Access Control document to the client, assuming
reasonably that the client would have connected with the right key had it
allready known the content.
It may also be possible to send the ACL rules directly in the body (Todo: research) of the response.

### The KeyId URL

In order for it to be clear that the `keyId` is to be interpreted as a URL, the `keyId` field MUST enclose the URL with `'<'` and `'>'` characters.
Expand All @@ -96,23 +105,20 @@ Signature: sig1=:cxieW5ZKV9R9A70+Ua1A/1FCvVayuE6Z77wDGNVFSiluSz...==:

It could also allow key based did URLs as described in [issue 217 of the Solid Spec](https://github.com/solid/specification/issues/217#issuecomment-777509084).

The advantage of a URL is that it allows the client to use HTTP Methods such as `POST` or `PUT` to create keys, as well as `PUT`, `PATCH` and `DELETE` to edit them, solving the problem of key revocation.
The advantage of `https` URL in particular is that it allows the client to use HTTP Methods such as `POST` or `PUT` to create keys, as well as `PUT`, `PATCH` and `DELETE` to edit them, solving the problem of key revocation.

We also reserve the use of keyIds enclosed with `'>'` and `'<'` characters for
possible extensions of HTTP such as the [Peer-to-Peer Extension to HTTP/2 draft](https://tools.ietf.org/html/draft-benfield-http2-p2p-02) as discussed on the [ietf-http-wg mailing list](https://lists.w3.org/Archives/Public/ietf-http-wg/2021JanMar/0049.html).
This would allow the client to let the server know that it can request the key by making an HTTP `GET` request on the given relative URL, reducing to a minimum the reliance on the network.
With such a protocol available, the request could be signed as follows
We also reserve the use of keyIds enclosed with `'>'` and `'<'` characters for possible extensions of HTTP such as the [Peer-to-Peer Extension to HTTP/2 draft](https://tools.ietf.org/html/draft-benfield-http2-p2p-02) as discussed on the [ietf-http-wg mailing list](https://lists.w3.org/Archives/Public/ietf-http-wg/2021JanMar/0049.html).
Here is an example of a header sent by a client to the server with such a URL:

```HTTP
Signature-Input: sig1=(); keyId=">/keys/test-key-a<"; created=1402170695
Signature: sig1=:cxieW5ZKV9R9A70+Ua1A/1FCvVayuE6Z77wDGNVFSiluSzR9TYFV
vwUjeU6CTYUdbOByGMCee5q1eWWUOM8BIH04Si6VndEHjQVdHqshAtNJk2Quzs6WC
2DkV0vysOhBSvFZuLZvtCmXRQfYGTGhZqGwq/AAmFbt5WNLQtDrEe0ErveEKBfaz+
IJ35zhaj+dun71YZ82b/CRfO6fSSt8VXeJuvdqUuVPWqjgJD4n9mgZpZFGBaDdPiw
pfbVZHzcHrumFJeFHWXH64a+c5GN+TWlP8NPg2zFdEc/joMymBiRelq236WGm5VvV
9a22RW2/yLmaU/uwf9v40yGR/I1NRA==:
```

On receiving such a signed header, the server would know that it can request the key by making an HTTP `GET` request on the given relative URL on the client using the same connection but after switching client/server roles.
This would reduce to a minimum the reliance on the network.



### The KeyId Document

Expand All @@ -137,11 +143,9 @@ If we were to use [the cert ontology](https://www.w3.org/ns/auth/cert#) (as used
(Other ontologies that could be used:
* [The Security Vocabulary](https://web-payments.org/vocabs/security)
* Any other?)
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps the Web Of Trust RDF Ontology. I use both cert and wot eg. the wot snippet:

@prefix wot: <http://xmlns.com/wot/0.1/> .

<https://csarven.ca/#i>
  wot:hasKey <https://csarven.ca/#key-8e3a> .

<https://csarven.ca/#key-8e3a>
  a wot:PubKey ;
  wot:pubkeyAddress <https://csarven.ca/key/A74187CE3D508E3A.asc> ;
  wot:fingerprint "0ADFF0BACC9F0A16FA782D94A74187CE3D508E3A" .


### The Access Control Rules

In order to understand a little bit better how the client can decide if it has
the right key, we give a quick description of how Access Control Rules function.
In order to understand a little bit better how the client can decide if it has the right key, we give a quick description of how Access Control Rules function.

The [Access Control Rules](https://solid.github.io/web-access-control-spec/) linked to by a resource, can specify an agent by describing their relation to a public key.

Expand All @@ -158,8 +162,7 @@ The [Access Control Rules](https://solid.github.io/web-access-control-spec/) lin
[ cert:key <https://candice.example/clefs/doc1#clef3> ]
```

The keys can also be relative to the server of course, and in the future
also `DID`s.
The keys can also be relative to the server of course (or `DID`s).

Instead of listing agents individually in the acl they can also
be listed as belonging to a group
Expand Down Expand Up @@ -201,7 +204,7 @@ If the Access Control Rule linked to in (2) specifies that only agents that can
If the policies do not give a clear answer, the user agent will need to ask the user -- at that time or later, but in any case before engaging in the request (3) - to confirm authenticated access.

Having selected a Credential, this can be passed in the response in (3)
to the server by adding a `Credential:` header with as value a relative or absolute URL enclosed in `<` and `>`.
to the server by adding a `Credential:` header with as value a relative or absolute URL enclosed in `<` and `>` refering to that credential.
As before we reserve the option of enclosing a relative URL in `>` and `<` to refer to a client side resource if some form of P2P extension of
HTTP is available (see [Peer-to-Peer Extension to HTTP/2 draft](https://tools.ietf.org/html/draft-benfield-http2-p2p-02)).

Expand Down Expand Up @@ -239,7 +242,9 @@ If the `Credential` header URL
* is enclosed in '<' and '>' then
* if it is relative it can be fetched on the same server
* if is is an absolute URL it can be fetched by opening a new connection
* is enclosed in `>` and `<` and P2P HTTP extension is enabled, the server can request the credential from the client directly using the same connection opened in (3).
* is enclosed in `>` and `<` and P2P HTTP extension is enabled, the server can request the credential from the client directly using the same connection opened in (3) exactly as above.

Note that if a client uses a P2P Connection to fetch a `>/cred1<` Credential and the client is authenticated with a `did:key:23dfs` then the server may be able to store that Credential at the `did:key:23dfs/cred1` URL in its cache. (todo: think it through)

### Linking a WebKey to a WebID

Expand Down