-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new encrypted variable without ability to decrypt #189
Comments
with the current implementation, yes, your understanding is correct. this is something i haven't given much thought yet, but one thought is this feature could be made available via a hosted service that holds your keys safely. then a teammate could be granted permission to write without seeing the key (the system/program would see it only) but can you elaborate more on your use case? you mention contributors - are you using it with an open source or closed source repo? on GitHub or somewhere else? are these contributors approved by you or they could be anyone who generates a PR with a patch or something? |
Closed source repo on github, deployed to azure. Updates are all approved. The concern is primarily around contractors who may have temporary access to the repo. If they introduce a new secret, it’s easy to rotate one when they finish, but annoying to rotate all of them. |
There’s also the issue of trusting the engineer’s machine itself. Granted, that’s a larger problem, but using a cloud KMS reduces the affected surface area. |
give
i suppose it is a few steps away from:
|
Seems like an interesting project, but unfortunately this is a sensitive application with rigorous vendor requirements, so another vendor is out of scope at the moment. Basically, if someone has access to the repo, I don’t mind them having access to a credential that lets you encrypt using a KMS, because that’s functionally equivalent to a public key. Therefore, it would be safe to embed this limited credential to Azure in the repo. |
all makes sense, but one further question: dotenvx would have to hold/manage this credential (so it could proxy to the true encryption key) so wouldn't you still be at the mercy of the same vendor requirements? vetting dotenvx as a vendor? |
Do you mean auditing this library? For the purposes of SOC 2 and other credentials, the vendor of third party code isn’t audited as closely as infrastructure, even though the code is risky. For third party code, the risk is mitigated by vulnerability scanners; while for SaaS, the risk is mitigated by one of these certs (which encompasses pen tests, certified vendors, etc). That’s why vetting a new library is easy, but vetting a new SaaS is more difficult. Did I understand your question correctly? |
i'm saying that it's not possible to do this without it being a SaaS. The SaaS (whether a KMS or the current Hub approach) is still a SaaS holding your .env.keys and obfuscating the encryption key to part of your team in some manner. Correct? or are you envisioning some other approach where maybe you store the .env.keys in Microsoft's or AWS's KMS? And dotenvx has a mechanism to fetch them just-in-time, hold them in memory, do the encryption set function on your contractor's machine, and then flush the memory? |
You're absolutely right; it's not possible to handle this key management securely without a SaaS. I was imagining using Azure's KMS (because it's already a vetted vendor with HSMs) to generate a single public/private key per environment. The public key for each would be embedded in the repo and used to encrypt any variables for a desired environment. To decrypt the variables in a given environment, I'd assign a role to the vm with the power to decrypt using the private key assigned to the environment. In this scenario, the plain text I guess I was imagining a simplified version of sops that worked on a per-key basis, and doesn't require a roundtrip to the KMS when adding or updating a variable. |
this is edifying. the current encryption algorithm (AES-256) is symmetric, but an asymmetric approach like you are mentioning could be very powerful and solve your request. the public key like you mentioned could just live in the .env.vault file it does complicate the formatting a bit - since 'encrypting' would actually be encrypting a but.. what i'm not sure how to solve is being able to set/override current keys without things getting kind of messy. it would technically work but would result in a decrypted .env file looking like this:
^ in this case the value is 'Dad' since the last value in a single .env 'wins' i suppose the tool could then provide a any thoughts around all this? |
Interesting. It seems like a ledger of changes could get unruly pretty fast. The problem may be easier to solve if we assume a variable's value is secret, but a variable name is not. This is likely true for most use-cases, because if you have access to the vault file, you have access to the codebase, which references the variables by name. Maybe a It's also ok for this to be out-of-scope for |
arguably yes, but thinking about it again, that also offers a helpful feature benefit - change history.
yes possibly but also possibly just shoving/appending it into the DOTENV_VAULT_DEVELOPMENT variable with some separator between appends. then additionally modify the .env.keys to state the mechanism they are using - algorithm/asymmetric, etc. the keys are in uri format so can take on more metadata/instructions. possibly this is something for the future, but going to table it for now given other priorities. thank you for the chat on this! |
Storing the vault in git seems to satisfy this req, regardless of the strategy. A caveat is that encrypting
Ah, I understand what you were thinking now. This seems really useful as it doesn't require substantial changes to the existing format.
Likewise! I'll leave this open, but feel free to close. |
+1 to asymmetric setup Reading here about the Having the ability to go with asymmetric encryption/decryption without hub would be amazing. For cases like ours, where we would love any dev to append/change a key (plaintext) with encrypted value to the If we could have
This would make it to see "a change" in PR without the need to decrypt to check which key was modified -> if I understood the append solution right. Since you'd see the ciphertext modified and name of var plain text, it could also allow for the last added value for the key to be the one persisted avoiding the append log / need for cleanup |
this is a good point since process could look like this:
then just manually remove the prior one - like you would any key from a
|
the above would be a departure from the current (for the sake of discussion let's call it a .env.environment.crypt file) benefits
downsides
others thoughts? example:
|
this approach would remove the need for paranoid mode - #178 - since everything would still just be contained in the |
after some research i've chosen an encryption algorithm. secp256k1 curve. now working on a proof of concept implementation. |
work happening here: #197 it shows real promise to simplify things for the same benefits, plus the extra benefit of allowing non-trusted parties to contribute in a trustless manner to an open source repo's .env file. the tooling is also arguably easier than having to manage a .env.vault file and grasp a new concept like that. |
One more benefit I can see is it will make it easier to deal with git merge conflicts since change will be limited to the key touched ( should be easier for git to pick up ) rather than the long vault string per env. |
Exactly wht I was hoping for, this will make things so much easier 💯 |
i'm working on
but also might adjust the last option to instead use |
@kevlened what are your thoughts on this so far? |
This looks great!
Great choice, as it's supported by the major KMSs, should you decide to add native cloud KMS support.
A nice plus.
Fantastic!
Seems like your first and fourth usage examples are the same, but the first has less information.
It seems like this would be necessary to have enough information for your first usage example. However, one thing that's nice about That said, if the env is encoded in the key AND the variable, it's not clear which would win. Perhaps it just throws an error to prevent accidents? |
That particular UI is in Azure |
i gave this more thought and I think the cleanliness and most common happy path is to embed the environment/file-extension in the environment variable key so that a user can do this on their production servers: scenario 1: .env.production $ export DOTENV_PRIVATE_KEY_PRODUCTION="<key>"
$ dotenvx run -- node index.js
# this will smartly run the .env.production file (`_PRODUCTION` => `.env.production`) scenario 2: .env.ci
scenario 3: .env remote server
i like this for the point you made @kevlened and because this is a 1 to 1 match with what you see in the # .env.keys file
# .env.production
DOTENV_PRIVATE_KEY_PRODUCTION="03e966744d2f4fcb1471f5dd2ecc38b0786cafb3ebe0e35e568e23de1eb78126"
# .env
DOTENV_PRIVATE_KEY="b7fe6cf1e5b064e0f3d0aa03f2bb601c15a6585c7cd9534595c87fe7ca4f7594" i additionally like this because it unlocks support for multiple encrypted scenario 4: multiple encrypted/mixed .env files in production
furthermore, this will also support rotating private keys without downtime for any specific .env file:
the only thing missing here is future options. those won't be able to be encoded in the key as a result, but i think adding additional environment variables will solve that elegantly for custom future cases. for example, we could support a different encryption algo with:
and one last note, i think these conceptually align well with the flags used in development which should make for less cognitive friction for developers. for example:
can be run instead using a
they are functionally equivalent. |
these features are now in the following commands will be deprecated and additionally moved under
when thank you guys for all your thoughts on this. i think i'll look back on this thread someday as when dotenv's next evolution really found its footing. |
Great! Thanks for looking at this seriously; I'm looking forward to the release. |
I'd like contributors to be able to encrypt new variables for a target environment without the ability to decrypt other variables.
For example, let's say we want to update the variable
BIG_SECRET
inproduction
. Today, it seems the contributor would need theDOTENV_KEY_PRODUCTION
key from.env.keys
and theDOTENV_VAULT_PRODUCTION
variable from.env.vault
. Because all the secrets are encrypted together, it seems a contributor would be able to read all the variables when given access to the key. It follows that a contributor can't add onlyBIG_SECRET
to the vault without access to everything inproduction
.Is my understanding correct?
The text was updated successfully, but these errors were encountered: