Signing HTTP Messages (henceforth HTTP-Sig
) is an IETF RFC Draft that has been developing since 2013 for signing and authenticating HTTP messages. It has the advantage of being very simple and being specified directly at the HTTP layer. As a result there are a large number of implementations, and is already widely used (todo: link).
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). This string must enable the server to look up the key. How this is done is not specified by the protocol.
The protocol allows the key to be interpreted as a URL, and so the proposal here is to use an https
URL identifier ending with a fragment for the keyId
. In order for a server to discover the key, it can simply 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).
The addition to the HTTP Signature protocol made here can be illustrated by the following Sequence Diagram:
Client KeyID Resource
App Document Server
| | |
|-request URL ------------------------------------------------------>|
|<-------------------------------------- 401 + WWW-Auth Sig header---|
| | |
|-- sign headers+keyId---------------------------------------------->|
| | initial auth|
| | verification|
| | |
| |<----------------------GET keyId---|
| |-return keyId doc----------------->|
| -verify sig |
| -verify wACL|
| |
|<-------------------------------------------------answer resource---|
The addition to the HTTP signature protocol is the request by the
resource server for the keyId document
.
Note: If the key document is local to the Resource server, the
protocol is indistinguishable in terms of requests to the current HTTP-Sig
specification.
The keyId
is a URL that refers to a key.
An example key would be:
https://bob.example/keys/2019-09-02#k1
The URL without the hash refers to the keyId
document,
which can be dereferenced, so in the above case it would be
https://bob.example/keys/2019-09-02
The KeyId document must contain a description of the public key in an RDF format. If we were to use the cert ontology used by WebID-TLS then this document would need to contain triples such as
@prefix cert: <http://www.w3.org/ns/auth/cert#> .
<#k1> a cert:RSAPublicKey;
cert:modulus "00cb24ed85d64d794b..."^^xsd:hexBinary;
cert:exponent 65537 .
(Other ontologies that could be used:
- The Security Vocabulary
- Any other?)
The WebACL for allowing an agent in possession of a specific key access, can simply refer to it.
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
@prefix cert: <http://www.w3.org/ns/auth/cert#> .
<#authorization1>
a acl:Authorization;
acl:accessTo <https://alice.example/docs/shared-file1>;
acl:mode acl:Read,
acl:Write,
acl:Control;
acl:agent [ cert:key <https://bob.example/keys/2019-09-02#k1> ].
Or instead of listing agents one by one one can use an agent group description:
<#authorization1>
a acl:Authorization;
acl:accessTo <https://alice.example/docs/shared-file1>;
acl:mode acl:Read,
acl:Write,
acl:Control;
acl:agentGroup <https://alice.example.com/work-groups#Accounting>.
The agent Group document located at https://alice.example.com/work-groups
can describe the users in various ways including by keyId
as in this example
<#Accounting>
a vcard:Group;
vcard:hasUID <urn:uuid:8831CBAD-1111-2222-8563-F0F4787E5398:ABGroup>;
dc:created "2013-09-11T07:18:19+0000"^^xsd:dateTime;
dc:modified "2015-08-08T14:45:15+0000"^^xsd:dateTime;
# Accounting group members:
vcard:hasMember [ cert:key <https://bob.example/keys/2019-09-02#k1> ],
[ cert:key <https://candice.example/clefs/doc1#clef> ].
We can think of current HTTP Signature implementations as using Web ACL's with only locally defined keys.
This goes beyond authentication, but can be integrated very simply in a number of ways.
The simplest way is for the WebID document to be the same
as the KeyId document. For example Alice's WebID
and keyID
documents
could be https://alice.databox.me/profile/card
and return
a representation with the following triples:
<#me> a foaf:Person;
foaf:name "Alice";
cert:key <#key1> .
<#key1> a cert:RSAPublicKey;
cert:modulus "00cb25da76..."^^xsd:hexBinary;
cert:exponent 65537 .
Todo: how does one deal with keyId
documents that are different
from WebID
documents?