Staging and production
Create an environment in your project, push values to it by name, and grant the role that reads it.
Each environment in your project holds its own version of every key. Reading one needs a role scoped to it.
Create the environment
penv env new stagingpenv env new asks us to create an empty environment in the project named by @penv=. The first penv push on a schema with no @penv= header creates the project with development plus the environment pushed, and writes the header. Other environment commands: penv env.
Push values
penv push --env stagingpush sends every key with its decorators and its value from .env and .env.staging, then deletes those files once we confirm the write. .env.local and .env.staging.local stay on your machine.
| Flag | Effect |
|---|---|
--env <env> | The environment written to |
--org <slug> | The workspace that owns a project penv is about to create. First push only |
--prune | Deletes cloud keys the schema no longer lists. Human only: exit 2 (agent_session) in an agent session |
--prune deletes keys. Read the environment's key list in the console first.
Single values: penv set KEY --env staging.
Environment selection
--env, then PENV_ENV, then the key @currentEnv names, then development, for every command. See environments and precedence.
| Identity | Readable environments |
|---|---|
No @penv= header | Any environment, from .env.<env> on your machine |
| You, signed in | Those your role assignments reach |
| Machine credential | The one bound environment |
When we refuse an environment with 403, penv reports environment_refused, exit 6:
error: your account has no access to acme/api-gateway/production.
Ask an admin to give you a role on that environment in the console, or pick another with --env <name>.Production access
Production has no separate unlock. Access is a role scoped to the project or environment, which you grant on the project's Access page.
| Action | Permission |
|---|---|
| Open the Access page | member:read on the project |
| Grant or revoke a role | member:role_assign at the target scope |
Read values (penv run, penv pull) | secret:reveal on the environment |
List keys and decorators without values (?values=false) | secret:read on the environment |
A build can validate a schema with secret:read alone. We record every value read in the audit log with the credential, and the harness and session under a coding agent.
Procedure
Create the environment: penv env new staging, or the console.
Grant a role scoped to that environment on the project's Access page.
Put the values in .env.staging, or set them with penv set KEY --env staging.
Run penv check until it prints ok.
Run penv push --env staging.
Run penv run --env staging -- <command> to confirm the environment resolves.
Repeat for production once a holder of member:role_assign grants a role there.
.env file vs a secrets manager
Your .env file is a per-machine copy; a secrets manager is one store every machine reads. Comparison, when a file suffices, and the move with penv push.
Run your app locally
penv run layers your value files, validates them against your schema, masks secrets in the output, and starts one child process with them.