Clone an environment without decrypting it

Copy an environment, a project, or an entire product with every variable it holds. The ciphertext is copied verbatim, so the operation never needs the workspace key and never produces a plaintext value.

What duplicate does

Spinning up a new environment usually means recreating a few dozen variables by hand, which is slow and is exactly the kind of manual copying that leaks secrets into chat. Duplicate does it in one action: it walks the tree below whatever you point it at and inserts a copy of every level, carrying each variable's encrypted value across byte for byte. Because it copies ciphertext rather than values, the workspace can be locked, the server learns nothing new, and at no point in the operation does a plaintext secret exist.

What gets copied, and what does not

The omissions are deliberate. A clone that inherited another environment's history would make every later rollback a trap.

7 fields

Per variable

Name, encrypted value, type, secret flag, visibility, required flag and default value. The value moves across as the same ciphertext, so nothing is decrypted and re-encrypted along the way.
no key

Needed to run it

Because nothing is decrypted, duplicate works on a locked workspace. Contrast that with push or compare, both of which have to decrypt to build a plan and therefore fail until you unlock.
1 transaction

For every row it writes

The product, project, environment and variable rows are inserted inside a single database transaction, so a failure part way through leaves nothing behind rather than a half-built product you have to clean up. The history events and the webhook are emitted after that transaction commits.
no history

Versions are not copied

A duplicate starts with a clean version history. Inheriting the source environment's snapshots would mean a rollback silently restoring values that belong to a different environment.
privacy kept

On a product clone

Duplicating a private product keeps it private and carries its per-member access grants across, so a clone never quietly widens who can reach the work inside it. A duplicated environment is never exposed either: the public-feed flag resets to off even when the source was serving one.
" (copy)"

Appended to the name

The copy is named for you and truncated if the suffix would push it past the name limit, so duplicating never fails on a validation error you did not ask about.

Three levels, one action

Point it at whichever level matches what you are trying to reproduce. Everything below that level comes with it.

  1. 1

    Clone one environment

    The common case: you want a scratch or preview environment that starts life identical to staging. You get every variable, with the same types and visibility flags, and an empty version history.

    envless env duplicate staging
  2. 2

    Clone a project

    Copies the project and every environment beneath it, each with its full variable set. Useful when a new service starts as a fork of an existing one rather than from nothing.

    envless project duplicate billing-api
  3. 3

    Clone a whole product

    The deepest form: product, every project, every environment, every variable. A private product stays private and keeps its member grants. Workspace plan limits are enforced at this point, so a clone cannot quietly push you past your project allowance.

    envless product duplicate payments
  4. 4

    Or do it over the API

    Each level has its own endpoint. Note the scopes: duplicating reaches variables, so it needs write on variables as well as on the thing you are copying, which is the API being honest about what it is about to touch.

    # products:write + projects:write + variables:write
    curl -X POST https://api.envless.cloud/products/payments/duplicate \
      -H "Authorization: Bearer $ENVLESS_TOKEN"
    
    # environments:write + variables:write
    curl -X POST https://api.envless.cloud/projects/billing-api/environments/staging/duplicate \
      -H "Authorization: Bearer $ENVLESS_TOKEN"

One-click duplicate FAQ

Straight answers about how this works in practice.

No, and that is the useful part. Duplicate copies the stored ciphertext directly rather than decrypting and re-encrypting, so it runs fine on a locked workspace. Any operation that has to compare or display values, such as push or environment compare, does need the key, because it genuinely cannot do its job without reading plaintext.

Because a version is a snapshot of one specific environment, and a rollback replays it into that environment. If a clone inherited the source history, rolling back would restore a set of values that were never actually in the clone, which is a footgun that only shows up during an incident. A clean history is the safe default; publish a version on the clone once it holds what you want.

No. A copy always lands beside its source: an environment copy stays in the same project, a project copy in the same product, and a product copy in the same workspace. There is no target selector anywhere, because the operation takes no request body at all. If you need the copy somewhere else, duplicate it in place and move on from there.

The copy stays private and keeps the same per-member access grants. That is the conservative choice: a clone that quietly became public, or that dropped its grants and fell back to workspace-wide visibility, would widen access at the exact moment nobody is looking. Change the grants afterwards if the copy is meant for a different group.

For some limits, yes, so it is worth knowing which. Duplicating checks the product and project allowances before it writes anything, and refuses outright rather than creating resources you are not entitled to. It does not check the environment or variable allowances, so cloning a project with many environments, or an environment with many variables, can leave you above those numbers. Nothing breaks, but treat the counts as something to review afterwards rather than something the clone guarantees.

You cannot choose, and that is the trade for it being one click. The copy takes the source name with " (copy)" appended, truncated to fit the 50-character limit, and a slug derived from that with a numeric suffix if one is already taken. Only the top level is renamed: nested projects, environments and variables keep their original names. Rename it afterwards if you want something else.

Not in this code path. The values are read as ciphertext, inserted as ciphertext, and never pass through a decryption step, which is the same property that lets publishing a version work without the key. Be precise about the scope of that claim: it says the duplicate operation performs no decryption, not that the server could not decrypt in general. What makes the server unable to read your values is that it never holds the key.

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.