Add asymmetric auth provider
- Dominant language
- Go
- Stars
- 9.5k
- Forks
- 1.2k
- PR merge metrics
- No merged PRs in 30d
Description
The HMAC authentication provider works great but it would be nice to have some sort of asymmetric authentication.
There are several ways to do this, but the requirements are simple. The client should sign the full request and include a signature performed with a private key known only to them. To verify the request, the server uses the corresponding public key. I will describe three scenarios here:
1) one key per label
This is the simplest model and most closely resembles the HMAC authenticator.
On the client side, the authenticator config would consist of one private key and a signing algorithm.
for example:
"auth_keys": {
"myauth": {
"type":"rsa_oaep_sign",
"privatekey":""
}
},
(alternatively could be a URI for accessing a public key such as file:///key.pem or pkcs11://object=my-key;objecttype=private;pinfile=/etc/ssh/token_pin)
When constructing the request to the server, the JSON message is serialized as in the standard auth case and the auth token is the request signed with the private key.
On the server side, the configuration holds the associated public keys for the requests.
"auth_keys": {
"myauth": {
"type":"rsa_oaep_verify",
"key":""
}
},
And validates the signature with that certificate before accepting the request.
2) Certificate-based
In this case, there is not a 1-1 relationship with authentication keys and authentication providers. Instead, the client can include a certificate in the message and sign the message with the corresponding private key. The server can validate the certificate through any means it wishes (certificate pinning, PKI, etc.)
On the client side, the authenticator config would consist of one private key, a signing algorithm and a certificate.
for example:
"auth_keys": {
"myauth": {
"type":"rsa_oaep_sign",
"privatekey":""
"certificate":""
}
},
When constructing the request to the server, the certificate would be added to the JSON message as an additional parameter so as to be included in the signed part of the message. The augmented JSON message is serialized as in the standard auth case and the auth token is the request signed with the private key.
On the server side, the configuration holds the associated public keys for the requests.
This is just an example:
"auth_keys": {
"myauth": {
"type":"rsa_oaep_verify_service",
"service":"database_lookup"
}
},
In this case, the service would first check the signature of the request using the certificate's public key, then use some sort of validation service to validate the public key.
Validation service
This could be as simple as
- validating that the client's IP matches a SAN in the certificate, or
- validating that the certificate was signed by a trusted certificate authority
This certificate could also be used by the signer to enforce hostname policy.
For example, consider a model where many clients (such as web servers) were previously issued client certificates and these client certificates are associated with the identities of their owners in a database. This database associates each identity with a set of valid hostnames. The certificate could be used as a client identity token in a separate hostname validation service called by the signer.
Contributor guide
Assessment
This issue has not been assessed yet.