-
Notifications
You must be signed in to change notification settings - Fork 15
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
HttpSig #125
Conversation
thanks :-) Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
HttpSignature.md
Outdated
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. | ||
|
||
We also reserve the use of keyIds enclosed with `>` and `<` characters for | ||
We also reserve the use of keyIds enclosed with `'>'` and `'<'` characters for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This suggests >{keyId}<
which I think is not what is intended.
"Enclosed with" usually enumerates first the prepend and second the append -- so if the intent is (as I believe) <{keyId}>
, this should read
We also reserve the use of keyIds enclosed with `'>'` and `'<'` characters for | |
We also reserve the use of keyIds enclosed with `'<'` and `'>'` characters for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
>{keyId}<
is exactly what was intended! :-)
The idea is that we want a way to say: this is the relative URL for the key, but it is not to be found out there on the internet, but by asking the client for it.
How does one ask the client for it? By using the P2P extension of HTTP/2 referred to, which allows the server to take on the role of a client on the same connection.
Do you think >{keyId}<
would be clearer?
HttpSignature.md
Outdated
* 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). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, I think this probably should be
* 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). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same point as above. Perhaps this is such an unusual idea that it requires more elaboration, perhaps even a picture or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it requires a lexical/literal example, at minimum. If there are other wrapping characters -- whether brackets, braces, parentheses, quotation marks, or otherwise -- which may be used in a more typical manner (the only thing I can quickly think of that uses >…<
wrappers in that order is an ASCII emoticon for a cat, >^..^<
), I would suggest using them instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way I see it is in terms of indexicals eg: I and you. In an HTTP connection of a client C
to a server example.com
, the you for the client is example.com
. The server on the other hand knows nothing of the client so it only can say you
. The client wishes to pass a key to the server but it can say: the key at my house at address so and so, or the key in your pocket, or the key in my pocket. We need to be able to distinguish between "the key in my pocket" and "the key in your pocket".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making such distinction doesn't seem to require any specific wrapping characters. It requires knowing who's "speaking", and to whom -- as the entity to which the possessive "my" or "your" refers changes in meaning with the speaker and the audience. In HTTP, we can speak of the Client and the Server, and describe what action each might be taking (requesting, responding, etc.). In other spheres, we have conventions like Requesting Party, Relying Party, Responding Party, etc., to serve the same purpose.
Sometimes, it's very hard to describe an interaction with generalities, but trivial to describe it through a concretized example. I think this might be one of those situations, at least at this point in the ecosystem's development.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making such distinction doesn't seem to require any specific wrapping characters. It requires knowing who's "speaking", and to whom -- as the entity to which the possessive "my" or "your" refers changes in meaning with the speaker and the audience.
Let us say we start with a connection from Phone to Pod .
Phone requests a secure resource, is returned a 401 by Pod, and then sends the Phone a signed message with a relative URL /auth/Cred1
referring to the Credential . Now that the Pod can turn around and be a client on the same connection, it is possible for it to also use relative URLs to make requests to the Phone, which was not possible before the P2P connection extension. So it is now possible for the phone to send a relative URL to the Pod that refers to the Phone's side of the connection. Relative URLs are relative to a communication.
So we want to allow the following two possibilities to exist:
- the Credential is on the Phone at >/auth/Cred1<
- the Credential is on the server at </auth/Cred1>
The relative path /auth/Cred1
is the same in both cases, so we use the angle bracket reversal to distinguish on which side the URL is relative to the roles at that stage in that conversation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote more about what P2P opens up to the web here w3c/architecture#14
I still want to integrate this into the spec here, but need to be careful not to make too much of it, as what is proposed can also work without it.
Co-authored-by: Ted Thibodeau Jr <[email protected]>
I am learning, slowly ;-) Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
It is a pitty that one cannot link to that OWL2-Primer using a query with say ?turtle=on to show the turtle examples, as readers of this may not know that one has to go to the top to click on "Turtle" to see those. Co-authored-by: Ted Thibodeau Jr <[email protected]>
Co-authored-by: Ted Thibodeau Jr <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀 Did I plant some of this in 2017 ( w3c-ccg/http-signatures#8 ) with an all too simple notation for URL in keyId
? 😄 Generalising it to relative URLs (as you've commented in that issue) and client side resource reference here is great!
Using URL in keyId
was acknowledged to be useful and that the suggestion was to describe the allowed value in a higher level spec. So, this proposal is the right place to reenergise and work this out. It can be defined in general terms and there can also be the Solid-centric bits. I would suggest to make this more clear for extensibility.
There are other relatively minor related considerations eg. whether a new field-name like keyIdType
can indicate what to expect from keyId
: w3c-ccg/http-signatures#3 . This is not particularly needed though if HttpSig
is used to set the method in which the keyId
value would be a URL.
Looking back at earlier work and discussions on Signing HTTP Messages, Authentication was in fact part of the earlier drafts (prior to HTTP Working Group's draft): https://tools.ietf.org/html/draft-cavage-http-signatures ( https://www.ietf.org/rfcdiff?url1=draft-cavage-http-signatures-12&url2=draft-richanna-http-message-signatures-00&difftype=--html ). It makes sense to have separate specs for the Authentication component - essentially the case given in this PR.
Lastly, this proposal is an excellent example of making wider interop possible with the works done by other groups / standards bodies in which the Solid ecosystem can benefit from. The Solid Community Group doesn't need to work out all areas/specs that's tied or dependent on eg. wallets, credential managers, crypto APIs, proofs.. We focus on bridging the layers and get some implementation going. Easier said.. of course.
HttpSignature.md
Outdated
The protocol allows a client to authenticate by signing a number of HTTP headers with it's private key. In order for the server to be able 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 is done is not specified by the protocol. | ||
HttpSig is a simple but very efficient authentication protocol extending [Signing HTTP Messages](https://tools.ietf.org/html/draft-ietf-httpbis-message-signatures-01) RFC by defining — | ||
* a `WWW-Authenticate: HttpSig` header the server can return with a 401 or 402 to the client | ||
* a `Authorization: HttpSig` method the client can use in response with two optional attributes `webid` and `cert` both taking `https` or `DID` URLs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicking: Clarify if only certain URI schemes are allowed. Or if https
is only intended to be for HTTP over TLS (as you've mentioned later in the document).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah yes, WebID would be for https URLs. I actually did not use webid
in the text, as I think a WebID is a form of minimal self signed certificate (and so could be covered by cert
), by the fact that it is located at the URL of its definition...
HttpSignature.md
Outdated
* a convention for how to encode URLs in the `keyId` attribute of [Signing HTTP Messages](https://tools.ietf.org/html/draft-ietf-httpbis-message-signatures-01)'s `Signature-Input` header when used with the `WWW-Authenticate: HttpSig` header | ||
* the ability to use absolute or relative URLs in all places mentioned where URLs can be used | ||
* allow relative URLs passed by the client to the server to refer to resources on the client using a [P2P Extension to HTTP](https://tools.ietf.org/html/draft-benfield-http2-p2p-02) which would allow authentication over a single HTTP connection. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: If the first and third point are specialisations of the second, consider moving the second to first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I starting to edit that, but then I realized that the the point that URLs can be used in the cert
field of the Authorization
header and the keyId
of the Signature-Input
header are more important changes. The relative URL point makes sense only after those have been introduced. But I'll make a few other improvements to that text.
HttpSignature.md
Outdated
|
||
The addition to the HTTP Signature protocol made here can be illustrated | ||
by the following Sequence Diagram: | ||
[Signing HTTP Messages](https://tools.ietf.org/html/draft-ietf-httpbis-message-signatures-01) 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: Not sure if "problem" is the right word here. Perhaps just not a universal solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/problem/challenge/
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Merged Version has
bypassing limitations of client authentication at the TLS layer, related to client certificate renegotiation, and the TLS layer occuring at lower layer of the communication stack.
That text can certainly also be improved. Still the problem that TLS is at the wrong level of the stack, is a big challenge for sure. Given that Chrome dropped token binding, something much simpler to do, it looks very difficult to get movement in that direction.
|
||
It should also add a `Link:` relation to an Access-Control resource which describes which resources might be accessible. | ||
This is described in [Web Access Control Spec](https://github.com/solid/web-access-control-spec/). | ||
(Without such a Link the client would only be able to guess what key to send.) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
HttpSignature.md
Outdated
This is described in [Web Access Control Spec](https://github.com/solid/web-access-control-spec/). | ||
(Without such a Link the client would only be able to guess what key to send.) | ||
Note: 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 known the rules. | ||
It may also be possible to send the ACL rules directly in the body (Todo: research) of the response. |
There was a problem hiding this comment.
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
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. This is a URL that contains in its name all the data of the public key. | ||
* The `keyId` URL refers to an external resource, but the resource server has a fresh cached copy of it. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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:key
s the key comes along with the message.
HttpSignature.md
Outdated
@@ -60,10 +180,12 @@ an RDF format. If we were to use [the cert ontology](https://www.w3.org/ns/auth/ | |||
* [The Security Vocabulary](https://web-payments.org/vocabs/security) | |||
* Any other?) |
There was a problem hiding this comment.
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" .
``` | ||
|
||
As before we reserve the option of enclosing a relative URL in `>` and `<` to refer to a client side resource, accessible to the server using a P2P extension of HTTP (see [Peer-to-Peer Extension to HTTP/2 draft](https://tools.ietf.org/html/draft-benfield-http2-p2p-02)). | ||
(Todo: how else can one pass the Credential?). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not up to speed with the browser APIs... face scan , fingerprint, voice.. Not sure if/how https://www.w3.org/TR/webauthn/ can fit here to pass the credential.
HttpSignature.md
Outdated
|
||
The protocol allows a client to authenticate by signing a number of HTTP headers with it's private key. In order for the server to be able 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 is done is not specified by the protocol. | ||
HttpSig is a simple but very efficient authentication protocol extending [Signing HTTP Messages](https://tools.ietf.org/html/draft-ietf-httpbis-message-signatures-01) RFC by defining — | ||
* a `WWW-Authenticate: HttpSig` header the server can return with a 401 or 402 to the client |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bikeshedding: Signature
was used in earlier drafts. We can reuse that or use HttpSig
(or another name) to be specifically URL-based / Solid-centric?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had forgotten that the draft-cavage had a Signature
header for authentication. I'd be happy to use that too, but don't want to step on toes in case the intent is too different. Perhaps @msporny has a view on that?
Co-authored-by: Sarven Capadisli <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm late to the game here, but I wanted to signal my +1
Extending the HTTP-Sig authentication IETF HTTPbis work to take into account WebIDs and the Self Sovereign Identity ecosystem with Verifiable Credentials and support for DIDs.
The text is a bit longer than essentially needed in order to help people who are new to Solid understand our use case.
In short it adds the following:
WWW-Authenticate: HttpSig
method for the server to let the client know it understands HttpSig method of authenticationA credential can be pointed to by the client passing a
cred
attribute to theAuthorization
header like this:Authorization: HttpSig cred="<https://alice.freedom/cred/BAEng>"
Again the URI for the credential can be a
https
URL, a relative URL pointing to the server or to the client using the P2P extension to HTTP.A major advantage is that it ties in nicely with the Self Sovereign Identity philosophy of putting the authenticating user at the center of authentication decisions.
It also has a major technical advantage in that optimally it can allow authentication over a single connection, when using the P2P extension to HTTP.