Skip to main content
Everything envlink stores from your files is sealed: chunks and folder trees in an environment’s store, snapshots and artifacts in object storage, Bazel cache records on a node. Nothing at rest is readable without your project’s key.

The keys

  • A KMS key wraps each organization’s key, with the organization in the encryption context, so a wrapped key opens only as its own.
  • The organization key wraps each of its project keys, bound to the project’s name and version.
  • A project key is 256 random bits. Separate subkeys are derived from it with HKDF for chunk IDs, for content, and for authenticating records.
Keys are stored only wrapped. A node or a laptop holds the keys of the projects it’s wired to, in a file only envd can read, and no others.

Sealing

  • A chunk’s ID is an HMAC of its content under the project’s ID key. The same file has different IDs in different projects, so no one can tell whether a project holds a known file.
  • Each chunk is compressed when that helps, then sealed with AES-256-GCM under a key derived for that chunk alone. The same content in the same project seals the same way, so it’s stored once. The same content in two projects never matches.
  • Every chunk is checked against its ID when it’s read, so a store or a cache that serves the wrong bytes is caught.
  • Records whose content changes under one name, like Bazel cache entries, are sealed with a fresh nonce each time.

In transit

Everything between your sandbox and an environment crosses the tailnet, which is WireGuard, and is sealed as above. The API is HTTPS only.

Shredding a project

destroys the project’s key, its snapshot records and its artifacts. Anything still sealed under the key, in object storage, in a node’s cache or in a backup, can never be opened again. The next environment in the project gets a new key.