Clone an environment without decrypting it

Copy an environment, project, or product. Ciphertext is copied verbatim, so it never needs the key or produces plaintext.

What gets copied, what does not

Duplicate copies every level below whatever you point it at, carrying each encrypted value across byte for byte, so no plaintext secret exists at any point.

Full definition

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.

  • Per variable

    7 fields

    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.

  • Needed to run it

    no key

    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.

  • For every row it writes

    1 transaction

    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.

  • Versions are not copied

    no history

    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.

  • On a product clone

    privacy kept

    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.

  • Appended to the name

    " (copy)"

    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

  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

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. Each clone checks the allowance for the thing it creates before it writes anything, and refuses outright rather than creating resources you are not entitled to: duplicating a product checks the product allowance and that the product's projects fit under the project allowance, duplicating a project checks the project allowance, and duplicating an environment checks the environment allowance for its project. What is not checked is the environment count when you clone a project or product, or the variable count in any clone, so those can leave you above your plan 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.