I have an application that needs to pull Vault secrets when it is deployed (started for the first time). It is deployed using Puppet Bolt from a trusted host.
The application have its own secret engine in Vault.
Would it be possible from the trusted to run Puppet Bolt, have it prompt for Vault LDAP username and password, get a read-only one-time token for this application?
This way I could have Puppet Bolt send the one-time token to the application host, and the LDAP username and password would never be available on the application host.
Basically you could have Puppet Volt retrieve the secrets needed to start your application and then wrap the secrets in a single use token.
Puppet Volt would then drop the token on your app server which would then need to unwrap the secret contents and use the contained data to start the application. (Supposedly you do not need a role for the target to authenticate to Vault for this to work. I’ve, personally, not been able to get this to work consistently without having a generic role that only allows unwrapping of these tokens, but I may not be doing something quite right. If needed, an AppRole with very limited permissions can be provisioned for this task.)
This assumes your Puppet Bolt instance has an appropriate role and permissions within Vault to perform the various required actions (retrieving the needed credentials specifically, as the ability to wrap secrets is part of the default default policy).
I think it depends on what you’re ultimately trying to accomplish.
The response wrapping is good for passing secrets to systems that aren’t easy to integrate authentication with Vault or to pass secrets to a system that doesn’t have direct access to the secret(s) within Vault.
I’m also making some assumptions about your use case that may not be valid, so it may be helpful to provide a little more detail around your scenario.
My first assumption is that when you’re referring to Vault LDAP you are referring to Vault’s LDAP authentication method (as opposed to Active Directory or OpenLDAP secrets engines or LDAP credentials to be passed to the application).
My next assumption is that the secret the application needs is mostly static and needed only at application startup. The secret is unlikely to change while the application is running and therefore you don’t need to renew or re-retrieve the secret until application restart.
Next I’m assuming your application server does not have an existing auth method/role setup for Vault (e.g AppRole or AWS/GCP/Kube login). However, your Puppet Bolt server does have an established authentication method configured.
I’m not entirely sure what the LDAP credentials are used for, is it to authenticate to Vault or used by the application at startup?
If that’s all correct then from what I understand you are looking to do the following:
Puppet Bolt server deploys application to target server
Puppet Bolt server authenticates to Vault
Puppet Bolt server retrieves secret
Puppet Bolt server drops secret on target server - this could be a wrapped token (preferred as it limits potential exposure), the actual clear-text secret, or a single-use token (or AppRole credentials) with a policy that allows reading the target secret(s)
Target server application starts and reads secret (either via unwrapping the wrapped secret, reading the clear-text secret, or authenticating to Vault with the single-use token and then retrieving the secret directly)
If you could confirm/correct the above that would help me, and others, provide a better recommendation.
At this point it doesn’t, but it can get what is needed for the desired solution.
This is the desired setup:
Puppet Bolt logins in to Vault using LDAP auth and gets an one-time read-only token back.
Puppet Bolt sends the one-time token to the app host.
The app login to Vault using the one-time token and gets the plain text secrets back.
The app is a NodeJS app, so I will implement the Vault API directly into the app, so is it the app that contacts Vault with the one-time token. That way the plain text secrets will never be on disk and Puppet will never see the secrets, and the privileged LDAP username+password will never be seen on the app host.
The reason LDAP auth is wanted to get the one-time token is to be able to track who that deployed the app.
To accomplish this with your criteria you’ll need to do a few things:
Create a policy with the required ACLs for access to the desired secret(s)
Create a token role that has the above policy assigned and the token_num_uses parameter defined. You may also want to consider some of the other parameters to further restrict the tokens usage (e.g. what CIDRs it can be used from and a reasonably short TTL).
Update your Puppet Bolt LDAP role policy to create tokens for the “token role” name created above
Once you have those pieces in place you should be able to implement your proposed solution.