From Dotenv to Dotenvx: Next Generation Config Management
Evolution from dotenv to dotenvx, a configuration tool addressing .env file leaks, multi-environment management, and platform inconsistencies. Offers encryption, uniform commands, and enhanced security. Version 1.0.0 released, promising future utilization.
Read original articleThe article discusses the evolution from dotenv to dotenvx, a next-generation configuration management tool. While dotenv has been widely used for 11 years, it faces issues like leaking .env files, managing multiple environments, and platform inconsistencies. Enter dotenvx, which addresses these problems by offering a consistent experience across languages and platforms, simplifying multiple environment management, and introducing encryption for .env files. With dotenvx, users can run commands uniformly, handle multiple environments effortlessly, and encrypt sensitive data securely. The tool generates encryption keys for added security, ensuring that even if .env files are exposed, decryption requires specific keys. This release marks version 1.0.0 of dotenvx, positioning it as a significant advancement in configuration management. The article concludes with an invitation for users to explore and utilize dotenvx, hinting at a promising future for the tool in the coming years.
Related
X debut 40 years ago (1984)
Robert W. Scheifler introduced the X window system in June 1984 for the VS100 Unix server, offering improved performance over W. The system was stable, with the Laboratory for Computer Science already transitioning to X and developing applications. Scheifler encouraged experimentation and welcomed volunteers for documentation contributions.
The 10x developer makes their whole team better
The article challenges the idea of the "10x developer" and promotes community learning and collaboration in teams. It emphasizes creating a culture of continuous learning and sharing knowledge for project success.
40 years later, X Window System is far more relevant than anyone could guess
The X Window System, developed by Scheifler and Gettys at MIT, remains relevant after 40 years. Its evolution from X10r4 to X11 brought graphical capabilities, cross-platform compatibility, and enduring value in academia and beyond.
Show HN: Envelope – A modern environment variable cli tool
The GitHub repository features "envelope," a Rust tool for handling environment variables via SQLite. Commands include add, check, delete, drop, duplicate, export, edit, init, import, list, and help. Simplifies environment configuration management.
XZ backdoor: Hook analysis
Kaspersky experts analyzed the XZ backdoor in OpenSSH 9.7p1, revealing hidden connections, SSH authentication bypass, and remote code execution capabilities. The backdoor manipulates RSA keys, uses steganography, and executes commands.
[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...
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.
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.
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.
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.
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?
[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
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 fileYou 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
Doubly the case now that env is natively supported by node now.
In Rails, the entire file is encrypted unlike here where only the secrets are
So we can have
FOOPW=pw1
when testing locally, but
FOOPW="{vault1:secret1}"
in production. Env vars are processed simply by running a regex with callback that fetches secrets from vaults. This is quite flexible and has the advantage of being able to inject the secrets in the same place as other configuration, without actually having the secrets in environment variables or git etc (even encrypted)
The URL in `dotenvx` points to https://gitub.com/dotenvx/dotenvx (gitub without the h)
It would only break in cases where people's values specifically started with "encrypted:"
Is there a good primer on using vaults? I know how to query and insert into Azure Key Vaults, but architecting around it is unclear to me.
Things that come up for me:
- As (azure) key vaults don't support per secret access rights, where do I store secrets between deployments?
- Should I store connection strings to cloud resources, or just ask the resource for the connection string at deployment time (for Azure, a cloud function pretty much needs a connection string for most basic things. They say they are moving away from this but ...)
- A security warning is send if a key is accessed more then x/times per hour. Does that mean I should pull in the key from vault at deployment? Cache it after first call during runtime?
- Most of our 3rd party vendors gives us 1 and only 1 key. How do I manage that key between development, production and several developers? Right now we mostly forward the e-mail from the vendor with the key ...
`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`
The correct fix for “it’s too easy to accidentally commit .env files with secrets” is to not function (panic/throw) if there isn’t a suitable .gitignore/.dockerignore, not a specialized cryptosystem for .env files. This just creates a different problem.
I simply use an envdir outside of the project and update all my run scripts to use “envdir $CONFIG_PATH <whatever>”. Simpler and safer.
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.
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.
Can’t I somehow do this in the script itself so “ruby index.rb” is enough? I know I’m only saving a couple of characters in the command line but I’m asking out of curiosity.
Does dotenvx support secrets managers?
The ability to use arbitrary filename for.env is quite nice though!
And the attackers will be after this file not the .env anymore.
It looks great nonetheless, especially the cross-language feature.
A=$B
B=$A
Anyway, I hope they don't do command interpolation on top of that (like Ruby dotenv does), because then you can inject code via environment variables (like in the Ruby version).I recently looked into various dotenv implementations just for fun. They're all different. No unified syntax at all. A lot don't do proper parsing either, but just use some regular expressions (like this one), which means they just skip over what doesn't matches. I started to document all the quirks I could find and wrote my own dotenv dialect just for fun. Nobody use it! Anyway, here it is: https://github.com/panzi/punktum
Direct link to the quirks of the JavaScript dotenv implementation: https://github.com/panzi/punktum?tab=readme-ov-file#javascri...
I've also tried to write a parser compatible to JavaScript dotenv (no x) in C++: https://github.com/panzi/cpp-dotenv
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
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
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.
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?
Related
X debut 40 years ago (1984)
Robert W. Scheifler introduced the X window system in June 1984 for the VS100 Unix server, offering improved performance over W. The system was stable, with the Laboratory for Computer Science already transitioning to X and developing applications. Scheifler encouraged experimentation and welcomed volunteers for documentation contributions.
The 10x developer makes their whole team better
The article challenges the idea of the "10x developer" and promotes community learning and collaboration in teams. It emphasizes creating a culture of continuous learning and sharing knowledge for project success.
40 years later, X Window System is far more relevant than anyone could guess
The X Window System, developed by Scheifler and Gettys at MIT, remains relevant after 40 years. Its evolution from X10r4 to X11 brought graphical capabilities, cross-platform compatibility, and enduring value in academia and beyond.
Show HN: Envelope – A modern environment variable cli tool
The GitHub repository features "envelope," a Rust tool for handling environment variables via SQLite. Commands include add, check, delete, drop, duplicate, export, edit, init, import, list, and help. Simplifies environment configuration management.
XZ backdoor: Hook analysis
Kaspersky experts analyzed the XZ backdoor in OpenSSH 9.7p1, revealing hidden connections, SSH authentication bypass, and remote code execution capabilities. The backdoor manipulates RSA keys, uses steganography, and executes commands.