Docs
Guidesince cloud@2026-09-10

Your first workspace

The first fifteen minutes in the console, from your first project to the values inside it.

A workspace holds projects. A project holds environments. An environment holds the keys your app reads. Start with one of each.

Create a project and an environment

penv push

When .env.schema carries no @penv= header, penv prints what it is about to create. It creates that project with a development environment and writes the slug the server returned into the header. Slugs are derived from names on the server. An address that could mean two things is refused rather than guessed.

Set a value

penv set STRIPE_SECRET_KEY

penv prompts for the value and never echoes it. Piping works the same way, so a script can write one without it landing in your shell history.

What the sidebar holds

A row you cannot use is a row you do not see. The same permission gates the page behind it, and a group whose rows are all hidden disappears with them.

RowWhereShown when you hold
Overview/dashboardany permission at all
Projects/projectsproject:read
Machine Identities: All Identities/identitiesmachine:read
Machine Identities: Connect a Platform/identities/connectmachine:create
Integrations: Connections/integrationsintegration:read
Integrations: Dynamic Engines/integrations/dynamicdynamic:read
Integrations: Providers/integrations/providersintegration:read
Audit Log/auditaudit:read
Billing/settings/billingbilling:read
Encryption/settings/encryptionorg:read
Settings: Organization/settings/organizationorg:read
Settings: Members/settings/membersmember:read
Settings: Roles/settings/rolesrole:read
Settings: Security/settings/securityorg:read
Settings: Single Sign-On/settings/ssosso:read
Settings: Danger Zone/settings/dangerorg:read

Machine Identities, Integrations and Settings are the three groups. They open to reveal the rows under them and have no page of their own.

Somebody who holds nothing anywhere in the workspace is sent to /no-access instead of a console, because every surface behind the rail would refuse them.

Approve a terminal

penv login prints an eight-character code in two groups, XXXX-XXXX. The /device page asks for that code and shows the device name and the address it came from before you approve or deny it. The code lasts ten minutes.

Approving asks you to confirm it is you (step-up) when you carry an authenticator. Denying never does, because shutting down a code you did not start should be one click.

Only approve a code you just saw in your own terminal. The page shows the device and the address so you can tell your own sign-in from somebody else's.

Answer a reveal

When a coding agent runs penv reveal KEY, it gets an approval id and exit code 4 back. The value is never in that answer.

A person opens /approvals/<id> and sees the key, the project and environment, who asked, the device, the harness and the session id. The request expires in ten minutes. Answering it needs secret:reveal at that environment, the same grant that would let you open the key yourself, and then confirming it is you (step-up).

Every reveal is written down with who, what, and when. One approval is four rows in the audit log:

  • secret.reveal_requested, the agent's ask
  • secret.reveal_approved or secret.reveal_denied, your answer
  • secret.read, the read itself
  • secret.reveal, naming you beside the session that asked

A redemption the server turns away adds a fifth, secret.reveal_refused.

Invite the rest of the team

Settings then Members adds people, and Roles decides what each of them may reach. Three people free. Machines never take a seat, so a pipeline or a server never shows up on the invoice.

Connect your CI