Docs
Conceptsince cloud@2026-09-10

How a machine logs in

Your CI or server proves who it is with something it already has, and it never takes a seat on your bill.

Your CI logs in like a person does, with no key to steal. The pipeline presents something the platform already gives it. penv checks that against a rule you wrote once and hands back a credential that dies in fifteen minutes.

The two kinds of credential

PrefixWho holds itHow it is obtainedHow long it lasts
pcu_A personpenv login, approved in your browser30 days from last use
pck_A machineA token you issue in the console, or an exchange15 minutes from an exchange

A person's credential extends itself on every authenticated request, so a laptop you use daily never signs in twice. penv logout revokes it.

A machine credential is bound to one project and one environment when it is created, and it carries a role. A request naming any other environment is refused. Every machine credential is stored hashed and always carries an expiry.

Three ways a machine proves itself

Which one you use depends on what the host can prove about itself. They are alternatives, and penv never falls back from one to another.

# GitLab CI: penv finds the runner's token in the job and exchanges it itself
penv run -- pnpm build

# GitHub Actions: the workflow asks the runner for the token and exchanges it,
# then hands the credential over. The GitHub Actions guide has the whole step.
PENV_TOKEN="$CREDENTIAL" penv run -- pnpm build

# Any other platform: hand penv the token, or a pck_ you issued in the console
PENV_OIDC_TOKEN="$RUNNER_MINTED_TOKEN" penv run -- pnpm build
PENV_TOKEN=pck_example penv run -- pnpm build

# A plain server, once: bind a keypair from the one-time secret the console showed you
penv machine enroll pce_example

A platform token (OIDC). GitHub Actions, GitLab CI, Kubernetes and the rest of the 32 platforms in the connect catalog mint a signed token that says which repository, ref or service account is running. On GitLab CI the token is already in the job, so penv finds it and exchanges it itself. On GitHub Actions the runner mints a token per audience on request, so the workflow asks for it with your workspace id as the audience, exchanges it, and passes the credential to penv in PENV_TOKEN. GitHub Actions has that step. You store a rule saying that a token from one issuer, addressed to your workspace, carrying one exact subject, is a given identity. The rule holds no secret. Subjects are matched exactly and never by wildcard, and the audience is always your workspace id, so a token minted for someone else's workspace cannot be used at yours.

An AWS role. The workload signs an sts:GetCallerIdentity call with its own instance, task or function role and sends the signed request to penv. penv replays it to AWS to learn who signed. Nothing secret leaves your machine. The rule matches the account plus the role's immutable id, so a role someone recreates under the same name does not inherit the trust.

A bound keypair. A plain VPS signs no metadata and has no secure element, so there is nothing to verify. The host holds an Ed25519 private key, penv holds the public half, and every login advances a counter both sides keep.

The counter detects a copied key after the fact. It cannot prevent one. A stolen key authenticates once, which advances the counter, and the real host then arrives stale and both are locked out. penv describes it that way everywhere it offers it.

PENV_TOKEN

PENV_TOKEN carries a pck_ and is how a pipeline or a container hands penv a credential. It takes precedence over anything in the operating system keychain, so a container that inherits a developer's image still uses the credential the pipeline gave it.

The binary looks for a credential in this order: PENV_TOKEN, then the keychain, then an enrolled keypair, then a platform token, then AWS.

Machines never take a seat

Three people free. Machines never take a seat. Your bill counts active human members of the workspace and nothing else. There is no per-identity or per-secret charge, so wiring up fifty pipelines costs the same as wiring up one.

Revoking

What you revokeWhat stops
One credentialThat credential. The identity can be given a new one
The identityEverything it holds, at once
A leaked keypairThe keypair and every credential it minted

A credential can also destroy itself at the end of a job by calling the revoke route with nothing but itself. That shortens the usual case. What bounds a leaked credential is the fifteen-minute expiry, and penv says so rather than treating end-of-job cleanup as the guarantee.

The record names the identity that read a value. The credential it authenticated with sits in the entry's metadata, so rotating a credential keeps one machine's history in one place.

Next: short-lived values.