bloomberg / vault-auth-spire

vault-auth-spire is an authentication plugin for Hashicorp Vault which allows logging into Vault using a Spire provided SVID.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ownership of X509-SVIDs are currently unknown

dennisgove opened this issue · comments

Background

Authentication using X509 SVIDs is a three-step process.

  1. Prove client logging into Vault is the owner of the X509-SVID being passed in.
  2. Prove the X509-SVID was generated by a trusted source.
  3. Use the SPIFFE ID to generate a list of policies to apply to the session.

Step (1) occurs during the initial TLS connection between the client and Vault. The mechanisms of that connection result in the verification of the public X509-SVID certificate against the private key used to generate it. If that TLS connection can be made then ownership of the X509-SVID has been proven.

Steps (2) and (3) occur during the execution of this plugin. The plugin receives the X509-SVID certificate (and peers) via logical.Request object passed into the login/renew methods. The X509-SVID can then be verified against known trust sources using spiffe.VerifyPeerCertificate.

Problem

I've discovered there is a problem with this plan stemming from a faulty assumption. It appears that not all of the original TLS connection state is passed to plugins. Here, here, and here show that only the remote_addr is passed from Vault proper into Vault plugins. The faulty assumption stems from my original review of the existing built in TLS authentication method. Seen here this auth built-in plugin uses the peer information in its execution and I incorrectly assumed this information is available in all plugins. In fact, it is not if Vault interacts with the plugin via gRPC (which is the standard communication mechanism for non built-in plugins).

If the X509-SVID is not passed into the plugin via request.Connection.ConnState.PeerCertificates then the ownership of that certificate cannot be guaranteed, thus invalidating step (1).

Path Forward

It appears (though I have not confirmed) that the lack of additional TLS connection information passed to plugins is merely a result of "hasn't been added yet" and not "the information cannot be passed for reasons". If this is true then technically it would be possible to enhance Vault to pass such information to plugins. But, such an action expands the scope of this specific plugin and adds a version dependency. So this approach should not be taken lightly.

It may also be possible to instead enhance the existing TLS authentication built-in to support the usage of SPIFFE IDs. As far as I can tell (though I haven't dug super deep yet) the policies applied to the login/token are passed in as part of something with the certificate. I don't think this approach works well with our use-case (as it may require adding Vault logic to the generation of the certificate, which IMHO should be avoided). Instead, I'd like to find a way to use the SPIFFE ID contained in the certificate to generate the list of policies to apply to the login session.

Is there a way to do a manual TLS challenge between the client and vault after the TLS connection has been initialized? The client could send along the SVID, and Vault could ask the client to complete a TLS challenge on the SVID.

I don't believe so as the plugin does not have the original TLS connection from the client. What it does have is the TLS connection from the Vault server to the plugin, but it doesn't have access to the connection from the client to Vault server. Non built-in plugins run as discrete processes and are not loaded into the Vault server process.