Venafi / vault-pki-backend-venafi

Venafi PKI Secrets Engine plugin for HashiCorp Vault that enables certificate enrollment using Venafi machine identity services.
Mozilla Public License 2.0
54 stars 20 forks source link

Venafi role is missing allow_glob_domains feature #102

Closed dune-fan closed 1 year ago

dune-fan commented 2 years ago

BUSINESS PROBLEM

We have many thousands of services, each with different subdomains, that are reading their certificates from Vault through the venafi-pki plugin.

Currently, we limit access to issue new certificates with a policy path such as:

venafi-pki/issue/*.domain.com

However, because of the amount of services that could be restarting at any given time, we have a vault-agent config that checks for certificates existing first on the venafi-pki/cert/ path, and if they don't exist then the venafi-pki/issue/ path will be targeted for issuing a new one.

This is needed, because at any given time we could be generating thousands of new certificates otherwise, which we want to avoid because of the costs associated with issuing that many new publicly signed certificates.

In order for our services to read existing certs from venafi-pki/cert/ however, we are using a wildcard policy path:

venafi-pki/cert/*

This is a problem, because it means that any service with read access on that path can request any certificate that currently exists. In order to limit access using the current existing features in the venafi-pki plugin, we would have to have policies for each specific subdomain:

venafi-pki/cert/example-1.domain.com
venafi-pki/cert/example-2.domain.com
venafi-pki/cert/example-3.domain.com
etc...

However, because of the amount of domains that certificates will be issued for, managing thousands of subdomains in our policy list isn't feasible. We want to have policies such as:

venafi-pki/cert/*.domain.com
venafi-pki/cert/*.domain-2.com
venafi-pki/cert/*.domain-3.com

This would allow us to limit read access by domain, and allow us to have a much smaller more manageable policy set.

PROPOSED SOLUTION

The Vault PKI engine has a feature called allow_glob_domains, that allows for domains to contain glob patterns, such as ftp*.example.com or *.example.com.

The role in venafi should have the alow_glob_domains boolean flag added to pki/path_roles.go, and the ability to have wildcards in the paths added topki/path_venafi_cert_read.go based on this role flag.

The result should be that the following policy paths should be valid:

venafi-pki/cert/*.domain.com
venafi-pki/cert/*.example.domain.com
venafi-pki/cert/ftp*.domain.com
venafi-pki/cert/example.*.com

CURRENT ALTERNATIVES

In order for our services to read existing certs from venafi-pki/cert/ we have to use a policy path like:

venafi-pki/cert/*

This will, however, not pass our audits. In order for us to pass auditing, we would have to specify each subdomain explicitly:

venafi-pki/cert/example-1.domain.com
venafi-pki/cert/example-2.domain.com
venafi-pki/cert/example-3.domain.com
etc...

But, due to the amount of certs we have at any given time, scaling up our deployment won't be possible. This will soon become a blocker for us deploying more services onto this venafi+vault workflow.

VENAFI EXPERIENCE

👍

amkhan1978 commented 2 years ago

Any update on this request

tr1ck3r commented 2 years ago

@dune-fan thank you for your very detailed submission 😃 and apologies for the delay in replying @amkhan1978. We've been coordinating with your Venafi account team since your organization has been directly engaged with them and are having ongoing discussions.

We think we have a good understanding of what you are trying to accomplish but there's still a chance we may not have a complete picture. Unfortunately, we don't believe the allow_glob_domains setting would be a viable path forward. That setting is a role parameter which means it influences the behavior of certificate requests but has no bearing on access to already issued certificates. In order to get the behavior as you've described, we believe that HashiCorp would need to enhance the Vault policy syntax to allow glob patterns more generally, rather than only as the last character of the policy path as it does currently.

We see that you would also need to rely on our store_pkey setting for the usage you've described, however, you've touched on one of the main reasons we consider that feature to be "experimental". There is currently no way to limit access to private keys if someone has access to retrieve certificates using the GET /pki/cert/:name endpoint.

HashiCorp has recommended using a KV (key-value) secrets engine rather than relying on their PKI secrets engine for persistent storage of private keys (which it doesn't support). We believe you could accomplish your goal by following this usage pattern (i.e., request a certificate from the Venafi secrets engine and immediately store the result in a KV secrets engine where it would be available to retrieve again later) because you can apply policy ACLs to restrict access to specific users/teams.

Ultimately, it seems relying on Vault for persistent storage of certificates and their private keys is suboptimal since it effectively duplicates functionality of TPP. Instead of querying Vault to see whether a valid certificate already exists for the one that is needed, a client could simply make a request for the certificate it needs and get back either a new certificate or an existing certificate if TPP has one that matches the request and is still valid. You would then leave store_pkey set to false and eliminate any risk of unauthorized users being able to access private keys (assuming you still have the policy ACLs you described applied to the roles). The functionality to "reuse" an existing certificate can be accomplished using the TPP REST API but does not yet exist in the VCert client library so that enhancement would be a prerequisite here.

tr1ck3r commented 1 year ago

This use case was addressed by v0.10.5