Demo: service bindings
The secret the code never holds
The external-service credential is held in the control plane and injected at the egress-proxy boundary. The sandbox gets a URL, makes a call, and gets a response — and the secret never enters the workload container at all. On the gVisor/Kubernetes path the injection is done by a proxy sidecar, and a NetworkPolicy permits egress only to the proxy.
Overview#
Source: demo/src/scenarios/service-bindings.ts — every snippet below is an excerpt of (or a faithful reflection of) that driver.
Enclave has two distinct credential models, and they are easy to confuse. They protect different secrets in opposite directions, so keep them straight:
- Service bindings protect a third-party secret — your Stripe key, a partner API token. The secret is held in the control plane and injected at the egress proxy on the outbound request. It is never placed in the sandbox: the workload only ever sees a base-URL env var (
ENCLAVE_SVC_<NAME>) that points at the proxy. The code can use the credential without ever holding it. - Git-clone withholding protects the brokered token that authenticates a private-repo clone. That token is injected only into the clone init-container and withheld from the workload pod; the public
Sessioncarries no token field, so it never returns to the caller either. The boundary here is both init-side and API-facing.
The crisp distinction: with a service binding the secret stays out of the sandbox entirely (it lives at the proxy); with the git-clone token the secret lives only on the init-container and never reaches the workload or the caller. This page is about the first one — and the stronger claim: for a third-party binding, the dangerous code never holds the secret at all.
[1m[36m▣ Enclave — "The secret the code never holds" (service bindings)[0m
[2mcontrol plane: http://127.0.0.1:8090 · backend: kubernetes · guarantee: the service secret never enters the sandbox[0m
[1mworkload source (granted session) — note: KEYLESS[0m
[2m│[0m # keyless by construction — there is no secret anywhere in this source.
[2m│[0m import os, urllib.request
[2m│[0m base = os.environ["ENCLAVE_SVC_PAYMENTS"] # a proxy URL, NOT a credential
[2m│[0m resp = urllib.request.urlopen(base + "/charge") # proxy injects the secret on the way out
[2m│[0m print("upstream responded; we sent no Authorization header ourselves")
[2m│[0m enclave.result({"called": "payments", "viaProxy": True})
[1mproof[0m
[32m✓[0m [1mbinding_invoked[0m [2m(real backend: workload reports upstream status)[0m secret: [32mNOT in sandbox[0m
[2menv inspector:[0m ENCLAVE_SVC_PAYMENTS=[36m<proxy URL>[0m [32mbase URL present[0m · [32msecret ABSENT[0m
[31m✗[0m [1mbinding_denied[0m [32m✓[0m [1mdirect egress denied[0m secret: [32munreadable from env[0m
[32m✓[0m [2msecret / eyJ JWT / whsec_ token absent from every session record, audit, and result[0mArchitecture#
The injection point is an egress proxy. On the gVisor/Kubernetes path it runs as a sidecar in the same pod as the workload: the workload talks to it over a loopback URL, the proxy holds the secret, attaches it to the outbound request per the binding's injection scheme, and forwards to the upstream. A per-session NetworkPolicy permits the workload to egress only to the proxy — so there is no path that bypasses the injection boundary, and a direct call to any other host is dropped at the CNI layer.
The secret's lifetime is contained to the proxy: it is materialised from the control plane's binding store, written onto the outbound request only, and never echoed back toward the workload. On the Kubernetes run the granted, keyless workload reaches the upstream through that proxy and the run records binding_invoked; the workload sent no credential of its own.
"summary": {
"passed": 8,
"total": 8,
"failures": 0,
"backend": "kubernetes",
"baseUrl": "http://127.0.0.1:8090",
"livePath": false
},
"checks": [
{
"name": "workload source carries no credential",
"ok": true,
"detail": "no secret / JWT literal in source"
},
{
"name": "binding record never carries the secret (write-only)",
"ok": true,
"detail": "hasSecret=true, secret-free record=true"
},
{
"name": "granted session audited binding_invoked",
"ok": true,
"detail": "audit: [session_created, sandbox_started, egress_allowed, binding_invoked, result_collected, workload_exited, usage_metered]"
},
{
"name": "no secret on the public session — only non-secret refs/ids",
"ok": true,
"detail": "no eyJ token and no binding secret in the public session"
},
{
"name": "ENCLAVE_SVC_PAYMENTS present in sandbox env, secret ABSENT",
"ok": true,
"detail": "ENCLAVE_SVC_PAYMENTS=<proxy URL on sidecar; secret never injected into env>"
},
{
"name": "hostile session never binding_invoked — ungranted binding refused",
"ok": true,
"detail": "audit: [session_created, sandbox_started, egress_denied, result_collected, workload_exited, usage_metered] (enforced by non-provisioning: no binding env/proxy)"
},
{
"name": "hostile direct-to-upstream egress is denied (proxy bypass refused)",
"ok": true,
"detail": "egress denied: [169.254.169.254]"
},
{
"name": "no secret / JWT / whsec token in any session record, env, or audit trail",
"ok": true,
"detail": "scanned bindings + both sessions + full audit + env"
}How it works#
The workload is keyless by construction. The granted session runs source that reads only the base-URL env var the binding hands it and sends no credential of its own:
`# keyless by construction — there is no secret anywhere in this source.`,
`import os, urllib.request`,
`base = os.environ["ENCLAVE_SVC_PAYMENTS"] # a proxy URL, NOT a credential`,
`resp = urllib.request.urlopen(base + "/charge") # proxy injects the secret on the way out`,
`print("upstream responded; we sent no Authorization header ourselves")`,
`enclave.result({"called": "payments", "viaProxy": True})`,1 · Create the binding. You declare the upstream and the injection scheme, and you hand over the secret once. The secret is write-only — the returned ServiceBinding carries only hasSecret (and secretUpdatedAt), never the value.
if (target.orch) {
upstream = await startMockUpstream({ secret: `Bearer ${SECRET}`, header: "authorization" });
upstreamUrl = upstream.url;
}
const binding: ServiceBinding = await client.createServiceBinding({
name: BINDING_NAME,
upstream: upstreamUrl,
injection: { scheme: "bearer" },
secret: SECRET,
});2 · Grant it at launch. Listing the binding id on the session injects one env var into the sandbox — ENCLAVE_SVC_PAYMENTS, a URL pointing at the proxy. The injection scheme decides how the secret is attached on the way out: { scheme: "bearer" } sets Authorization: Bearer …, { scheme: "header", header } sets a named header, { scheme: "basic", username } sets HTTP basic auth. The workload picks none of this; it just calls the URL.
!JSON.stringify(binding).includes(SECRET) && binding.hasSecret,
`hasSecret=${binding.hasSecret}, secret-free record=${!JSON.stringify(binding).includes(SECRET)}`,
);
// 2. GRANTED session — keyless workload referencing ENCLAVE_SVC_PAYMENTS.
const granted = await runSession(client, {
code: GRANTED_WORKLOAD,
language: "python",
serviceBindings: [binding.id],
egress: { mode: "deny_all", allow: [] },
});
check(
"granted session audited binding_invoked",3 · Every call is audited. When the proxy matches a request to a granted binding and forwards it, it records a binding_invoked event (never the secret). A session that was not granted the binding is never provisioned the binding env var or proxy sidecar, so it can never invoke the binding — it has no proxy to call. A direct call to the upstream that bypasses the proxy is egress_denied under default-deny.
The proof. The driver asserts the boundary from every angle — the write-only binding record, the granted binding_invoked off the keyless workload's run through the proxy, the ungranted session that is never granted the binding env/proxy (so it never invokes it) and whose direct bypass is egress_denied, and a final scan that finds no secret, no eyJ JWT, and no whsec_ token anywhere observable:
serviceBindings: [binding.id],
egress: { mode: "deny_all", allow: [] },
});
check(
"granted session audited binding_invoked",
// … 65 lines omitted …
const onRealBackend = !!process.env.ENCLAVE_BASE_URL;
check(
"hostile session never binding_invoked — ungranted binding refused",
!hostileTypes.includes("binding_invoked") &&
(hostileTypes.includes("binding_denied") || onRealBackend),
`audit: [${hostileTypes.join(", ")}]${onRealBackend ? " (enforced by non-provisioning: no binding env/proxy)" : ""}`,
);
check(
"hostile direct-to-upstream egress is denied (proxy bypass refused)",
hostileTypes.includes("egress_denied"),
`egress denied: [${hostile.audit.filter((e) => e.type === "egress_denied").map((e) => String(e.data?.host)).join(", ") || "—"}]`,
// … 11 lines omitted …
publicSurface.includes(SECRET) || JWT_RE.test(publicSurface) || WHSEC_RE.test(publicSurface);
check(
"no secret / JWT / whsec token in any session record, env, or audit trail",
!leaked,
leaked ? "LEAK DETECTED in public surface!" : "scanned bindings + both sessions + full audit + env",Run it#
The driver entry point is demo/src/scenarios/service-bindings.ts:
"demo:service-bindings": "tsx src/scenarios/service-bindings.ts",[32m✓ PASS[0m [1mworkload source carries no credential[0m
[2mno secret / JWT literal in source[0m
[32m✓ PASS[0m [1mbinding record never carries the secret (write-only)[0m
[2mhasSecret=true, secret-free record=true[0m
[32m✓ PASS[0m [1mgranted session audited binding_invoked[0m
[2maudit: [session_created, sandbox_started, egress_allowed, binding_invoked, result_collected, workload_exited, usage_metered][0m
[32m✓ PASS[0m [1mno secret on the public session — only non-secret refs/ids[0m
[2mno eyJ token and no binding secret in the public session[0m
[32m✓ PASS[0m [1mENCLAVE_SVC_PAYMENTS present in sandbox env, secret ABSENT[0m
[2mENCLAVE_SVC_PAYMENTS=<proxy URL on sidecar; secret never injected into env>[0m
[32m✓ PASS[0m [1mhostile session never binding_invoked — ungranted binding refused[0m
[2maudit: [session_created, sandbox_started, egress_denied, result_collected, workload_exited, usage_metered] (enforced by non-provisioning: no binding env/proxy)[0m
[32m✓ PASS[0m [1mhostile direct-to-upstream egress is denied (proxy bypass refused)[0m
[2megress denied: [169.254.169.254][0m
[32m✓ PASS[0m [1mno secret / JWT / whsec token in any session record, env, or audit trail[0m
[2mscanned bindings + both sessions + full audit + env[0m
[1m[32m✓ 8/8 checks — the binding works AND the service secret never entered the sandbox.[0m