Demo: Private git source
Clone the private repo. Never see its key.
Pulling code from a private source is itself a credential risk: somewhere a token has to authenticate the clone. Enclave keeps that token on a single init-container's private HOME, hands the workload only the cloned tree, and proves — with a probe that hunts every gitconfig path — that the running code can't find it.
Overview#
Source
Everything on this page is summarised from the actual demo driver and its workload:
demo/src/scenarios/private-git.ts— the driver (request shape, assertions, evidence bundle)demo/src/scenarios/private-git/probe.py— the adversarial workload entrypoint
A git-sourced workload looks innocent: clone this repo, run its entrypoint. But a private repo has to be authenticated, and the obvious implementations leak. Bake the token into the clone URL and it lands in .git/config, in process listings, in git config --list. Set it in a global gitconfig and the workload — untrusted third-party code — reads it straight off disk. The credential that fetched the code becomes a credential the code can exfiltrate.
Enclave treats the clone and the workload as two different trust zones. The brokered git token is minted by the control plane, mounted into a clone init-container on a private HOME volume, and used to fetch the repo into a shared workspace. The workload pod that runs the cloned code mounts the workspace read-only and gets nothing else — no token env, no gitconfig, no .git directory. The token never touches the workload PodSpec or argv, and like every Enclave credential it is never returned to the caller.
[1m[36m▣ Enclave — "Clone the private repo. Never see its key."[0m
[2mbackend: kubernetes · baseUrl: http://127.0.0.1:8090[0m
[2msource: git http://192.168.1.120:36237/private-agent.git@main → probe.py · cred scopes: [git:read] (brokered + withheld)[0m
[32m✓ PASS[0m [1mclone private:true succeeded[0m
[2maudit: clone_started=true clone_completed=true private=true[0m
[32m✓ PASS[0m [1mcloned entrypoint ran as the workload and returned a result[0m
[2mphase=succeeded exitCode=0 durationMs=5779[0m
[32m✓ PASS[0m [1mworkload probe found NO git token (real execution)[0m
[2mprobed 12 locations · findings=[] · leaked=false[0m
[32m✓ PASS[0m [1mno git token in the workload's stdout/stderr[0m
[2mscanned 51 bytes of workload output[0m
[32m✓ PASS[0m [1mno token / eyJ on any public surface (session, result, audit)[0m
[2mscanned session + result + 7 audit events (2561 bytes)[0m
[1m[36m── money shot ──[0mArchitecture#
The token's blast radius is one container. The broker mints it into a Secret; the clone init-container is the only thing that mounts it (via env secretKeyRef) and the only thing with the private /githome HOME where the gitconfig lives. The arrow into the workload carries the cloned /workspace tree and the credential boundary — nothing token-shaped crosses it.
This is the gVisor-on-Kubernetes path: a separate init-container, a Secret mounted by secretKeyRef, and a private emptyDir for HOME — built in control-plane/src/backends/manifests.ts. The simulator models the same withholding contract; the Docker dev loop runs a clone in a local container (host kernel — a convenience, not a security boundary).
The request#
The caller never sees a git token — it passes credential scopes. A git workload source with credentialScopes tells the broker to mint a short-lived, scoped git credential for the clone; the public Session carries no token field, so the git credential cannot leak through it.
const req: CreateSessionRequest = {
language: "python",
egress: { mode: "deny_all", allow: [] },
source: {
kind: "git",
repo,
ref,
entrypoint,
language: "python",
// Marks the clone PRIVATE: the broker mints a scoped git token, injected on
// the init-container only. Its value is never returned to us.
credentialScopes: ["git:read"],
},
};The phase stream is the tell: a git source emits clone_started and clone_completed before running— the init-container's work, surfaced as audit events. The audit never echoes the clone log (it could carry the auth header); it records only that a private clone happened.
Inside the clone#
Here is the exact script the init-container runs. The token arrives in $GIT_CRED (from the Secret, via env) and is written into a gitconfig under the private HOME — never onto the clone URL, never onto argv. After the clone, .gitis deleted so no credential cache or remote config survives into the workload's tree.
/**
* The session Job: one gVisor-sandboxed pod that runs the runner image against
* the mounted code, under CPU/memory limits and a wall-clock deadline, with no
* service-account token, no host mounts, and a locked-down securityContext.
*
* For a git source (C1.3) an init-container shallow-clones the repo into a shared
* `workspace` emptyDir (which then replaces the code ConfigMap as the read-only
* /workload mount) and the workload runs the declared entrypoint from it.
*/
export function buildSessionJob(input: ManifestInput): V1Job {
const n = names(input.sessionId);
const git = input.gitSource;
// The runner image bundles the harness at /app; it execs the mounted workload,And the PodSpec wiring that makes the boundary structural: the git Secret and the private githome volume are mounted only on the init-container. The workload container mounts the cloned /workspace read-only and declares neither the Secret nor the HOME volume — so there is no path by which the token reaches the running code.
readOnlyRootFilesystem: true,
capabilities: { drop: ["ALL"] },
},
volumeMounts: [
{ name: "workspace", mountPath: "/workspace" },
// Private HOME/TMPDIR for the clone (holds the gitconfig with
// the token) — mounted ONLY here, never on the workload.
{ name: "githome", mountPath: "/githome" },
],
},
]
: []),
...(hasBindings(input) ? proxySidecar(input)! : []),
];
return inits.length > 0 ? { initContainers: inits } : {};
})(),
containers: [
{
name: "workload",
// A non-default Environment supplies a built image; else the runner (C3.1).
image: input.image ?? input.runnerImage,
command: runnerCmd,
// The workload writes outputs relative to CWD; default is the
// … 52 lines omitted …
// C2.2 — the binding-material Secret + the sidecar's writable tmp.
...(hasBindings(input) ? proxyVolumes(input)! : []),
],
},
},
},
};
}
/**
* The warm interactive session Pod (C1.1). Unlike the oneshot Job, this is a
* long-lived bare Pod whose PID-1 is a `sleep` pause: the backend then opens a
* k8s `exec` stream that runs `runner_kernel.py` as a single persistent process
* (the shared namespace), driving one turn per stdin frame. It deliberately does
* NOT use a Job — a Job's backoff/completion semantics are wrong for a process we
* drive over exec and reap from the orchestrator. The hardened defaults are
* byte-identical to the oneshot pod (runtimeClass, non-root, caps drop ALL,
* read-only rootfs, no SA token); the differences are: `stdin` held open for the
* exec attach, `restartPolicy: Never`, a `sleep` PID-1, and a generous
* `activeDeadlineSeconds` crash backstop (the orchestrator reaper is the primary "summary": {
"passed": 5,
"total": 5,
"failures": 0,
"backend": "kubernetes",
"repo": "http://192.168.1.120:36237/private-agent.git",
"ref": "main",
"entrypoint": "probe.py",
"privateClone": true,
"probeRan": true,
"auditTypes": [
"session_created",
"clone_started",
"clone_completed",
"sandbox_started",
"result_collected",
"workload_exited",
"usage_metered"
]
},
"checks": [The probe#
To prove the withholding rather than assert it, the demo's workload is the adversary. The repo's probe.pydoesn't do the repo's actual job — it hunts for the git credential in every realistic hiding place: gitconfig files (home, root, /githome, tmp, the workdir), the effective git config --list, the cloned .git directory, and the entire process environment.
import os
import re
import subprocess
TOKEN_RE = re.compile(r"(eyJ[\w-]+\.[\w-]+\.[\w-]+|Bearer\s+\S+|ghp_\w+|github_pat_\w+|x-access-token)", re.I)
GIT_HINT_RE = re.compile(r"(extraheader|credential\.helper|authorization|password|oauth|token)", re.I)
def _scan(label, text):
"""Return a finding dict if text smells like a credential, else None."""
if not text:
return None
tok = TOKEN_RE.search(text)
if tok:
return {"where": label, "match": tok.group(0)[:24] + "…"}
if GIT_HINT_RE.search(text):
# A gitconfig that mentions auth helpers is itself a leak signal.
return {"where": label, "match": "<git-auth-config-present>"}
return None
def _read(path):
try:
with open(os.path.expanduser(path), "r", errors="replace") as fh:
return fh.read()
except OSError:
return None
def main():
findings = []
probed = []
# 1. gitconfig in every place a clone might have stashed one.
for path in ("~/.gitconfig", "/root/.gitconfig", "/githome/.gitconfig",
"/tmp/.gitconfig", "./.gitconfig", "/workload/.gitconfig"):
probed.append(path)
hit = _scan(f"file:{path}", _read(path))
if hit:
findings.append(hit)
# 2. effective git config the workload can actually read.
probed.append("git config --list")
try:
cfg = subprocess.run(["git", "config", "--list"], capture_output=True,
text=True, timeout=5).stdout
hit = _scan("git-config-list", cfg)
if hit:
findings.append(hit)
except (OSError, subprocess.SubprocessError):
pass # no git in the sandbox is fine — nothing to leak
# 3. the cloned .git directory, if it survived into the workload tree.
for path in ("/workload/.git/config", "/workload/.git/credentials",
"/workload/.git/packed-refs", ".git/config"):
probed.append(path)
hit = _scan(f"gitdir:{path}", _read(path))
if hit:
findings.append(hit)
# 4. the process environment — GIT_ASKPASS, *_TOKEN, Authorization, etc.
# The git clone credential must NEVER reach the workload; this probe hunts
# for it across the environment. The sandbox carries no brokered secret of
# its own — only non-secret provenance (ENCLAVE_SESSION_ID).
probed.append("os.environ")
for k, v in os.environ.items():
if re.search(r"(token|askpass|auth|cred|secret|password|git_)", k, re.I):
hit = _scan(f"env:{k}", v)
if hit:
findings.append(hit)
elif TOKEN_RE.search(v or ""):
findings.append({"where": f"env:{k}", "match": "<token-shaped-value>"})
# Report. Print human lines (these show up in stdout) and a structured result.
if findings:
for f in findings:
print(f"[probe] LEAK at {f['where']}: {f['match']}")
else:
print(f"[probe] scanned {len(probed)} locations — no git token found")It reports the list of places it found anything token-shaped. The money shot is that the list is empty — and the demo additionally asserts that no eyJ…/Bearer string appears anywhere in stdout, the Session, the result, or the audit log.
enclave.result({ # noqa: F821 — injected by the runner harness
"probe": "git-credential-hunt",
"locationsProbed": len(probed),
"findings": findings,
"leaked": len(findings) > 0,
})[32m✓[0m clone private:true succeeded [2mhttp://192.168.1.120:36237/private-agent.git@main[0m
[32m✓[0m probe: no token found (12 locations, 0 findings)
[32m✓[0m git token: [1mNOT in env, NOT in gitconfig, NOT on any public surface[0m
[1m[32m✓ 5/5 checks — private repo cloned, entrypoint ran, the git key never left the broker.[0m
[2mevidence written to evidence/private-git-report.{json,md}[0mRun it#
The driver lives at demo/src/scenarios/private-git.ts. If ENCLAVE_BASE_URL is set it drives that running control plane (the gVisor/Kubernetes control plane the evidence here was captured on); otherwise it boots the in-process simulator. Either way it asserts the credential-withholding contract and writes an evidence bundle.
"demo:private-git": "tsx src/scenarios/private-git.ts",Honest boundary — Phase R
The live proof in the repo authenticates the clone against an in-cluster git server (a git-http-backend fixture for the Docker/e2e loops, a git daemon service on the gVisor e2e). The credential-withholding property is exercised end-to-end and asserted unconditionally. Cloning a remote forge over the public internet — egress to an external forge plus a live forge token — is the remaining Phase R piece; the init-container, the private HOME, and the Secret plumbing are already production-shaped.