Most applications require secrets, for example to connect to a database, communicate with another application using tokens or certificates, define an admin password…
Dealing with this is often a headache. Even when you have a proper secret management tool, it's sometimes a nightmare to inject the secrets into the application where it needs to be used.
The 4 ways
First way: build time
This is probably the worst way to do it.
Examples:
- Build a WAR file, or a Docker image or any artifact with a configuration file that contains the secret in plain text.
Pros:
- Your deployment tool does not need permissions to decrypt the secrets.
Cons:
- Your whole artifact becomes a secret;
- You have to rebuild and redeploy when you want to renew a secret.
Second way: deploy time
Examples:
- Give a Continuous Deployment pipeline access to a secrets store an let it inject the secrets in the application's configuration files;
- Give a Continuous Deployment tool, like ArgoCD, access to a secrets store an let it inject the secrets in the application's configuration files.
Pros:
- You don't have to rebuild when you want to renew a secret.
Cons:
- Your deployment tool needs permissions to retrieve and decrypt the secrets;
- You have to redeploy when you want to renew a secret.
Third way: start time
Examples:
- Use Kubernetes Secret Store CSI drivers to inject secrets as volumes or secrets;
- Use HashiCorp Vault as a secret store and Vault Agent Injector as an init container to create configuration files before the application starts.
Pros:
- Your deployment tool does not need permissions to decrypt the secrets;
- You don't have to redeploy when you want to renew a secret.
Cons:
- You need to restart your application when you want to renew a secret.
Forth way: run time
Examples:
- AWS instance profiles;
- HashiCorp Vault as secret store and Vault Agent Injector in sidecar mode.
Pros:
- You can renew your secret without even having to restart your application, allowing a dynamic secrets mechanism.
Cons:
- You probably need to adapt your application (or not if you already use an SDK that supports it).
Conclusion
Do you know any more ways to inject secrets in your applications? Let me know in the comments!
Top comments (2)
I was considering using Vault via the Kubernetes auhtentication method. This way you create service accounts, and associate them with a vault role. Your app uses the JWT generated inside the container to authenticate against vault, and then you can fine grain the permissions for it using Vault policies. I was wondering if someone else is using this method and has some feedback about how secure/good it is :-)
Yes, we are currently starting using it either with vault-k8s or secrets-store-csi-driver.
I personally love the idea of secrets-store-csi-driver ; it brings an abstraction layer that will allow to use cloud providers' secret store (only Azure Key Vaults for now), or HashCorp's Vault or any implementation that will support this project.