1. Docs
  2. Account Structure
  3. Environments

Environments

How Environments isolate access-control configuration inside an Application.

Overview

Environments are the unit of access-control isolation inside an Application. Each Environment is a self-contained workspace with its own permissions, roles, hierarchy, API keys, OAuth clients, and webhooks — completely independent from sibling Environments in the same Application. Most teams use Environments to mirror their software development lifecycle (development, staging, production), but the system imposes no naming convention or count — you can run a single Environment per Application or many, with any names that match how your team works.

Access Control Context

Environment is the context for Access Control

When you select an Environment in the dashboard's workspace switcher, every page under Access Control — Overview, Hierarchy, Identities, Roles, Permissions, Integrations — re-scopes to that Environment's data.

Permissions in Development are not the same rows as permissions in ProductionAn identity assigned Manager at a node in Development is not assigned Manager at the same node in ProductionAn API key minted in Development will fail to read Production data

This is what makes safe iteration possible — reshape the hierarchy, add and rename permissions, hand out roles, test invite flows inside Development, with zero risk of affecting Production. When the configuration is solid, push it across with the Promote action on the Application's environment card.

One deliberate exception: identities and role assignments are never copied across Environments. Identities live at the Account level (shared across every env), and assignments are operational state you choose per env. A promote from Development to Production brings the permissions, roles, and hierarchy — but Production still has zero people in it until you assign them.

Moving Configuration Between Environments

There are four mechanisms shipped today for moving configuration from one Environment to another — three primitives plus one guided flow built on top. The rules are the same across all four.

What's copied, what isn't
Copied: permissions, roles, role-permission joins, hierarchy nodes, OAuth client configurations, webhook configurationsNever copied: identities, role assignments, API keysRotated: OAuth client secrets and webhook signing secrets are regenerated in the target Environment; the originals never travel

Even after a full clone, the target Environment starts with zero people and zero assignments — those are operational state you choose deliberately per env.

When you create a new Environment, the Create Environment dialog has a Copy configuration from dropdown. Pick a source Environment and the backend seeds the new one with that source's full configuration. Use this when you're standing up a fresh Environment (e.g., spinning up a new qa env modeled on development) and want to start populated rather than empty.

The Export Configuration action downloads the Environment's full configuration as a JSON file named <account>-<app>-<env>-config-YYYY-MM-DD.json. The source Environment is unchanged — export is read-only. Useful for offline review, version control, or handing the configuration off to another tool.

The Import Configuration action opens a file-upload dialog. Provide a Canopy-exported JSON file, confirm the replacement, and the backend overwrites the target Environment's configuration with the file's contents.

Import is replace-semantics, not merge — anything in the target that isn't in the file gets removed. Identities, role assignments, API keys, and secrets are left alone as always, but everything in the configuration scope (permissions, roles, hierarchy, OAuth/webhook configs) is fully overwritten.

The Promote Configuration to… action is the one-click version of export-then-import. Pick a target Environment in the same Application, confirm, and the dashboard runs the export on the source and the import on the target in sequence. The same replace-semantics apply.

Promote runs as two network calls (export then import) and is not atomic across the pair. If the export fails, the source is untouched. If the import fails partway, the target Environment is in whatever state the import got to — but the source is still unchanged, so retrying is safe. The dialog distinguishes the two failure modes inline so you know which one happened.

If you manage configuration through Terraform, your own CI/CD, or another infrastructure-as-code tool, you can skip the dashboard entirely. Each Environment has its own API key; calling POST /api/v1/permissions, POST /api/v1/roles, etc. against each Environment using its API key gives you the same end state as a clone or import, with whatever orchestration your tooling prefers.