[HN Gopher] Show HN: From dotenv to dotenvx - better config mana...
___________________________________________________________________
Show HN: From dotenv to dotenvx - better config management
Author : scottmotte
Score : 190 points
Date : 2024-06-25 14:49 UTC (8 hours ago)
(HTM) web link (dotenvx.com)
(TXT) w3m dump (dotenvx.com)
| bdcravens wrote:
| Seems odd to announce new features without calling out to the
| fact that libraries with the same name in other languages have
| had those same features for years. (for example, the dotenv gem
| in Ruby)
| smartplaya2001 wrote:
| Node.js already has built in support for .env
|
| https://nodejs.org/en/blog/release/v20.6.0#built-in-env-file...
| bdcravens wrote:
| True, but the dotenv npm package has been around much longer
| than that support (11 years vs 9 months), and the .env
| support in Node doesn't yet support features like auto-
| inclusion of environment-specific files.
| boxed wrote:
| I don't get it. Dotenv is only good for local dev. Otherwise you
| should put your secrets in environment variables (the "env" in
| ".env"). That people put .env files in prod is a mistake itself,
| and the proposed fixes here seem to not really do much about
| that.
| isoprophlex wrote:
| Just set those env vars in your IDE. Let your IDE or docker-
| compose or whatever read an .env file if you must. But don't do
| it directly from your application code, indeed you're one lazy
| dev away from putting an .env file on prod servers.
|
| Using dotenv-like constructions is, in my eyes, an antipattern.
| aendruk wrote:
| And it need not even be an _I_ DE. Whatever environment you
| use for development, set environment variables in that.
| Tainnor wrote:
| Please don't configure important things in the IDE. IDE
| configs are notoriously fickle and checking them into the
| repo usually just leads to a lot of problems in my
| experience, plus it will mean duplicated effort every time
| you need to do something from the CLI.
| adolph wrote:
| > Just set those env vars in your IDE.
|
| How is that different from a dotenv, other than location of
| where the k/v persists?
| hu3 wrote:
| I've seen so many .env files in production that I don't even
| wince anymore. I just formalize the finding by email and
| carry on.
| daralthus wrote:
| You can commit your secrets as an encrypted vault with this.
| Then decrypt it with a key where needed: locally, on CI, on
| prod, etc.
|
| This is basically a simplified version of Hashicorp's Vault,
| GCP key vault etc. with some less granularity on user
| authentication.
|
| It solves the issues around .env.example and is perfect for
| gitops. You have all your secrets for all your envs ready,
| while you only need to set a single env var (the private
| encrpytion key) on your specific hosting environment.
|
| You could even use separate keys per env, eg.: to give access
| to a developer to staging only.
|
| Mozilla's https://github.com/getsops/sops is another contender
| but with a more complicated (and perhaps more flexible) key
| management.
| candiddevmike wrote:
| https://rotx.dev can also be used for a local password safe,
| and it supports environment variables injection into various
| scripts or workflows.
|
| (author of rot)
| daralthus wrote:
| Looks great, however it is much easier to work with just
| files, rather than key rings stored somewhere third party.
| randomdata wrote:
| Dotenv is an okay hack, but the root problem is that the
| operating systems we run these applications in don't have a
| fully conceived environment variable system.
|
| I think you have a fair point that dotenvx doesn't get the
| implementation right, but it does at least seem to recognize
| where the problem lies and is trying to fix it from that angle.
| You have to start somewhere. Almost never do we get solutions
| right the first time. It takes iteration and experimentation
| and perhaps this (and others like it) can pave the way towards
| a better solution.
| l5870uoo9y wrote:
| > Dotenv is only good for local dev.
|
| It wouldn't surprise me if many VPS use .env files.
| rhplus wrote:
| Secrets don't belong in environment variables either. Place
| them in a vault and grant specific processes/identities
| permission to read and decrypt them.
|
| Env vars are prone to leaking and best practice moves the goal
| post further. Devs love to dump envs to log files, child
| processes inherit them, admins can very easily sniff them.
| pluc wrote:
| Keys in the env file will ultimately be loaded as environmental
| variables, so it's just adding a convenience layer.
| daralthus wrote:
| Would be nice to be able to configure which .env file to read as
| an environment variable. Why? Imagine a package.json with this
| line:
|
| `start: dotenvx run -f .env.local -f .env -- node index.js`
|
| Instead of the -f flag, which now cannot be overriden, one could
| invoke it with
|
| `DOTENV=.env.staging npm run start`
| fiddlerwoaroof wrote:
| Or just have the environment variable used after the flags are
| processed
| vinnymac wrote:
| You can, you just need to define the private key.
|
| For example
|
| DOTENV_PRIVATE_KEY_PRODUCTION
|
| Would provide it with the information it needs to read
| .env.production
| throwaway240403 wrote:
| "Config Management" means something else to systems folks.
| Suggest adding "for node projects" or something akin to the title
| to clarify.
| dymk wrote:
| It's not node specific like dotenv, it's a generic tool for
| launching processes with (optionally encrypted) environment
| variables.
| jitl wrote:
| Secrets in env vars in production is not too secure either,
| ideally you'll move to your app pulling secrets in-process from
| your infrastructure at boot-up or upon use. This also gives a
| nice advantage of not needing to rebuild the app or container or
| whatever to rotate a secret.
| Etheryte wrote:
| This just moves the problem to a different step. How are you
| going to manage access to said secrets, especially when your
| application lives off premises?
| nevir wrote:
| Many hosting environments give you this.
|
| For example AWS gives you multiple ways of injecting secrets
| as env vars into your containers when they boot up (ECS +
| secrets manager, EKS, etc)
| jitl wrote:
| This is still "env vars", easy to read from /proc/*/env too
| see the decrypted secrets from a different process. Versus
| in-process only secret fetch where you'd need to scan the
| memory pages of the app, which is a bit harder - especially
| if you keep the credentials in memory in a scrambled format
| so a simple scan on process memory for "secret_prefix_"
| doesn't find them.
| Spivak wrote:
| If an attacker can read other processes' envs you've
| pretty much lost as they're
|
| 1. Inside your process which means they can see the
| decrypted values.
|
| 2. Root which means they can get into your process to see
| the decrypted values.
|
| I'm not sure if your average dev has a threat model that
| assumes in memory scrambling let alone leaked env vars.
| After all we're talking about the standard way to do it
| being populating a file with the decrypted secrets and
| just leaving it there. All the security is already kernel
| security.
|
| I'm honestly not sure who dotenvx is aimed at.
|
| - No one security conscious is going to be cool just
| making the cyphertext available publicly or even
| internally.
|
| - Someone scrambling in-memory secrets isn't using dotenv
| to begin with, is using SecretsManager and the like, and
| probably doesn't want to change those to now go through
| the filesystem. You now get less auditing because all
| those secrets are bundled and you now only know "they
| accessed the decryption key."
|
| - And someone using dotenv for secrets doesn't have a
| threat-model where this meaningfully improves security.
| aforwardslash wrote:
| In adittion, if I'm not mistaken, child processes inherit
| the parent env vars, so if your application forks or use
| subcommands, you may be exposing the whole environment
| trove to 3rd party scripts, no root needed. Also, most
| vulnerabilities that enables execution of code will
| happily leak the env vars, no root access or "being
| inside the process" thingy (I know, code execution is
| technically "inside the process", but without requiring
| privileged levels)
| jitl wrote:
| I'm advocating people use something like SecretsManager,
| not this thing. In-memory only > env vars > secret files
| on disk.
|
| I find env vars very precarious because harmless
| developer debug logging, actions like sshing into a
| container and typing `env` etc can easily expose them.
|
| File on disk can be read by an attacker with via
| subdirectory path traversal bug
|
| It's much less likely for in process only secrets to be
| exposed by common mistakes/bugs
| bbor wrote:
| Yeah but it seems like the right step -- deployment, not
| implementation. All my secrets are managed by GitLab AFAIR,
| but in general I feel way better integrating secrets into
| each service/container (I happen to use Dokku, so it's as
| simple as something like `dokku add_secret APPNAME SECRET`)
| than having a central system.
|
| I am far too clumsy to trust myself to push secrets in
| encrypted form, personally
| bluelightning2k wrote:
| I've always wondered this. Seems like a password to get more
| passwords is potentially actually less secure (as in practice
| people will reuse master keys and they might actually
| increase the surface area, or make it a persistent threat
| after the keys themselves rotate)
| jitl wrote:
| In AWS and other clouds, you application can use an
| infrastructure provider API to create a secure session to
| access infrastructure APIs with per-application-instance
| credentials that are automatically rotated and can be used
| only by that instance. These APIs are how the cloud
| provider themselves provides environment variable injection
| features, but if your application consumes these APIs
| directly you can avoid having decrypted secrets hanging out
| in environment variables as a middleman between your app
| and the cloud runtime.
|
| Typically the application instance sessions are
| automatically rotated very frequently, AWS's sessions are
| limited to 6 hours for example.
| vinnymac wrote:
| Dotenvx has a cloud hub from which the keys can be
| pulled. I imagine an eventual feature will be for the
| keys to expire, and you'll have to re-authenticate with
| the cloud to get new credentials, just as you would with
| AWS.
| smallerfish wrote:
| Doppler is very nice, although it gets expensive at the
| middle tier, which is needed to separate by role.
| ashenke wrote:
| There's a typo in the article, if the author reads this : > But I
| think we have a solution to all three today - with dotenvx. In
| reverse problem order
|
| The URL in `dotenvx` points to https://gitub.com/dotenvx/dotenvx
| (gitub without the h)
| ssahoo wrote:
| Hey this link is malicious. It redirects to location:
| http://ww99.gitub.com/dotenvx/dotenvx and then some site
| blocked by ublock
| VWWHFSfQ wrote:
| I always used foreman [0] which I found to be superior to dotenv
| in every way. Even superior to this new dotenvx
|
| [0] https://github.com/ddollar/foreman
| edward28 wrote:
| Not to be confused with the larger foreman[0] also written in
| ruby.
|
| [0] https://theforeman.org
| itslennysfault wrote:
| Yeah, this is a really weird post for me. Before dotenv existed
| I used Foreman. It worked basically exactly how "dotenvx cross-
| platform" works (as a global command line). I switched to node-
| foreman because I largely switched to working on node projects
| and didn't want devs to need to have ruby installed. Then, at
| some point I switched to dotenv, and I don't even remember why.
| pictur wrote:
| I think for some reason people don't like such simple tools. I
| think it seems more reasonable to deploy a vault service running
| on kubernetes with jenkins. In some comments, they didn't even
| understand what the tool was for. Dear dude, you can travel
| between dimensions with this tool.
| brigadier132 wrote:
| Encrypting secrets and committing them seems very convenient but
| I'm paranoid about these sorts of things. Can anyone tell me why
| this would be a bad idea?
|
| One reason I can think of is that normally with secrets I
| actually don't keep any copies of them. I just set them in
| whatever secret manager my cloud environment uses and never touch
| them again unless I need to rotate them. Meaning there is no way
| to accidentally expose them other than by the secret vault being
| hacked or my environment being hacked.
|
| With this approach if someone gets access to the encryption key
| all secrets are exposed.
| Atotalnoob wrote:
| Using encrypted secrets provides a way better developer
| experience than using a vault.
|
| Typically, developers can't change production secrets in vaults
| and need to follow some other protocols.
|
| Encrypted secrets mean you deploy everything along side the
| secrets.
|
| The developer experience is great, but the biggest issues I
| have faced while using Kubeseal were
|
| 1. Developers HAVE the secret in order to encrypt it. This can
| be not ideal as then they can use these secrets in production
| or leak them
|
| 2. The secret encryption key change causes the need to re
| encrypt everything.
|
| 3. People don't understand the concept.
| prepend wrote:
| I disagree. Using vaults isn't that bad. And I'd also like
| developers to never actually know the secrets.
|
| It's a learning curve, but I think it's best to just bite the
| bullet and use a vault rather than trusting developers to
| know and manage secrets properly.
| nahtnam wrote:
| Another benefit is that debugging secret changes is a lot
| easier. We've had a couple of cases where someone changes the
| secret in a vault and that causes problems and no one can
| tell what changed between two deploys
| solatic wrote:
| The biggest issue with storing secrets in version control with
| the code is that past secrets are never relevant after they
| have been rotated. This makes rollbacks risky. Consider:
| 1. Create secret v1 2. Code v1 3. Deploy 4.
| Secret v2 (rotation) 5. Code v2 6. Deploy 7.
| Oops, need to roll back to v1 (from step 2) 8. Outage,
| because the secrets in step 2 are not the secrets from step 4
| bluelightning2k wrote:
| I don't really understand why this is a new project. Seems it
| would have been pretty simple to add these in a backwards
| compatible way.
|
| It would only break in cases where people's values specifically
| started with "encrypted:"
| daralthus wrote:
| It was added in a backwards compatible way, but the author
| decided to make a breaking change with this release.
|
| The previous (IMHO superior) version was generating a
| .env.vault and a .env.keys from a .env file. Leaving the .env
| plain text and .env.vault encrypted.
| bluelightning2k wrote:
| Maybe the simple idea is to start a company. Nothing wrong
| with that. It's definitely what I would do. First envx then
| "envx vault"
| OJFord wrote:
| Even without backwards compatibility, why not just a breaking
| change in the same project? Don't get it either.
|
| I've never used it (knowingly) but if I did and wanted to use
| this new version/project even the CLI name change to append 'x'
| would be annoying (I'd probably alias /symlink it).
| triyambakam wrote:
| Whether good or bad, it's marketing
| hermanradtke wrote:
| I've been using dotenv-cli for a long time now. I appreciate the
| encryption, but I will keep loading secrets from a vault instead.
| golergka wrote:
| I don't think encryption is a good idea, and the reason is
| forming bad habits. Now developers have a very strong and non-
| ambiguous habit: never put .env files in version control (except
| may be for .example.env). However, with this, you'll get
| accustomed to commit .env in _some_ projects, so you'll easily
| slip and commit it in another project where the vars are not
| encrypted.
| mplanchard wrote:
| Seems pretty similar to sops[0], but without the encrypted-by-
| default feature that makes sops feel significantly safer for
| secret management.
|
| Sops also integrates easily with AWS and other existing key
| management solutions, so that you can use your existing IAM
| controls on keys.
|
| I mentioned in another comment, but I've been using it over five
| years at two jobs and have found it to be great.
|
| [0]: https://github.com/getsops/sops
| pmccarren wrote:
| I too have been using sops for years, and agree -- dotenvx
| encryption seems very similar to sops.
|
| I'd prefer an integration between dotevnx and sops where
| dotevnx handles the UX of public env and injection, while
| leveraging sops for secret management and retrieval.
| Additionally, being able to have multiple keys for different
| actors is important.
|
| Having a single `.env.keys` file feels risky and error prone.
| dotenvx encourages adding your various env files, such as
| `.env.production`, to vcs, and you're one simple mistake away
| from committing your keyfile and having a bad day.
|
| If sops is not to be integrated, dotenvx could take some
| inspiration where the main key is encrypted in the secrets file
| itself, and you can define multiple age key recipients, each of
| which can then decrypt the main key.
| hadlock wrote:
| I've been using sops in production since at least 2017, plus it
| has excellent compatibility with containerized infra tools like
| helm and other infra tools like terraform (both technically
| using plugins, but helm secrets and the carlpetts terraform
| plugin have been around for ages and are widely used.
| rrgok wrote:
| Can a kind soul point me some documentation on how to put .env in
| a vault correctly? Possibly open-source solutions?
|
| If the vault is password protected, aren't you just adding one
| more indirection and nothing more? How is that helpful, since now
| I have to write the vault password in clear-text somewhere such
| that my application can read the env file from the vault?
| c0brac0bra wrote:
| A lot of modern cloud deployments read from a secret management
| system or vault at deployment time, and the secrets are made
| accessible to the application through various indirect methods
| so they cannot be accessed later on (i.e. if someone were to
| gain access to a running Kubernetes container).
|
| At no point does the application have access to the vault
| itself, and access to read the vault is guarded by IAM role
| permissions.
| rrgok wrote:
| Oh well, I really appreciate you taking the time to explain
| it. But honestly, I didn't understand a word. I recognize it
| is my lack of knowledge.
|
| I hope someone can do me a ELI5.
| freeone3000 wrote:
| Something _else_ pulls from the vault and exposes it as a
| regular env var to your process. The .env file is a
| workaround to get this running locally! For open source,
| the simplest to explain is using a k8s secret mounted to a
| pod -- pod identity allows access to the secret via rbac,
| which cannot be faked. Only that pod has access to that
| secret. But your process, running on the pod, sees it as an
| env var.
| boarnoah wrote:
| That doesn't cover what the GP was talking about with
|
| > (i.e. if someone were to gain access to a running
| Kubernetes container)
|
| right? Since those would still be secrets available in
| the env.
|
| I get that if someone has access to read your envvars,
| its a foregone conclusion already (about how compromised
| you are).
|
| However IIUC, the part of the point of doing things in
| memory with reading secrets (like with a Secrets Manager,
| is to eliminate having to keep secrets around as
| envvars/secret files in the runtime?
| freeone3000 wrote:
| If they can snoop on env vars of a running pod, it can
| snoop on the process. A k8s secret could be a file in the
| pod or a env var in the process, but neither are a
| persistent file distributed to developers
| pluc wrote:
| During deployment, the pipeline connects to the Vault,
| dumps relevant secrets in a .env file that it pushes to
| production systems that the application then reads from.
| postalrat wrote:
| A script fetches values from a database then sticks them in
| a file. This script runs before the your application starts
| so the file will be there waiting.
| hluska wrote:
| You were on the right path when you called a vault "one
| more layer of redirection." A vault on its own won't
| dramatically improve your security posture. Neither will a
| .env file.
|
| Instead, they both beat the alternative (which is writing
| secrets and environmental config directly in the source
| code). And they're both part of defending in depth.
|
| Defense in depth is hard to explain to a five year old, so
| think of candy. You're five and you're obsessed with candy.
| If I don't want you to eat pounds of it every single day,
| I'll likely do different things to stop you.
|
| 1.) I'll give you a reasonable amount of candy.
|
| 2.) I'll explain that if you eat too much candy, you'll
| face health consequences like tooth decay or childhood
| obesity.
|
| 3.) I'll put the candy somewhere both out of sight and out
| of reach.
|
| Software security is like that too. Instead of relying upon
| just one method, you'll do a number of different things. On
| their own, few of them are really very useful. But when you
| combine them all together, you can end up with a reasonably
| secure system.
|
| In the case of vaults, it's just a slightly safer tradeoff
| with its own problems. We've already established that it's
| bad to write secrets and environmental configuration info
| in source code. One way around that is to put secrets in a
| .env file but then distributing that file becomes the weak
| link. Maybe you Slack them around, or email them or maybe
| you write all the secrets on a whiteboard in your office? A
| vault has a lot of flaws, but it's better than writing them
| on a whiteboard. In some threat models, it's better than
| Slack or email.
|
| It adds depth but it's far from perfect.
| nunez wrote:
| Add your actual dotenv to .gitignore. Use bfg to make sure that
| any traces of your dotenv aren't in your commit history. Use
| detect-secrets client-side commit hook to confirm this and also
| monitor for secrets leakage. Use sops to encrypt your dotenv
| into some other file that is tracked by git. Sops can integrate
| with secrets management solutions (Vault, AWS KMS, etc.). Done.
|
| This is mildly complicated, but the alternative is storing
| config in a configuration server somewhere, which comes with
| its own can of worms.
| ComputerGuru wrote:
| We've been pushing for committing encrypted secrets for many
| years now, and have written an open source spec and
| implementation in multiple languages:
| https://github.com/neosmart/securestore-rs
| curiousdeadcat wrote:
| I got so excited, but it doesn't seem to support multiple keys
| and seems overly eager to encourage people to leave a valuable
| key lying around on disk.
|
| So if a single dev machine is compromised, all of your prod
| secrets are exposed?
|
| I wish this were closer to sops with support for gpg and or ssh
| keys. Because sops is a great idea locked in a questionable
| codebase.
| ComputerGuru wrote:
| Happy to discuss a proposal to add asymmetric key support to
| the project in the GitHub issue tracker. Although I'm not
| sure how the security changes with an asymmetric key, as
| either way the worst case scenario is the same?
|
| Note that you don't have to leave the key "lying around" as
| you can secure it the same way you would an asymmetric key.
| And it certainly beats leaving the plaintext secrets
| themselves lying around in a .env file or similar.
|
| EDIT:
|
| I see you were saying "dev machine" exposes "prod secrets"
| but that's not the case. The protocol is designed so you
| would have secrets.json and secrets.prod.json, encrypted with
| different keys and (necessarily) managed separately but with
| the same tools and api. Dev machines being compromised
| compromises dev keys, not prod keys.
|
| Read the last section in the README on GitHub for more on the
| dev/prod split.
| curiousdeadcat wrote:
| Asymmetric keys mean you can you can have per-dev or per-
| team keys and allow one team to rotate them and resign them
| for all other consumers. I don't know how you'd do that
| with symmetric keys. This is an important feature of sops,
| imo.
|
| It also means I can do things like seal them to a key that
| is stored in KeyVault and then allow the transparent
| retrieval of that key at runtime on Instances that have
| been given an identity with access.
|
| This means that production secrets are sealed in place and
| only openable by effectively authenticated workloads.
|
| And if you use sops-nix, this becomes a "setup once and
| never think about it ever again, ever" kind of operation.
| mplanchard wrote:
| There's also sops: https://github.com/getsops/sops
|
| I've used it at two jobs now over about 5 years and have had
| zero issues.
| ComputerGuru wrote:
| Another commenter mentioned it, I'm looking at it now.
|
| SecureStore was launched in 2017 (initial version was .NET
| only): https://neosmart.net/blog/securestore-a-net-secrets-
| manager/
| jahewson wrote:
| I don't get it. There's a symmetric secrets.key that anyone
| could get hold of and use to overwrite secrets? No thanks.
|
| And where do I keep the key? In a secret store?
| ComputerGuru wrote:
| You keep the key wherever you want to keep the key, just
| don't commit it and don't distribute it. Put it in on a
| YubiKey for your devs, upload it out-of-band securely to
| prod.
|
| Whether it's a symmetric key or an asymmetric key, you have
| the same problem. Someone overriding your secrets is
| definitely not high on the list of concerns, and if they're
| committed to git then they can never be truly overwritten.
| ptdorf wrote:
| So.. it just swapped ignoring `.env` for `.env.keys`?
| wodenokoto wrote:
| On my phone so can't double test, but can't you get this by
| adding "export" in front of every line in your env file and then
| source before running command?
|
| I suppose if you don't want it to stay after execution i believe
| you can: > $(source .env; my command)
|
| I'm sure there is a fairly straightforward way to encrypt and
| decrypt a local file
| bogdan wrote:
| https://github.com/getsops/sops
| newzisforsukas wrote:
| Being able to source the file is the main benefit of using a
| .env file, IMO. Otherwise, you can just use any format for
| config management.
| ruined wrote:
| dotenv has features that include conditional selection and
| ordered merging of env files, which are configurable by
| dotenv's runtime and buildtime APIs.
| eternauta3k wrote:
| Now take that a step further with Environment Modules and you
| can source them from any shell or scripting language:
| https://modules.readthedocs.io/ (without creating a
| subinterpreter)
| gkfasdfasdf wrote:
| If in bash, you can use the 'allexport' option and source the
| .env without having to add 'export' in front of every line:
| #!/bin/bash set -o allexport . .env
| set +o allexport cmd
| bradgessler wrote:
| I really wish 1Password would ship an environment manager for
| their op CLI.
| michaelmior wrote:
| With leaking secrets being such a big concern, it seems wise to
| _require_ that secrets be encrypted to use dotenvx. That is, it
| will only work with encrypted secrets. As others have commented,
| this doesn 't eliminate the risk entirely, but I think having a
| tool that doesn't support unencrypted secrets at all, although a
| bit less convenient, is a win.
| akvadrako wrote:
| Encrypted with what key? Do you just mean obscured?
| projektfu wrote:
| The utility has a means of encrypting them with public key
| cryptography so that the plaintext is never in your
| development directory. GP thinks this should be made
| mandatory.
| cced wrote:
| There are a lot of ways of doing this, sealed secrets is one,
| mozilla sops is another.
| 0xbadcafebee wrote:
| The whole idea of using environment variables for configuration
| information is good, but ultimately flawed, and we are way past
| the point where this should continue to be the status quo.
|
| Environment variables are great for configuration because:
| - you can inherit them from a previous application or
| application(s) - you can override them in each environment
| you run your app in - you can pass them on to other
| applications - they are globals that can be loaded by
| libraries - they're not hardcoded in the code, so easier to
| change things without rebuilding, easier to reuse in different
| ways/environments/configurations - the OS has primitives
| for them - they're simple
|
| Environment variables are bad for configuration:
| - because (by default) when set in application, they are passed
| on to all future applications/forks/execs - they are often
| dumped as part of troubleshooting and aren't considered
| confidential - they can often be viewed by external
| processes/users - there are restrictions on key names and
| values and size depending on the platform - typical
| "dotenv" solution doesn't necessarily handle things like multi-
| line strings, has no formal specification - no types,
| schemas
|
| What we actually need that environment variables are being used
| for: - configuration information passed at
| execution time that can change per environment - loading or
| passing secret values - development environments -
| production environments
|
| So what would be a good alternative? - an
| application library ("libconfig") that can load configuration of
| various types from various sources in various ways -
| support for configuration types: key-value, file/blob,
| integer/float - support for confidentiality (require
| specific function to unseal secret values; in programming
| languages the intent would be you can't just print a stringified
| version of the variable without an unseal function) -
| support for schema (application defines schema, throws exception
| if value does not match) - support allowing a configuration
| to be overloaded by different sources/hierarchies - support
| passing a configuration on to other applications - support
| tracing, verbose logging - truly cross-platform and cross-
| language with one specification, behavior for all
|
| How would it work? - devs can create a .env file
| if they want - devs load 'libconfig' into app, use it to
| load their configuration values during development. library can
| have default sources, and even set env vars or an object
| internally, so no code needs to be written to use it - in
| production, same code causes libconfig to look at cloud-native
| and other sources for configuration - when debugging,
| secret confidentiality is maintained, tracing communicates
| sources of configuration, what was loaded, from where, etc
| tamimio wrote:
| > An attacker needs the DOTENV_PRIVATE_KEY
|
| And the attackers will be after this file not the .env anymore.
|
| It looks great nonetheless, especially the cross-language
| feature.
| boundlessdreamz wrote:
| This is similar to how Rails handles secrets -
| https://edgeguides.rubyonrails.org/security.html#environment...
|
| In Rails, the entire file is encrypted unlike here where only the
| secrets are
| vinnymac wrote:
| Dotenvx used to encrypt by file. It's a very recent design
| decision to encrypt by secret.
| cyberax wrote:
| I _detest_ this kind of encryption. It's literally worse than
| useless. It makes life much harder during debugging, and it
| eventually leads to developers just storing the decryption keys
| locally.
|
| For this kind of encryption to work, you need to supply the
| decryption key from some outside system (e.g. via env vars, AWS
| SSM, etc.). And if it can supply the key, then why not just use
| it for other important secrets directly?
| gregwebs wrote:
| I use tools that read secrets out of vaults on demand using
| existing infrastructure for key management. For AWS there is
| aws-vault.
| slt2021 wrote:
| it might be easier to just store and checkout a single
| decryption key that only devops people know, vs storing
| hundreds of secrets.
|
| while developers can move around their .env file across systems
| without worrying that they left plaintext secrets somewhere.
|
| also it allows adding new secrets without knowing decryption
| key - I think it is important for collaboration
|
| also most importantly: plaintext decrypted secrets are never
| stored on disk, and only kept in memory. I think it is also an
| improvement towards the regular doting
| cyberax wrote:
| > it might be easier to just store and checkout a single
| decryption key that only devops people know,
|
| "Devops people know" means that the key must be some secret
| property. Or you need to use the key during the deployment
| artifact building pipeline, and then deploy the artifacts
| with clear-text secrets.
|
| > vs storing hundreds of secrets.
|
| Then serialize them to JSON or whatever.
|
| > also it allows adding new secrets without knowing
| decryption key - I think it is important for collaboration
|
| So basically, you want developers (who don't have access to
| prod) to add random properties that your peers can't see
| during the code review? Ok...
|
| Sorry, there's just no way the encrypted secrets in git are a
| good idea for general-purpose software.
| tptacek wrote:
| It's also problematic from a secrets management perspective,
| because a big part of the perceived value of encryption is
| being able to check secrets into git. But because the
| encryption is tied to long-term keys, you have to design your
| security processes with the assumption that those keys will
| eventually be exposed and need to be "revoked" (ie: the secrets
| re-encrypted), and the "de-revocation" of those keys is hiding
| in your git history.
| sandstrom wrote:
| I've started using Mise for some stuff at work. Haven't digged in
| a lot yet, but looks really promising.
|
| https://mise.jdx.dev/
|
| It handles task running (wipe local test db, run linting scripts,
| etc), environment variables and 'virtual environments', as well
| as replacing stuff like asdf, nvm, pyenv and rbenv.
|
| Still somewhat early days, tasks are experimental. But looks very
| promising and the stuff I've tried to far (tasks) works really
| well.
| ralgozino wrote:
| I second mise, it's been a nice replacement for direnv, asdf
| and makefiles for my use case. Much faster, still compatible
| with the old configuration files when needed and all in one
| tool for the new projects. Awesome.
| stiiv wrote:
| dotenv has zero npm dependencies. dotenvx has 21, including a few
| I have never heard of. Is this really more secure?
| caliwagon wrote:
| Recent versions of node support env files directly, so you
| don't even need one dependency anymore.
| https://nodejs.org/docs/latest-v20.x/api/cli.html#--env-file...
| cimnine wrote:
| I think it's good advice to not pass secrets through environment
| variables. Env vars leak a lot. Think php_info, Sentry, java vm
| dumps, etc. Also, env vars leak into sub-processes if you don't
| pay extra attention. Instead, read secrets from a vault or from a
| file-system from _inside_ your process. See also [1] (or [2]
| which discusses [1]). Dotnet does this pretty good with user
| secrets [3].
|
| [1] https://blog.diogomonica.com/2017/03/27/why-you-shouldnt-
| use... [2]
| https://security.stackexchange.com/questions/197784/is-it-un...
| [3] https://learn.microsoft.com/en-
| us/aspnet/core/security/app-s...
| nimishk wrote:
| I don't think this is the best approach. I am building
| https://phase.dev which lets you import secrets (.env), encrypt
| secrets (end-to-end encrypted with keys you control), sync them
| to other services/platforms (think AWS, GitHub, Kubernetes), and
| inject them into applications at runtime (e.g., phase run node
| index.js).
|
| Source: https://github.com/phasehq/console
| poopsmithe wrote:
| What do you mean it's not the best approach? That's a little
| light on the details.
| hamasho wrote:
| I want an option to manage all env in a single file using a TOML
| like format like this. [local]
| API_KEY=local-key API_SECRET=local-secret
| DB=postgresql://username:password@localhost:5432/database_name
| [production] API_KEY=prod-key API_SECRET=prod-secret
| DB=postgresql://username:password@prod-db:5432/database_name
| [staging] API_KEY=stg-key API_SECRET=stg-secret
| DB=$(production.DB)
|
| It makes it easier to update all env at once, compare, and share.
| It's not much help, but it helps me avoid a few annoyances.
|
| On an unrelated note, I always find it a real headache to keep
| the naming convention of the environments throughout the project.
| It always ends up like a mixed bag: * Juggling
| production/prod, staging/stg, and develop/dev, *
| Inconsistent placement of env, e.g. prod-myproject or myproject-
| stg, * Skipping env name sometimes, e.g. myproject-bucket
| for dev S3 bucket but prod-myproject-bucket for prod (though it's
| okay to emit env name for user facing places like URL), *
| Inconsistent resource sharing between envs, e.g. same S3 bucket
| for local and dev but different DB, or same Kubernetes cluster
| with different labels for dev/stg but different cluster without a
| label for prod.
|
| These inconsistencies often result from quick decisions without
| much thought or out of necessities, and everyone is too scared to
| fix them anyway. But it bothers me a lot and sometimes causes
| serious bugs in production.
|
| Fix: format
| nunez wrote:
| You can do that today with sops if you'd like!
| the_duke wrote:
| We implemented the exact same method for config encryption a year
| ago or so, using pub/private key auth and the same `encrypted:`
| prefixes for encrypted config values.
|
| This is a great tradeoff: easy way to share configuration, easy
| way to edit non-encrypted config values, reasonable security for
| the private values.
|
| Doesn't solve key rotation of course, but for small teams this is
| a great solution.
| treflop wrote:
| The only reason I use .env is because it's dead simple and very
| obvious as to how it works to anyone.
|
| If now someone has to read docs to figure out how to configure
| the app, I'd rather have them read docs for some other safer and
| more powerful configuration scheme.
| neonate wrote:
| https://github.com/dotenvx/dotenvx
| difu_disciple wrote:
| I always thought highly of the approach used by
| https://www.npmjs.com/package/@strong-config/node
|
| Does dotenvx support secrets managers?
| tracker1 wrote:
| Since node v20.06, has built in support for --env-file=.env on
| load... as for local(ish) encryption and pushing them into source
| control, I don't like this at all. I'm fine using a vault or
| secret distribution from either the environment host (k8s) or
| ci/cd deployment.
|
| I do like to keep a .env.example that you can rename to .env and
| adjust as desired. I tend to have defaults for running a compose
| stack locally that close to "just works" as possible.
|
| I doubt I'd ever want to use this in practice.
| hooverd wrote:
| Personally, I like sops for encrypting my secrets.
| nunez wrote:
| dotenvx encryption goes a long way towards solving THE BIGGEST
| problem with dotenv; using multiple tools to ensure that secrets
| are protected.
|
| I wonder if dotenvx ensures that .env is in .gitignore and yells
| loudly if it is not.
|
| I encrypt my dotenvs with gpg, but that's hella esoteric and
| everyone shouldn't be forced to do that.
| daralthus wrote:
| and .dockerignore
| TZubiri wrote:
| Importing a set of library and dependencies to handle reading a
| plain text file poses more risks than just leaving the file
| unencrypted.
|
| You don't need to encrypt your keys, with what keys are you going
| to do so? Will you encrypt those?
|
| if someone is in your server you are pwned anyways.
|
| It's ok if you identify yourself as a cybersecurity dude and hold
| a cybersecurity role and you need to justify your livelihood.
|
| But do it in a way where you don't bother people. It's ok if you
| bother devs, but then you go on and bother users with 4FA, 5 rule
| passwords, systems that can't answer subpoenas because you have
| encrypted your sense of self.
|
| When you are improving security at the expense of every other
| variable, that's annoying, but when you keep "improving security"
| at the expense even of security, is the point where people will
| start ignoring and hiding shit from you
| NegativeK wrote:
| > if someone is in your server you are pwned anyways.
|
| This is false and also a symptom of an all-or-nothing approach
| to cybersecurity, which isn't feasible in the real world.
| TZubiri wrote:
| I suppose they could have read only access to the filesystem
| and read the api keys, like through an http server
| Aerbil313 wrote:
| I looked up dotenv for the first time. Heard about it a lot,
| thought it must be something revolutionary. 18k stars on GitHub.
| Turns out it's a tool to load environment variables when you
| enter into a directory.
|
| The state of modern software.
| swedonym wrote:
| Huge fan of dotenv, excited to try this out!
| daralthus wrote:
| GOAL: To be able to commit all your envs to git.
|
| This is the only goal and this tool archives it. In the simplest
| way. While keeping you as secure as you were before, manually
| setting envs on heroku, railway, aws, jenkins etc.
|
| GitOps FTW
| daralthus wrote:
| Can you do safer? Yes, yes you can with a secrets management
| service (e.g.: Hasicorp Vault). Is that way more complicated to
| setup in all envs? Oh yes, yes it is.
| frithsun wrote:
| Thanks, but I would rather go with the imperfect setup that I
| understand than an allegedly perfect setup with dozens of third
| party dependencies that I don't understand.
|
| Doubly the case now that env is natively supported by node now.
| rednafi wrote:
| Written in JS; I think I'll pass.
___________________________________________________________________
(page generated 2024-06-25 23:00 UTC)