From install to injected secrets

Six commands on a new account. Only a 0600 credential file and a secret-free .envless touch your disk.

What each step actually writes

Setup is three separate things: authenticate your machine, bind a directory and unlock the workspace. Then every later command runs with no arguments.

Full definition

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.

  • Written by login, mode 0600

    ~/.envless/config.json

    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.

  • Written by link, safe to commit

    .envless

    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.

  • Device code lifetime

    5 minutes

    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.

  • When every level has one option

    0 keystrokes

    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.

  • Before a passphrase is cached

    verified first

    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.

  • Free plan products, projects, environments

    1 / 1 / 2

    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: two of the three are created, it warns, writes .envless with the environments that were created, and exits non-zero.

The whole path

  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

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 two per project. When that happens init warns you, still writes .envless with the environments 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.