[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)