← All posts

Alternatives to .env Files

Why a .env file is not a safe place for secrets

A .env file is a plaintext list of KEY=value lines that a loader reads into your process at startup. It is the fastest way to get a secret into an app, and it is where most secret leaks start. The same failure modes show up in every language:

If you are looking for an alternative to .env files, the durable one is to stop keeping secrets in files at all. That is what SikkerKey does, and the reason .env files are popular, that they are dead simple, is the bar it is built to meet. You bootstrap a machine once, and your code reads secrets with no file, no token, and no config.

One command to set up, nothing to wire up

Getting a machine onto SikkerKey is a single command. You create a bootstrap token in the dashboard and run it on the server, container, or runner:

curl -sSL https://api.sikkerkey.com/v1/bootstrap/<token> | sh

validate-modal

That gives the machine its own identity on the host. From then on, the CLI and every SDK find that identity on their own. There is no token to store in an environment variable, no key path to configure, and nothing to pass in your code. You set the machine up once, and reads just work.

A drop-in CLI for any language

The CLI is the direct replacement for a .env loader. sikkerkey run injects the secrets a machine can read as environment variables and runs your command, with no key or token in the line because it already knows the machine:

# inject everything this machine can read, then run your app
sikkerkey run --all -- node app.js

# pick specific secrets, or scope to one project
sikkerkey run --secret sk_db_prod --secret sk_stripe_prod -- ./worker
sikkerkey run --all --project production -- node app.js

# preview what would be injected, without running anything
sikkerkey run --all --dry-run

Migrating is a one-line change to your start command: node --env-file=.env app.js becomes sikkerkey run --all -- node app.js, and your code keeps reading from the environment exactly as before. When you want a file or a single value instead, sikkerkey export --format dotenv writes one on demand, and sikkerkey get sk_api_key prints a single secret.

Six native SDKs that find the machine for you

If you would rather read secrets in code, SikkerKey ships a native SDK for Python, Node.js, Go, .NET, Kotlin/JVM, and PHP. Each one detects the machine's identity for you, so you create a client with no arguments and read a secret by id:

# pip install sikkerkey
from sikkerkey import SikkerKey

sk = SikkerKey()                       # finds this machine's identity for you
api_key = sk.get_secret("sk_stripe_prod")

The other five follow the same shape, and all are read-only with minimal or zero dependencies. Full reference is in the SDK docs.

One encrypted vault, with rotation built in

Your secrets live in one encrypted vault, organized into projects, instead of the same plaintext file copied onto every machine. Because they live in one place, the things a .env file cannot do come for free:

Per-secret access and a full audit log

A .env file holds the secret in the clear, so anything on the box can read it, and you never find out who did. SikkerKey gives you the opposite by default. A machine reads only the secrets you granted it, and it proves who it is on every request without carrying a reusable token, so there is nothing in a file or a log for someone to copy. Every read is recorded against a specific machine, with the time and source, and streamed to your dashboard live, so a secret read at 3am from an unfamiliar host is something you hear about rather than piece together later.

Wherever your code runs

The same one-command setup covers every place a .env file ends up. Long-lived servers bootstrap as above; containers can take a ready-made identity from the dashboard; CI runners and autoscaled fleets enroll themselves per run with short-lived identities that expire on their own; and AI coding agents get their own identity that can manage the vault while staying locked out of secret values.

Replacing your .env file

A .env file is convenient because the secret is right there, which is exactly why it leaks. SikkerKey is the alternative that keeps the same simplicity, one command to set a machine up and sikkerkey run --all -- in front of your start command, while the secret stays in an encrypted vault and reaches a machine only when it asks. You get rotation, an audit log, and per-secret access on top, in place of a plaintext file any process can read.

Create your first secret and point one machine at it to see the whole flow end to end.