#!/usr/bin/python3 # git-credential-mosaic — production entrypoint (P0-SEC R4, rev-code-02 B1). # # WHY THIS IS NOT BASH: three review rounds falsified every in-bash startup # guard. A non-interactive bash sources $BASH_ENV and imports exported # functions BEFORE the first script line, so read(), unset(), exit(), # declare(), printf() — every callable — can be shadows that fake the # ancestry, defeat the scrub, or forge diagnostics (rev-code-02 probes 1 and # 2, artifacts fc49e9d9 lineage). No in-language dispatch survives that. # # This entrypoint is unshapable at the bash level: python does not read # BASH_ENV and imports no bash functions, and the interpreter is pinned by # absolute shebang (no PATH resolution). It builds the child environment BY # ALLOWLIST and execve's the bash implementation directly — the child bash # starts with no BASH_ENV, no BASH_FUNC_*, no SHELLOPTS/BASHOPTS, and exactly # the variables the credential protocol needs. stdin/stdout/stderr and argv # pass through untouched. # # The implementation file (git-credential-mosaic.impl) refuses to run without # the clean-mode marker, so it cannot be invoked directly as a shaped-entry # bypass of this wrapper. import os import sys IMPL = os.path.join(os.path.dirname(os.path.realpath(__file__)), "git-credential-mosaic.impl") # Absolute-path candidates ONLY — never PATH resolution (an attacker-shaped # PATH must not choose the interpreter). /usr/bin/bash is the fleet-host # layout; /bin/bash is alpine and other FHS variants (found by the T125 # gateway-image verification: the hardcoded /usr/bin/bash made every call # exit 127 inside node:22-alpine). BASH_CANDIDATES = ("/usr/bin/bash", "/bin/bash") BASH = next((p for p in BASH_CANDIDATES if os.access(p, os.X_OK)), None) # Allowlist: everything else in the environment dies at this boundary. Adding # a variable here is a security decision — it crosses into a shell that no # longer has any startup shaping, but it also becomes the only context the # implementation can see. KEEP = ( "HOME", "PATH", "LANG", "MOSAIC_GIT_IDENTITY", "MOSAIC_AGENT_NAME", "MOSAIC_BRAIN_HOME", "MOSAIC_CREDENTIAL_SPOOL", "MOSAIC_CREDENTIAL_LINEAGE_FENCE", ) env = {"_MOSAIC_HELPER_CLEAN": "1"} for name in KEEP: value = os.environ.get(name) if value is not None: env[name] = value argv = [BASH, IMPL] + sys.argv[1:] if BASH is None: sys.stderr.write("git-credential-mosaic: no executable bash at " + " or ".join(BASH_CANDIDATES) + "\n") sys.exit(127) try: os.execve(BASH, argv, env) except OSError as exc: sys.stderr.write(f"git-credential-mosaic: entrypoint exec failed: {exc}\n") sys.exit(127)