Secret Management with Vault
chairnerd.seatgeek.com
chairnerd.seatgeek.com
I use it to hold all my LetsEncrypt certs, my private keys get stored in Vault and I never have to expose them even to myself. I created the NodeJS package ten-ply-crest [0] (expressjs middleware) to handle this for me [1], using indutny/bud [2] as the TLS terminator with SNI.
[0]: https://github.com/nextorigin/ten-ply-crest
[1]: https://github.com/nextorigin/ten-ply-crest/blob/master/src/...
https://www.vaultproject.io/docs/auth/aws-ec2.html
But it's all in my head and I haven't gotten around to planning this out. It looks like once the initial trust is granted then hooking up consul template and chef is pretty straight forward. At least, that's what I got from Seth Vargo's post on using Chef and Vault.
https://www.hashicorp.com/blog/vault-cubbyhole-principles.ht...
I prefer the "pull" model, it can be done with a few lines of code in the CD process: First from the deployer to authorize a new instance, and second on the app/instance to request the token.
Regarding machine- or user- oriented, it just depends on whether you trust the deployer (user) or the deployment machine to authorize a new temp token.
No. No. No. No. No. No. This should NEVER be an option. You should not allow data to pass unencrypted over the wire, period.
TLS is not the only game in town.
We're extremely aware that this isn't ideal, and is more or less the first thing we're working on fixing. It's why we have this listed both under "Causes for Concern" and "Strategic Improvements". The order of those issues isn't done so by importance :)
[0] https://www.washingtonpost.com/world/national-security/nsa-i...
Practise: Always encrypt. Aw wait... what do you mean "tls is not supported?" Are you saying that half of our applications have been running on bare HTTP for years?. Mehhhh. Well, all our public accessible websites are running on HTTPS, right? Right. Guess it's only half a disaster after all:(
That mirrors our thoughts exactly - also would be great to hear about some of your tooling! - though at the moment there didn't seem to be a pressing need to move to the AppRole workflow. Our usage would be fairly similar if we did move, so I assume that we'll be revisiting this once it becomes clearer as to how we can better take advantage of AppRole.
I've been very pleased with vault, our biggest hurdle has been working out the TLS fun, vault TLS certs from the PKI backend expire in ~ 32 days, but vault is a long-running service, you don't really want it restarting and having to re-unseal all the time, so we have our own CA out on disk, and vault's PKI holds an intermediate cert. This gives us the ability to generate long-term certs for stuff like vault, but still use vault's PKI infrastructure for most TLS certs, while only having to keep track of 1 CA cert internally.
Yep, thats more or less what we're planning on doing. The documentation released was the result of the initial deploy. We prototyped integration with a few different areas of our infra, and are at the point where we'll be making strategic improvements as we rollout the integration everywhere.
In the interest of being fully transparent, the engineer in charge of the project listed as many issues - small or large - with their initial implementation so we could figure out how to prioritize each one before moving forward.
We used this https://jamielinux.com/docs/openssl-certificate-authority as a guide to get that all going. Good luck! otherwise awesome write up. I wish we could share more of what we do internally, but it's complicated.. getting permission! :)
Good luck on getting permission! I'll be on the lookout for when you can post this stuff :)
How do people handle refreshing secrets on servers which maintain a connection to a database once their creds expire?
I look forward to other answers though, if anyone's currently set this up. I haven't used it yet myself, but I've been considering it.
In that situation I would check out periodic tokens[0] since they live as long as they're renewed within the TTL.
0. https://www.vaultproject.io/docs/concepts/tokens.html#period...
If you are able to change your application's code, you could integrate with vault's API directly which is the most clean solution. If you are unable, you can use [consul-template](https://github.com/hashicorp/consul-template) or [envconsul](https://github.com/hashicorp/envconsul) to securely introduce your secret which would entail reloading/restarting your application.
TOKENS however do get killed at the end of their TTL. But you can renew tokens forever if you allow for that.
Integration with a CI bot is another consideration.
A big reason was that Vault’s AWS authentication backend is not based on AWS infrastructure like IAM/KMS, but uses a somewhat backhanded method (https://www.vaultproject.io/docs/auth/aws-ec2.html) to establish verify an EC2 instance. We use ECS, and it doesn't play well with it - see https://github.com/hashicorp/vault/issues/1298
Instead, we would have had to fall back to the App ID method, which requires separate configuration, and is “Trust On First Use” so doesn’t offer as strong of security guarantees in my opinion.
Also, the only Hashicorp supported-backends are file (non-HA) and Consul.
If you're all-AWS, I'd recommend checking out Confidant/Knox (run as a separate service) or Credstash/Biscuit (run directly against AWS infra).
- Azure Key Vault: https://azure.microsoft.com/en-us/services/key-vault/
- Blackbox: https://github.com/StackExchange/blackbox
- CredStash: https://github.com/fugue/credstash
- Lyft Confydant: https://github.com/lyft/confidant
- Trousseau: https://github.com/oleiade/trousseau
- Sneaker: https://github.com/codahale/sneaker
Some of these didn't exist when we were first investigating proper secret management, while others didn't fit as well with our deployment strategy. We're using what works when it makes sense - Blackbox is used in some repos, for instance - but I'll be sure the next time we have an internal doc like this that we cover why we didn't choose a different set of tools.One thing we liked about Vault is that it built upon our usage of Consul and the http interface for Vault meant it was simple to plug into how we build and deploy services. While I'm sure some of these other tools would have had as good workflows, our experience in administrating Consul made it easier for us to have confidence in Vault.
Because every operation with Vault is an API request/response,
the audit log contains every interaction with Vault,
including errors.
The data...will be hashed with a salt using HMAC-SHA256.
The purpose of the hash is so that secrets aren't in
plaintext within your audit logs. However, you're still
able to check the value of secrets ...by using the
/sys/audit-hash API endpoint
Does this not cover your use-case?For security reasons it doesn't include raw secrets, but the hash is enough to tell you if it matches some known value.
Funny enough, so do we. We actually use both Vault and Blackbox for building out our BaseAMI, though for different purposes depending upon the nature of what is being encrypted.
One thing I like about Vault is that it allows us to rotate keys without needing to rekey all encrypted secrets. Being able to expire certain secrets - like database credentials - means we can rotate these at will without needing an extra git commit.
I highly recommend using something here, and I commend you for at least encrypting with blackbox :)
im not a security expert, so im wondering whether vault encapsulates security best practices to store lots of sensitive data in production
Works well for me.
Definitely worth looking at solutions from the hosting platform you're infrastructure is on. In our case, we don't use Azure, so going across the net for secrets was less than ideal.
That said, if you're in Azure, it's certainly the easiest way to go, and definitely not a bad approach.
Firstly, it doesn't actually manage credentials for you (other than with AWS, a bunch of databases, and a few other things). It's not going out and logging into your 10s of thousands of Linux hosts making sure all the root passwords are vaulted, unique, and must be checked out before use. This is where products like CyberArk's come in (we use CyberArk and it's crap to be honest; it doesn't scale, its API is broken--REALLY broken--and its architecture is some of the worst junk I've seen in years and that's just scratching the surface of how bad it is!).
Another problem with Vault is that it exposes too much information about the secrets via their URL/path. This is a very minor concern of mine and probably shouldn't impact your decision to use the product but here's what I'm talking about: The article author says that they're going to use this model for their paths:
http://<vault>/secret/ENVIRONMENT/APP/KEY
Here's my problem with this: If any configuration information is ever exposed an attacker will know that this application is part of ENVIRONMENT and has access to the keys for APP. If the host or container running this application were compromised this isn't really of concern since the attacker will probably be able to figure these things out anyway but my concern has more to do with configuration management systems. It's easy to imagine the ability to map out who-has-access-to-what in the vault just by examining their configurations.It's the difference between a config file with this:
"secret_url": "http://<vault>/v1/secret/ENVIRONMENT/APP/KEY",
"certificate": "/path/to/vault/client_cert.pem"
...and this, my preferred way (I split the vault_url and secret below just to save space since indented lines don't get wrapped on HN): "secret": "2a9ac85d-f6f1-4ef5-8d36-65331708623a",
"vault_url": "https://<vault>/api/v1/secret/{secret}",
"credential": "whatever" // I'd support multiple auth options
The latter doesn't give an attacker much info at all about what that credential is. Even if they're able to retrieve it all they'll get back is, "<the secret>". "Great, now what do I do with this?"How I would do things different:
* Secrets may only be accessed via their unique (e.g. UUID) object identifier. This means that if you want the credential for ENVIRONMENT and APP you must have the object ID. It cannot be inferred by the path.
* Access to credentials will be controlled via attributes (extra keys/values attached to the same record as the secrets). This is mostly standard attribute-based access control (ABAC) with one exception...
* Attributes can exist in namespaces that are controlled via independent groups. So you can imagine an internal team controlling namespace FOO and attaching `{"foo.admin":['userx']}` to the secret record for X. So if the FOO team wants to grant admin access to their app they can add a user (aka a subject) to their little "foo.admin" attribute on that particular secret. The point being that the FOO team doesn't need to open a ticket with the one true attribute authority (i.e. traditional ABAC) they can make the change themselves; the whole thing would be entirely self-service. There's zillions of ways to handle namespaced attributes like this but I personally prefer to just stick them right in the secret record itself and control access at the application layer.
At my current employer I've been tasked with writing a vaulting and management application from scratch because nothing in the market will suit our needs. We (me specifically) tried really hard to avoid this situation but it seems that nothing that exists currently can do everything. Most notably:
1. Sane architecture (i.e. something that doesn't send all its
logs to the same database as the secrets and doesn't run on
Windows, gahh! Among other things)
2. Secure vaulting of secrets (aka "dumb vault")
3. Can *manage* credentials for various platforms
4. Provides a user interface for "checking out" secrets
Hashicorp Vault does a great job with #1 and #2 but it doesn't do #3 or #4. We had initially planned to use it as a "dumb back end" for a custom system but it didn't work out for reasons that have nothing to do with faults in the product. That just isn't really what it was meant for.For reference, here's some of the problems we had with Vault that most won't run into:
* Uses its own Certificate Authority (my employer only allows
*one true authority*, sigh).
* Written in Go which isn't approved.
There were others as well but they were mostly bureaucratic.Note: In theory Hashicorp's Vault can do full credential management for anything but at this point in time it does not support writing your own custom back-ends. That feature is essential for managing zillions of disparate and possibly proprietary systems. For example, say you wanted to manage admin/root credentials for all Unix-like OSes at your company. All you'd need is a generic SSH back-end that can be scripted (e.g. expect or state machine scripts like CyberArk). Why they haven't added this is beyond me.
The vault we're writing at my employer is actually pretty damned awesome and innovative. I wish I could share more about it but I can't. I'm pushing to make it open source but that probably won't happen.
As for #3 and #4, you can write tooling around vault using the generic backend to store the data to accomplish both of those things.
In our setup, credentials are stored in namespaces, which is equivalent to adding an attribute to the credential and having that attribute be namespaced.
I'm not quite sure how this helps anything except adding an extra level of indirection for both operators and users, but I'm definitely interested in learning more.
[nit] Token Management