Skip to main content
“Secrets that can’t leak” is a real guarantee with a precise shape. This page describes exactly how it works and, just as important, what it does and does not protect against. For the configuration surface like binding secrets, allow lists, and placeholders, see Secrets.

The idea

Instead of putting a real credential inside the VM, microsandbox puts a placeholder there. The real value stays in host memory. When the guest sends a request to a host you’ve allowed, the host-side network stack swaps the placeholder for the real value at the network boundary, on the way out. Anywhere else, the placeholder is just a meaningless string. So a workload can call an API with a credential it never actually holds.

The data flow

  1. You bind a secret to an environment variable and list the hosts it’s allowed for.
  2. The guest’s environment receives a placeholder ($MSB_<env_var> by default), never the real value.
  3. The workload uses the placeholder as if it were the credential, in a header, auth field, query string, or body.
  4. On egress to an allowed host, the host-side proxy decrypts the intercepted TLS, verifies the request is really going where it claims, substitutes the real value, and forwards it upstream.
  5. The upstream server receives the real credential. The guest never did.
A placeholder becomes the real secret only at an allowed host; any other host receives only the placeholder.

What gates a substitution

A placeholder only becomes a real value when every one of these holds. They use the same DNS and SNI machinery the network page describes:
  • Allowed-host match. The TLS SNI matches one of the secret’s allowed host patterns.
  • DNS pin. The destination IP was actually resolved for that host through the interceptor, so a hard-coded IP with a forged SNI doesn’t qualify.
  • TLS identity. By default a secret requires intercepted TLS, so it is never substituted over a connection the host can’t see into.
  • Authority alignment. For intercepted HTTP, the request’s Host or :authority must match the SNI, which closes domain-fronting.
If any check fails, the placeholder is left untouched. The request goes out carrying a useless string, or it’s blocked, depending on your policy.

What this protects

  • The credential cannot leak to a host you didn’t allow. Send the placeholder to evil.com and evil.com receives the placeholder, not the secret.
  • A captured guest is worthless for the secret. A memory dump, a leaked image, or a malicious process inside the VM will only ever find the placeholder.
  • Hard-coded-IP and SNI-spoof exfiltration attempts don’t receive the injection at all, because they fail the DNS pin or authority checks.

What this does not protect

Being candid about the edges matters more than the headline.
  • The allowed endpoint receives the real credential. This stops exfiltration to other hosts. It does not stop the host you explicitly allowed from misusing what you sent it. Keep allow lists narrow.
  • It needs TLS interception for that host. Over a bypassed-TLS domain, or plain HTTP with the default TLS-identity requirement on, no substitution happens. That’s by design, since the host can’t verify where opaque traffic is really going. You can opt a secret into plain-HTTP injection, but it’s weaker and not recommended.
  • A few content shapes aren’t rewritten. Placeholders inside HTTP/2 request bodies, non-identity-encoded (for example gzipped) bodies, or very large fixed-length bodies aren’t substituted. When an injection is eligible but can’t be substituted safely, the request is blocked rather than sent wrong.
  • Real values live in host process memory. They’re held as plain strings for the sandbox’s lifetime and aren’t specially zeroized. Anyone who can read the host process’s memory is already on the trusted side of the boundary, and host compromise is out of scope for the model.

Where the values live

Real secret values exist only in the host process, only for the sandbox’s lifetime. They are never written to the guest’s environment, the guest’s disk, or a snapshot. When the sandbox stops, they’re gone.

See also