I built EnvKey to simplify the process of securely managing API keys, credentials, and configuration.
It provides you with a convenient, end-to-end encrypted ui for managing user access levels and multiple server environments in one place, and makes integration as easy as an environment variable (ENVKEY=p9WYzzHefy33gzgDdvPJ-EKdh4jgBsRBBNerK
) and a line or two of code.
The goal is to help your team avoid sharing sensitive config over Slack, email, or other insecure channels. Its OpenPGP-based encryption ensures that no third party (including EnvKey itself) ever has access to your secrets.
It would be great to get your feedback, and I'd be happy to answer any questions here!
Having lots of duplicated ENV vars in CI, and consequently seeing builds fail again and again when they'd get out of sync is part of the frustration that inspired me to build EnvKey.
I don't think there should be special integration required to use it with any CI platform, including Jenkins... as long as there's a place to set environment variables, you just need to set a single ENVKEY there, and from that point, your CI server will stay automatically in sync.
I will look into the possibility of a KeePass import. Currently, you can import config as key-value pairs to speed up integration with an existing project, so if you can get your KeePass data into this format:
KEY1=val1
KEY2=val2
etc. you could already import and start using EnvKey without much fuss.
Sound cool. Could you give a high level view on how does this exactly work? (I've skimmed the page)
I assume the ENVKEY is some sort of ID or part of OpenPGP decryption key. Where does the actual config come from? Is it stored in encrypted form in some kind of shared service?
EnvKey is essentially a thick convenience/signature verification/web of trust layer on top of OpenPGP. Every user and every ENVKEY (which gives access to either a local dev machine or a server) represents an OpenPGP keypair. As you add/edit config, an encrypted copy is created for each public key that has access to that environment.
The config itself is stored encrypted in EnvKey's servers, and is also backed up to S3 (in a separate region) on every update.
An ENVKEY is one part lookup id and one part OpenPGP passphrase. For example in this one: ENVKEY=QD8zrywsAccdUhLKSqAx-36MWK4hmY8sd9Siw
QD8zrywsAccdUhLKSqAx is the lookup id, and 36MWK4hmY8sd9Siw is the passphrase.
You can see what a raw server response looks like here: http://env.envkey.com/v1/QD8zrywsAccdUhLKSqAx
It contains the encrypted config, the ENVKEY's associated public key, a private key encrypted with a 16-char alphanumeric passphrase (the second portion of the ENVKEY), trusted public keys that were stored and signed by the private key when the ENVKEY was generated, the public key of the last user to update the associated config, and a chain of signed public keys that allows the client libraries to verify that updater's public key back to an initially trusted public key.
For more nitty gritty details on encryption and security, you can read more here: https://security.envkey.com
If you're on AWS, a good solution is EC2 Parameter Store. Paired with KMS, you have encrypted secrets, locked down by IAM user if necessary. Paired with IAM Roles, you don't even have to have a key you manage for secrets access. You can cache a secrets file in S3, using the same encryption mechanism (useful if you want something like a .env.development to pull down). Most complicated part is bootstrapping your app to pull down the secrets, which is true of any secrets management solution you might use.
a tool which pairs well with parameter store is https://github.com/segmentio/chamber/ . it's a nice interface over the awscli commands that save you a lot of typing. definitely worth looking at as it also saves you the hassle of dealing with a secrets file stored in s3.
Thanks for this - I've been wondering about a way to manage environment variables securely within AWS itself. I hate the way that the keys are readily viewable within the Elastic Beanstalk 'Configuration' screen.
EDIT: Looks like Parameter Store only works directly with EC2 instances, rather than with Elastic Beanstalk? Looks like I cannot set up a load balanced environment which can use the same Parameter Store across (potentially) multiple dynamic instances?
EDIT2: Also looks like it is tricky to run multiple sets of parameters which will auto configure the instance depending on its role (i.e. development, staging, production)? I may be misreading the docs though. Must admit that reading the config docs and options makes me lean towards a quicker solution like the OP's EnvKey.
Someone already posted our tool, chamber, that we use to manage secrets in parameter store at Segment. Here is a blog post we published with all the details about exactly how it works:
For your setup, terraform can easily be used for dev, staging, prod with different IAM Roles or AWS Accounts. We separate each in to completely separate AWS accounts.
Not using Elastic Beanstack myself but you can definitely use Parameter Store across multiple dynamic instances, including ECS and Lambda.
Paths are now supported as well, so you could do something like prod/mykey and staging/mykey and set up IAM roles to limit to given environments.
We use it in ECS; we use AWS SDK to read values in and out. As we may launch several containers simultaneously, and hit API limits, we cache it into S3, which is read when container spins up.
Since this is what basically every secret-sharing system purports to do, and the major ones are all FOSS, I'm curious if you could tell me why someone would pay for a new commercial secret-sharing system.
This seems like the classic "OSS is free if you value your time at zero" answer, but I don't think it is wrong.
I think this is the type of tool which I model you as having relatively little need or use for (since you care very strongly about the details and are willing to burn N days on getting e.g. HashiCorp Vault working) and which I would adopt ~instantly rather than trying to again stitch together all of the Ansible scripts required to get Vault working properly.
"So I can give an external Rails contractor all the API keys they need to run the application without also giving them e.g. my payment processor secret key? And I don't have to configure their Macbook to make this happen or explain to them how to use a toolchain to get e.g. passwords out of an encrypted Ansible vault? Done." would be my approximate reaction here.
I'm looking at their integration guide and Vault's side-by-side and trying to model out installing them in a typical boring Rails app. My mental math is "~25 minutes and one deploy, maybe an hour if you want to monkeypatch Rails.secrets" versus "2~3 days, assuming you've already got a well-maintained Ansible All The Things setup running; a capital-P project otherwise."
It's my ambient impression that this would improve secret management at, hmm, 98% of Microconf attendees' shops. My estimate for e.g. software companies which have raised an A round is not lower than 50%.
I would probably be much closer to (my model of) your POV on this matter if I were making the decision on behalf of a company with elevated security requirements or which already had a staffed-up DevOps or security team.
Let me ask a question that is closer to the spirit of what I meant before:
Given that there are already carefully tested FOSS secret sharing systems, why should some other enterprising soul not just host one of them and compete, rather than building a new proprietary scheme?
This is a good question, and believe me, it's an approach I strongly considered.
In the end, I couldn't find a system that would work well as a base for the functionality I wanted to build. If I could have, I would have been all over it, but it would have required compromises to the simplicity and convenience of the service that I didn't want to make. No secret store that I know of is designed in a way that would make it scalable as a saas service like EnvKey without heavy retrofitting.
EnvKey's main focus is on convenience and speed of integration.
- As a hosted service, it offers a ~5-10 minute integration workflow, and doesn't require setting up/maintaining your own secrets server.
- Pulling secrets/config into an app is extremely simple vs. existing open source solutions. You set a single environment variable, add 1-2 lines of code, and you're done. There are a lot fewer hoops to jump through.
- It has a UI that makes it convenient to manage different environments (development, staging, production) right next to each other, and provides a quick visual overview of developer and server access levels. It also offers some other useful capabilities like YAML-style inheritance between environments and quick/secure invitations for collaborators.
In my experience, there are a lot of companies out there who are managing secrets poorly (email, Slack, Google Docs, etc.), but don't necessarily have the capability or desire to make a major DevOps investment in improving the situation. EnvKey offers a much quicker option.
As a side note, while EnvKey's server is not open source, the app and client libraries are all MIT-licensed, and they are designed specifically not to trust the server.
In the same vein, why should the client be closed sourced at all?
I skimmed through the source of the npm package and see that it's a shim for a binary blob for each target environment (linux32, linux64, windows, etc). It's 8MB per platform and the tarball has all the other platforms there as well so there's 52MB of junk added to each app build:
All the clients (including the app) are fully open-source. Both the npm package and the ruby gem wrap a lower-level library that is written in Go - https://github.com/envkey/envkey-fetch. This implements core OpenPGP logic in a cross-platform way. I'll try to make this clearer in the Readme.
I could also look at splitting out platform-specific packages for those who only need a subset of them, but the reason for including every binary is to make it plug-and-play for multi-platform teams.
> every secret-sharing system [...] and the major ones are all FOSS
Can you recommend a specific one? I'd like to integrate a secret-sharing system into my personal set of computers and applications.
In case you are wary of giving recommendations, perhaps you could just list the top three instead. But ideally I'd like to have a specific recommendation. Also, if said secret-sharing system is written in rust an is available as a library I'd be extra super happy.
Having just said that, I decided to do a search on crates.io. https://crates.io/search?q=secret. It seems that at least a couple of those are about the thing that we are talking about here.
The short/salty answer: EnvKey's app and client libraries are end-to-end encrypted and open source so that you don't have to trust our servers with your data.
The longer answer:
I run EnvKey - https://www.linkedin.com/in/daneschneider, along with help from a small marketing team and OpsZero (https://www.opszero.com/), a Kubernetes-focused devops consultancy that has worked with several YC companies. I've worked as a developer/consultant for a long time for various startups and agencies, both in the US and, for a 2-year stint, in Australia.
My most recent job was at GiveLively (https://www.givelively.org), a startup/foundation that builds payment integrations for non-profits and other charity-related apps and tools--they were also EnvKey's first beta customer.
Sorry. I'm really not sold that this is suitable for applications to use.
The core problem to secrets management is service identity. Managing encrypted data is not hard, it's actually really easy. It's the identity that is hard.
You're just trading out all of my secrets for a new secret. This works for password managers because I remember one password, but doesn't work for applications because you still end up with this env key baked in to source code...
You're right that the ENVKEY still needs to be protected. There is no getting around the need store and protect some sort of key.
You definitely should not be keeping it in source code--it should be set in a gitignored .env file (in development) or as a server environment variable (in staging/CI/production).
It's true that you are essentially trading out multiple secrets for a single one, but there are a number of major benefits to doing this, both for security and ops.
1 - It's much easier/quicker to cut off access.
2 - It's much easier/quicker to rotate secrets when they need to change.
3 - It makes it trivial for developers and sys admins to get access to the latest secrets so they don't resort to sharing over email, Slack, etc. in order to get their work done.
4 - You don't have to worry about keeping secrets in sync when they're stored outside of source control. In my experience, this is a frequent cause of bugs, and it slows down development.
I would also have to disagree somewhat that managing encrypted data isn't hard. Just encrypting data and sending around public keys isn't particularly hard, but unless you are implementing your own web of trust logic to verify that public keys are authentic, you are leaving yourself open to all kinds of man-in-the-middle attacks. EnvKey does the hard work on this.
You're just moving the problem around... Access isn't "cut off" by revoking an env key. The actual secret has not changed.
I think, just like vault, this is missing the point wrt secrets management for services. Sorry to be the negative nancy but this is something I've spent a lot of time on and feel pretty strongly about.
I see your point, but using EnvKey also removes storing plain text copies of secrets as a default step in the workflow, so after you revoke an ENVKEY, it's a lot less likely that copies are still floating around. Of course, in the event that you're worried about this, you still need to assume that copies could have been made, so you still have to rotate any secrets that could have been exposed. EnvKey makes that process a LOT faster as well, and speed can be crucial in the case of a compromise.
In short, while EnvKey doesn't solve every conceivable issue with managing secrets securely, and still requires some common sense, I think it does offer a drastically better default workflow for companies that are currently sharing secrets on email or slack, keeping them in git, etc.
One problem I see this solving is passing ENV vars between developers. Teams I've been on usually kept them in a google doc or emailed/slack'd them around. If I was on vacation when a new API key got added or an old one changed, sometimes I'd have a difficult debugging day ahead of me.
we have a git repository that uses git-crypt for that. in there I can find all the credentials we need as developers and only someone whose key was added can unlock it. you still need to pull changes of course but it has made our lifes a lot easier for development.
I personally like the idea and will try it out for my private projects but this would probably not be possible to be used by the company I work for because we'd give everything to a third party.
Maybe you should think about a self-hosted solution in the future, that might increase the audience.
Yes, that's understandable. To be clear, all config is end-to-end encrypted, so EnvKey's servers cannot see any configuration in plaintext. The native app and the client libraries go to great lengths to avoid trusting the server on anything crypto-related.
That said, a self-hosted version is in the works--the backend is based on Kubernetes has been designed with portability in mind. It won't be a difficult process to set it up on-premises or in a private cloud. For anyone who would be interested in self-hosting, definitely reach out and we can figure out a setup that will work for you: dane@envkey.com
There are some interesting points in this piece, but if you can't trust a binary that is executed as a subprocess, you have much bigger problems.
I also don't think it's true that developers aren't expecting secrets to be stored in the environment. If anything, this is exactly where they expect them to be stored. Maybe things were different a few years ago.
In the end, I want to meet people where they're at. If accessing secrets is difficult or unfamiliar, then many won't use any secrets manager, which leaves them much worse off.
Is it reasonable to use it for production environment? I've got set up a few servers on Google Container Engine and trying to figure out what's the best way to manage ENV variables and this tool seems like a good fit.
Yes, it's been through a several-month beta period and is now production ready. It's running a high availability, multi-az Kubernetes architecture, and encrypted config is also backed up to S3 in a separate region for additional redundancy.
Definitely give it a try :) Feel free to reach out to me directly with any questions, feedback, concerns, etc.: dane@envkey.com
It actually started out as a web app, but the web as a platform is unfortunately not at the point that it can be relied on for zero-knowledge encryption.
In short, the goal is to not have to trust the server, but if the server is delivering you javascript and html, there's no way to avoid trusting it.
Browser extensions are another problem--there's no way to block a browser extension that has been given page-level permissions from reading the DOM, so managing secrets in your browser means implicitly giving access to a lot of different third parties if you use extensions.
I was part of the Beta when it actually was a web app. The reason I was told for switching to a native app was that it's much easier to secure a native app vs a web app. I think browser extensions are one of the big reasons for that.
- EnvKey runs as a hosted service, so it doesn't require setting up or managing your own secrets server. A self-hosted version is in the pipeline, but I thought there was a need for something lighter-weight than Vault for teams that want to secure API keys and credentials without a major DevOps investment.
- EnvKey comes with a UI that makes it really convenient to manage development, staging, and production versions of secrets and config right next to each other. It also offers some useful capabilities like inheriting between environments YAML-style.
- EnvKey's integration story is much simpler. Using bash, for example, this is all you need:
ENVKEY=ZeyyAM4S2EJ3PWUvK652-5awRZi1wVwFSsh1S (in a gitignored .env file in development, or an environment variable)
eval $(envkey-source)
And now all your secrets/config are available as environment variables.
- For now, EnvKey is especially focused on application-level secrets and config, and less on OS-level secrets like SSH keys, ssl certs, etc.
I built EnvKey to simplify the process of securely managing API keys, credentials, and configuration.
It provides you with a convenient, end-to-end encrypted ui for managing user access levels and multiple server environments in one place, and makes integration as easy as an environment variable (ENVKEY=p9WYzzHefy33gzgDdvPJ-EKdh4jgBsRBBNerK ) and a line or two of code.
The goal is to help your team avoid sharing sensitive config over Slack, email, or other insecure channels. Its OpenPGP-based encryption ensures that no third party (including EnvKey itself) ever has access to your secrets.
It would be great to get your feedback, and I'd be happy to answer any questions here!