What the server can see
The server can open your values, and this page says exactly what that reaches and what it does not.
Penv Cloud keeps your values on a server, and that server can open them. The sentence lives on encryption in the cloud with the mechanism behind it. This is not zero knowledge, and penv does not describe it as such anywhere.
This page is what that choice reaches, so you can answer a security questionnaire from it.
What the server can open
The server can open any value in your workspace, because it has to hand values to your machines and show one in an audited reveal. Two things follow.
Plaintext exists in memory on the compute that runs the decrypt path, for the length of one request.
It is never written to a log, an error, a URL or a response outside that path. Values carry a type
whose serializers print [redacted], so printing one to a console yields that string rather than
the value.
Reading a value is an explicit call, and it is the only way through. Everything that reaches a customer's value lands an entry naming who asked and what they touched.
What a database reader gets
Someone holding the database gets ciphertext plus metadata. They do not get values, because the wrapping key lives in a key management service and never lands in a row.
| They get | They do not get |
|---|---|
| Sealed value bytes, the wrapped data key, the id of the key that wrapped it | Any value, and any unwrapped data key |
| Key names, paths, project and environment names, timestamps | The wrapping key, which never leaves the key service |
| Password hashes, one way | Any password |
| Machine credentials as sha256 hashes and nothing else | Any machine credential that would still authenticate |
Moving a sealed row somewhere else does not help them. The seal is bound to the value's own address built from ids, so a row dropped into another environment or another workspace will not open.
What penv never keeps at all
- A dynamic value's minted credential. The lease table has no column to write one into.
- An unwrapped data key in any cache. Standing your own key down takes effect on the next call.
- A copy of your local
.envafterpenv push. That command deletes the file once the values land. - A value inside an audit entry, a key's contents, or a third party's response body.
Holding the wrapping key yourself
Enterprise workspaces can point penv at a key they own, in AWS KMS, Google Cloud KMS, Azure Key Vault or HashiCorp Vault Transit. Disabling that key ends the server's ability to open your values on the next call, because there is no cache of unwrapped keys anywhere.
A key id the server cannot place is refused outright. "The customer key failed, fall back to the platform key" is not something the system can express. See your own key.
Where plaintext leaves our own boundary
One subprocessor holds plaintext values in memory, because it runs the compute that decrypts them. The subprocessor register names it and says so per row rather than claiming "none" across the board.
What this does not protect against
Anything running inside the process that received a value can read that value. penv run puts values
in one child process and nowhere else, and that child is yours. A malicious dependency inside it, or
a malicious step beside it in the same CI job, is inside the boundary. See
values in a CI build.
Two more limits, stated rather than implied.
A person holding a valid credential with a role that grants a read gets the value, and the record shows they did. Detection is what the log gives you, and it arrives after the read.
A copied host key on a plain VPS authenticates once before both sides lock out. That is detection rather than prevention, and it is described that way on a host that proves nothing.
Next: values in a CI build.