Docs
Conceptsince cloud@2026-09-24

Write-only environments

Values in a write-only environment can be set and rotated, and only workload identities read them back. People and static tokens get the key marked redacted.

A write-only environment withholds its values from people. They are still delivered to deploys and CI.

Who reads a value

CallerGets
Credential exchanged from OIDC, AWS IAM or a bound keypairThe value
Integration sync to its destinationThe value
Console, penv login credential (pcu_)redacted
Static pck_ token issued in the consoleredacted
Reveal approvalRefused before anyone is asked

A static token counts as a person: anyone who can copy it can read with it. Move CI and servers to an exchange before you turn this on.

Who may add a workload

A workload reads this environment's values, so adding one needs what turning write-only off needs.

Action on a write-only environmentNeeds
Add an OIDC or AWS trust, bind a keypairenvironment:update, two-factor authentication and a fresh step-up
Connect a CI platform or a GitHub repositoryThe same

Trusts and keypairs that exist when you turn write-only on keep reading. Review them under Machine identities first (machine identities).

Writes are unaffected. penv set, penv push and the console still set and rotate values. They can never show a value back.

Turn it on

Project, environment, Write-only. Pro and Enterprise (plans).

ActionNeeds
Turn onenvironment:update and a plan that includes it
Turn offenvironment:update, two-factor authentication and a fresh step-up, on any plan
New environment named productionOn by default, on Pro and Enterprise
Duplicate a write-only environmentThe copy is write-only

After a downgrade it stays on until someone turns it off.

What penv pull writes

penv pull writes a marker, not a value, for each withheld key:

penv pull --env production
LOG_LEVEL=info
# penv:redacted DATABASE_URL
# penv:redacted STRIPE_KEY

The marker is a comment, so no dotenv loader reads it as a value. With the @penv= header removed (local mode), penv still refuses to run without the key:

penv --json run --env production -- node server.js
{
  "error": "redacted",
  "message": "DATABASE_URL in production is write-only in penv-cloud.",
  "fix": "Set DATABASE_URL in .env.production.local. penv-cloud keeps the production value write-only."
}

A value in .env.production.local overrides the marker (value files).

What a person sees

SurfaceResult
penv run, penv bundleRefused with redacted, exit 6, naming every key
penv check, penv ls, penv whyThe key is present and redacted, never missing
penv revealRefused, exit 6
Console value cellWrite-only badge; the pencil still sets a new value
Console exportRedacted keys are named and left out of the file
GET /api/v1/envs/...The key with its schema and "redacted": true, and "writeOnly": true on the body
Read a secret409 redacted
Bulk readThe key in redacted, apart from skipped

redacted is never an absence. The value exists; do not overwrite it.

Audit

ActionRow
Turn on, turn offenvironment.write_only_enabled, environment.write_only_disabled
A value withheld from a callersecret.read_redacted, one per key

The audit log.

Encryption

Write-only controls who can read a value. It does not change how the value is encrypted: every environment uses the same envelope (encryption in the cloud). We can still decrypt the value to deliver it to a workload, so this is not zero-knowledge.