Machine identity
Your CI and servers authenticate with a proof their platform already issues, which we exchange for a 15-minute credential. A machine takes no seat.
Your pipeline can present a proof its platform already issues instead of a stored key: we check it against the trust rule you stored and return a credential that expires in 15 minutes.
Credential kinds
| Prefix | Holder | Obtained by | Lifetime |
|---|---|---|---|
pcu_ | A person | penv login, approved in the browser | 30 days from last use, extended on every authenticated request, at most 90 days from sign-in |
pck_ | A machine | A token issued in the console, or an exchange | 15 minutes from an exchange |
penv logout revokes a pcu_.
A machine credential is bound to one project and one environment at creation and carries a role. We refuse a request naming any other environment. We store every machine credential hashed, always with an expiry.
Proof methods
The three methods are alternatives. Neither penv nor we fall back from one to another.
# GitHub Actions (id-token: write) or GitLab CI (ID_TOKEN): penv exchanges the job's token
penv run -- pnpm build
# Any other platform: a platform token, or a pck_ 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 console's one-time secret
penv machine enroll pce_example| Method | Host | Trust rule | Detail |
|---|---|---|---|
| Platform token (OIDC) | GitHub Actions, GitLab CI, Kubernetes and the rest of the 62 platforms in the connect catalog | Issuer, audience, one exact subject. Holds no secret | Subjects match exactly, never by wildcard. The audience is always your workspace id, so we refuse a token minted for another workspace |
| AWS role | An instance, task or function role | Account plus the role's immutable id | The workload signs an sts:GetCallerIdentity request; we replay it to AWS. Nothing secret leaves the host. A role recreated under the same name does not inherit the trust |
| Bound keypair | A plain VPS with no signed metadata | Ed25519 public key | The host holds the private key. Every login advances a counter both sides keep |
The audience must be your workspace id, the Organization ID under Settings, Organization. We refuse a workspace slug as audience (audience_not_workspace_id), because a workspace name is not unique. On GitHub Actions, exchange the token for PENV_TOKEN with the snippet Connect a Platform shows, or use the penv-run action; on GitLab CI penv reads ID_TOKEN. See GitHub Actions.
The keypair counter detects a copied key after the fact; it cannot prevent one. A stolen key authenticates once and advances the counter, then the real host arrives stale and both are locked out.
Credential lookup order
| Order | Source |
|---|---|
| 1 | PENV_TOKEN (a pck_) |
| 2 | Operating system keychain |
| 3 | Enrolled keypair |
| 4 | Platform token |
| 5 | AWS |
PENV_TOKEN wins over the keychain, so a container built from your developer image still uses the credential your pipeline supplied.
Billing
Machines never take a seat. We bill active human members only, with no per-identity or per-secret charge, so fifty pipelines cost the same as one. See seats.
Revoking
| Revoked | Effect |
|---|---|
| One credential | That credential stops. You can issue the identity a new one |
| The identity | Everything it holds stops at once |
| A leaked keypair | The keypair and every credential it minted |
A credential can revoke itself at the end of a job by calling the revoke route with only itself. The 15-minute expiry, not end-of-job cleanup, is what bounds a leaked credential.
Our audit entries name the identity as actor and keep the authenticating credential in metadata, so rotating a credential keeps one machine's history together.
Next: dynamic values.
Encryption in the cloud
We seal every value with AES-256-GCM under your workspace's data key, wrapped by a key in a key management service. We can decrypt to serve your machines.
Short-lived values
A dynamic key has no stored value. On request we ask the upstream system to mint a credential, record the lease, and let the credential expire.