From install to injected secrets

Six commands on a brand-new account, four on an existing project. The only things written to your disk are a 0600 credential file in your home directory and a committable .envless file that contains no secrets.

What you are setting up

Setting Envless up means three separate things that are easy to conflate: authenticating your machine, binding a directory to a specific workspace, product, project and environment, and unlocking the workspace so values can be decrypted locally. They are separate because they have different lifetimes. Login lasts 90 days, the directory binding is a committed file the whole team shares, and the workspace key is cached per machine and can be forgotten without signing out. Once all three are in place, every later command runs with no arguments.

What each step actually writes

Worth knowing precisely, because two of these files end up on disk and one of them is meant to be committed.

~/.envless/config.json

Written by login, mode 0600

Inside a directory created 0700, through a temp file that is chmod-ed and then atomically renamed, so a crash mid-write cannot leave a world-readable half-file. It holds the session token and, later, the derived workspace keys.
.envless

Written by link, safe to commit

Four-space-indented JSON holding only workspace, product, project and environment slugs. No secrets. It is resolved strictly from the current directory with no upward walk, so each package in a monorepo gets its own binding.
5 minutes

Device code lifetime

Login prints a 6-character code from a 32-symbol alphabet with I, O, 0 and 1 removed, and polls while you approve it in the browser. The session it mints lasts 90 days and is stored server-side only as a hash.
0 keystrokes

When every level has one option

Link skips any prompt where only one choice exists, so on a single-workspace, single-project account it completes without asking you anything. Flags cover the non-interactive case for CI images.
verified first

Before a passphrase is cached

The CLI pulls an existing ciphertext and tries to decrypt it, so a wrong passphrase is rejected up front rather than cached and producing undecryptable variables later. On an empty workspace the first passphrase must clear the strength floor.
1 / 1 / 1

Free plan products, projects, environments

Signup creates a workspace and three system roles and nothing else. On Free, envless init's default of development, staging and production only partly succeeds: it warns, writes .envless with the environment that was created, and exits non-zero.

The whole path

Steps two and three run once per machine. Everything after that is repeatable and works with no arguments.

  1. 1

    Install the CLI

    A single binary named envless, requiring Node 20 or newer. Install it globally, or pin it per project if you would rather everyone on the team run the same version.

    npm i -g @goenvless/cli@latest
    envless --version
  2. 2

    Sign in through the browser

    The device flow prints a short code and waits while you approve it in a browser tab, so no credential is ever typed into the terminal. This writes the one file in your home directory.

    envless login
  3. 3

    Create or bind a project

    On a fresh account, create the product and initialise a project. On an existing one, link binds this directory to what already exists. Either way you end up with a .envless file you commit.

    # fresh account
    envless product create "Acme"
    envless init --name "Web API" --env development
    
    # existing project
    envless link
    envless link --workspace acme --product web --project api --env development
  4. 4

    Unlock the workspace

    This derives the encryption key locally and caches it. It is a separate step from login because the key is what decrypts values, and the server has no part in it. The CLI warns that the derived key now sits on disk, and passphrase clear removes it.

    envless passphrase set
  5. 5

    Add your first variables

    Set them one at a time, or import the .env you already have. Push plans the change against decrypted remote values first, so --dry-run shows you exactly what would happen before anything is written.

    envless var set DATABASE_URL=postgres://localhost:5432/app
    
    envless push --file .env --dry-run
    envless push --file .env
  6. 6

    Run your app

    Nothing is written to disk. If a tool in your stack insists on a real file, sync writes .env.<slug> instead, and --require-gitignore aborts the whole run before decrypting anything if the target is not ignored by git.

    envless run -- npm start
    
    # only when a tool needs a real file
    envless sync --require-gitignore

Getting set up FAQ

Straight answers about how this works in practice.

Six commands on a brand-new account, four on a project someone has already set up. We will not put a stopwatch figure on it, because the honest answer depends entirely on whether the workspace already exists and whether you are the person who has the passphrase. The steps themselves are quick; getting the passphrase from a colleague is the part that takes real time.

Yes, and it is meant to be. It holds slugs only: which workspace, product, project and environments this directory maps to. No secrets, no tokens, no keys. Committing it is what lets a teammate clone the repository and run envless run with no arguments, and it is what makes CI work from a checkout.

No plaintext .env, which is the claim that matters, but not literally nothing. Setting the passphrase has already written the derived key into ~/.envless/config.json at mode 0600, and run reads it from there. The CLI warns you about this at the time. If you want it gone, envless passphrase clear removes it without signing you out.

You will be told immediately rather than later. Before caching anything, the CLI fetches an existing ciphertext from the workspace and tries to decrypt it, so a wrong passphrase is rejected up front. The only case where a passphrase is cached unverified is a workspace with no encrypted variables yet, and that is also the case where the strength floor is enforced.

You can run everything except link. Set ENVLESS_TOKEN to a machine key and supply ENVLESS_KEY or ENVLESS_PASSPHRASE, and reads work headlessly. Link is the exception: it reads your local config and never falls back to a machine key, which is deliberate, because the answer for CI is to commit the .envless file rather than to re-derive the binding on every run.

No. Signup creates a workspace and its three system roles and nothing else, and envless init tries to create all three environments but the Free plan allows one. When that happens init warns you, still writes .envless with the environment it did create, and exits non-zero so a script notices.

Not for reading values, because there is nothing else that can decrypt them. Every read needs a cached workspace key, an ENVLESS_KEY, or an ENVLESS_PASSPHRASE; without one, sync, run and var fail with the workspace reported as locked. On unattended machines prefer the exported raw key, which skips derivation and keeps a human-chosen string out of your environment.

They are separate credentials for separate jobs. Your CLI session authenticates you as a person for interactive work. The @goenvless/env runtime, which loads variables inside a running application, explicitly refuses a CLI session token and requires a machine key. So importing env in your app right after envless login will not work; the runtime path is a machine-key path.

Get Started

Ship secrets, not chaos.

Start free today and discover why developers trust Envless for end-to-end encrypted, versioned secrets across every environment.