Penv Cloud
Start free
Docs
Referencesince 1.0.0-alpha.3

The variables penv reads

Every variable penv 1.0.0-rc.1 and its installers read, what each changes, the masking triggers, and what a child process of penv run receives.

Variables penv 1.0.0-rc.1 reads. Project settings live in .penv/config.toml; flags are on each command page and on global options.

penv

VariableEffect
PENV_ENVEnvironment a command reads when --env is absent; wins over the @currentEnv key. Precedence: environments and precedence.
PENV_TOKENYour pck_ machine credential. Read before the OS keychain and every other credential source (machine identity).
PENV_URLOur address, used instead of https://penv.cloud and before [providers.penv] url. https anywhere; plain http only for 127.0.0.1, localhost and [::1], otherwise bad_url.
PENV_OIDC_TOKENA platform token exchanged as it stands, for any platform not listed below or a self-minted token.
PENV_BUNDLE_KEY64 hex characters. penv run opens .penv/<env>.bundle from penv bundle with it instead of reading from us.
PENV_LOCAL_KEY64 hex characters: the key for enc:v1: values (penv encrypt) on a machine with no keychain. With neither this nor a keychain, penv keeps the key in penv/local.key under XDG_CONFIG_HOME (default $HOME/.config), or APPDATA on Windows.
SSL_CERT_FILEA PEM bundle penv trusts instead of its compiled-in Mozilla roots, for a network that inspects TLS. Under an agent, cloud commands refuse a bundle you own or can write as untrusted_ca_bundle.
NO_COLORAny non-empty value turns color off.
CLICOLOR0 turns color off; other values change nothing.

Platform credentials

VariableSet byEffect
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYAWS runtimeBoth present: penv offers the machine's AWS identity as a credential.
AWS_SESSION_TOKENAWS runtimeCarried into the signed request when a role supplied one.
AWS_REGIONAWS runtimeSTS region penv signs against.
AWS_DEFAULT_REGIONAWS runtimeRead when AWS_REGION is unset. Neither means us-east-1.
AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARNEKS IRSABoth present, and no AWS keys: penv exchanges the token file with STS for keys.
AWS_ROLE_SESSION_NAMEEKS IRSASTS session name; default penv.
AWS_ENDPOINT_URL_STS, then AWS_ENDPOINT_URLYouSTS endpoint for that exchange.
AWS_CONTAINER_CREDENTIALS_RELATIVE_URIECSTask role credentials from the ECS endpoint, tried after web identity.
AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_CONTAINER_AUTHORIZATION_TOKEN, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILEEKS Pod IdentityCredentials from that endpoint: https, loopback, or the ECS and EKS link-local hosts only.
ACTIONS_ID_TOKEN_REQUEST_URL, ACTIONS_ID_TOKEN_REQUEST_TOKENGitHub ActionsBoth present: penv mints a GitHub Actions token for the workspace.
ID_TOKENGitLab CIA platform token penv exchanges as it stands. The retired CI_JOB_JWT_V2 is ignored.

Order: PENV_TOKEN, your login, an enrolled keypair, a platform token, then AWS keys, web identity and container. Per-platform setup: connect. Exchange details: API authentication.

Agent detection

"Set" means set and not 0 or false.

VariableAgent named
AGENTamp names Amp outright; any other name on penv's list is a weaker match.
COPILOT_CLI (set)Copilot
CLAUDE_CODE_CHILD_SESSION, CLAUDECODE (set)Claude Code
CODEX_THREAD_ID, CODEX_SESSION_ID (present)Codex
GEMINI_CLI (set)Gemini
CURSOR_SANDBOX, CURSOR_AGENT (present)Cursor
CLINE_ACTIVE (set)Cline
ROO_ACTIVE, ROO_CLI_RUNTIME (set)Roo
OR_APP_NAME = Aider, any caseAider
PS1 holding ###PS1JSON###OpenHands
AI_AGENTShared convention; parsed as name_version_mode or name@version.

Detection is a ladder: the first matching row wins, so colliding variables still resolve to one name. Order and agent behavior: coding agents.

Session id variableAgent
CLAUDE_CODE_SESSION_IDClaude Code
CODEX_THREAD_ID, then CODEX_SESSION_IDCodex
CURSOR_TRACE_IDCursor
AMP_CURRENT_THREAD_ID, then AGENT_THREAD_IDAmp
COPILOT_AGENT_SESSION_IDCopilot

