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 pushWhen .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_KEYpenv 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.
| Row | Where | Shown when you hold |
|---|---|---|
| Overview | /dashboard | any permission at all |
| Projects | /projects | project:read |
| Machine Identities: All Identities | /identities | machine:read |
| Machine Identities: Connect a Platform | /identities/connect | machine:create |
| Integrations: Connections | /integrations | integration:read |
| Integrations: Dynamic Engines | /integrations/dynamic | dynamic:read |
| Integrations: Providers | /integrations/providers | integration:read |
| Audit Log | /audit | audit:read |
| Billing | /settings/billing | billing:read |
| Encryption | /settings/encryption | org:read |
| Settings: Organization | /settings/organization | org:read |
| Settings: Members | /settings/members | member:read |
| Settings: Roles | /settings/roles | role:read |
| Settings: Security | /settings/security | org:read |
| Settings: Single Sign-On | /settings/sso | sso:read |
| Settings: Danger Zone | /settings/danger | org: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 asksecret.reveal_approvedorsecret.reveal_denied, your answersecret.read, the read itselfsecret.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.