penv stamps the session id on every request it sends us.

Masking

TriggerEffect
Any penv runMasking on by default, including inside Node, Bun, Deno and Python through a preload (--no-preload skips it).
A detected agentJSON output, masking on.
--agentSame treatment, on purpose (global options).
stdout not a terminal and GIT_EDITOR set to an editor that cannot prompt (true, cat)Session recorded as non-interactive, masking on, no agent named. penv reveal and penv pull behave as for a person.
penv run --no-maskMasking off; human only (penv run).

What masking covers: keep agents out of .env.

Detection reads variables any process can set or unset, so it only changes defaults. penv guard writes refusals into the harness's own settings.

System

VariableEffect
PATHLookup for the penv run command and a language target's toolchain.
PATHEXTRunnable suffixes on Windows, so tsc finds tsc.cmd.
HOME~/.penv for target and guard lookup; cache and local key directory on macOS and Linux.
USERPROFILE~/.penv on Windows when HOME is unset.
LOCALAPPDATA, APPDATAEncrypted cache and local key file on Windows.
XDG_CACHE_HOME, XDG_CONFIG_HOMEEncrypted cache (default $HOME/.cache) and local key file (default $HOME/.config) on Linux.
COMPUTERNAME, then HOSTNAME, then HOSTMachine name on a reveal approval page. Without all three: /etc/hostname, then "the penv CLI".

Installers

VariableInstallerEffect
PENV_VERSIONBothPin a release tag such as v1.2.3.
PENV_INSTALL_DIRBothInstall directory.
PENV_RELEASE_BASEBothRelease address; used by installer tests. The binary has one compiled address.
PENV_TARGETinstall.shInstall for another target triple.
PENV_ALLOW_ROOTinstall.sh1 installs as root (refused by default).
PENV_ALLOW_ELEVATEDinstall.ps11 installs from an elevated shell (refused by default).
PENV_ADD_TO_PATHinstall.ps11 writes the user PATH; the only way when piping through iex.
SHELLinstall.shWhich PATH line is printed. No startup file is edited.
TMPDIRinstall.shScratch directory; default /tmp.
PROCESSOR_ARCHITEW6432, then PROCESSOR_ARCHITECTUREinstall.ps1Processor for the target triple, read only when the registry value is missing. The first wins because an x64 shell on ARM64 reports AMD64.

Usage: install the CLI.

PENV_SIGNING_KEY (release workflow secret, read by an unpublished signing tool) and PENV_BLESS (rewrites test snapshots) exist in the penv repository; nothing that ships reads them.

Child process of penv run

ReceivesDetail
penv's own environmentInherited as it stands.
Every resolved keyFrom your value files in local mode; from us, or a bundle, in cloud mode. A key left empty takes its schema default.
PENV_ENVThe environment this run read.
Preload variablesWith masking on: PENV_SENSITIVE, and NODE_OPTIONS, BUN_OPTIONS and PYTHONPATH extended, never replaced.
ColorFORCE_COLOR=1 and CLICOLOR_FORCE=1 when penv pipes output at a terminal, unless set or NO_COLOR is.
Sealed runHTTPS_PROXY, HTTP_PROXY, empty NO_PROXY, NODE_USE_ENV_PROXY=1, and a CA bundle in SSL_CERT_FILE, REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE, AWS_CA_BUNDLE, NODE_EXTRA_CA_CERTS and DENO_CERT.
Does not receiveDetail
Missing required keyspenv run exits 3 before starting anything.
PENV_LOCAL_KEY, PENV_BUNDLE_KEYpenv removes both.
Unread outputWith masking on, penv pipes stdout and stderr and scrubs every value not marked public that is four characters or longer; shorter ones get a warning.

In cloud mode penv run writes values to disk only for random() keys, into .env.local (.env.test.local for test). Its cache of your values is encrypted with a key in the OS keychain; a host with no keychain gets no cache.

Apart from the two keys above, penv removes nothing it inherits: a PENV_TOKEN in your shell reaches the child. Set a pipeline credential on the step that needs it, not the whole job (CI builds).

Next: error codes.