jadoonf/pypi-analysis-feed, run 23613262288, after the litellm_init.pth payload from LiteLLM 1.82.8 landed in site-packages. The record shows a double-Python interpreter ancestry — python3.11 → python3.11 — that dropped into a shell and ran 17 credential-recon commands before any explicit litellm import path was exercised.Public reporting documents the technique — LiteLLM 1.82.8 shipped a litellm_init.pth file that runs on every Python interpreter startup (not just import), executing a three-stage credential-harvest chain against environment, filesystem, and cloud-metadata surfaces (StepSecurity). The run below imports LiteLLM on a Garnet-instrumented runner; the focus from here is what fires when an interpreter spins up with the .pth present.
Execution lineage
Run 23613262288 · jadoonf/pypi-analysis-feed
Analyse local PyPI archives
The lineage shows what fires when a Python interpreter starts inside an environment where litellm_init.pth is present. The .pth file runs on interpreter initialisation, not import — so at the kernel level the record opens with python3.11 spawning a second python3.11, which drops to a shell. That double-Python ancestry is the behavioural fingerprint of .pth auto-execution and never appears during a regular package install.
Assertions flagged
| Check (class) | Granular id | Result | Evidence |
|---|---|---|---|
| Network egress | no_bad_egress_domain | attention | Outbound calls were made to models.litellm[.]cloud and checkmarx[.]zone; both destinations had been taken down by run time (DNS returned NXDOMAIN), so the egress did not complete but the record carries the attempts on the post-startup ancestry. |
What was observed
Process ancestry. The interpreter startup branch carries python3.11 → python3.11 → sh → curl / kubectl / printenv .... The full chain is visible in the embedded lineage above. From the shell at the bottom of the double-Python ancestry, the payload executed 17 commands in rapid sequence, grouped below by phase. The version comparison:
1.82.7 | 1.82.8 (profiled) | |
|---|---|---|
| Trigger | proxy_server.py at import | litellm_init.pth on interpreter startup |
| Visibility to static tools | Malicious module path | Site-packages .pth — often missed |
| Scope | Downstreams that import litellm | Any Python process in the environment |
The 17 post-startup commands organise into four buckets:
- Recon (5 commands).
hostname,whoami,uname -a,ip addr,printenv— full environment capture. - Cloud credential probes. Environment greps for
AWS_, Azure/GCP key checks, thencurlto169.254.169.254and169.254.170.2. Both probes triggered Garnet'snet_suspicious_tool_execdetection — a PyPI package has no legitimate reason to query cloud-metadata endpoints at interpreter startup. The same class is documented ascloud_metadata_access. - Kubernetes and filesystem harvest. Greps for
kubeandk8s, thenkubectl get secrets --all-namespaces -o json. In parallel, scans of/var/secrets,/run/secrets, and workspace files for API keys, webhook URLs, wallet RPC credentials (rpcuser,rpcpassword), database connection strings, Solana wallets, and WireGuard configurations. - Fork-bomb signal. Because
.pthre-fires on every spawned Python subprocess, the record carries exponential fan-out on the post-startup ancestry.
On the same ancestry the record carries code_on_the_fly (dynamic execution via base64 decode in the bootstrap stage), interpreter_shell_spawn (Python spawning a subprocess shell at interpreter startup), exec_from_unusual_dir (execution off the .pth detached branch and from /tmp), cloud_metadata_access and net_suspicious_tool_exec for the IMDS/ECS probes, and credentials_files_access for the touches on /var/secrets, /run/secrets, and workspace credentials.
Network. Outbound attempts on the post-startup ancestry covered models.litellm[.]cloud, checkmarx[.]zone, and the link-local cloud-metadata addresses 169.254.169.254 and 169.254.170.2. Both off-cloud destinations had been taken down by run time — DNS returned NXDOMAIN — so no egress completed from this run. The record carries the attempts on the post-startup ancestry.
File / memory access. credentials_files_access on /var/secrets, /run/secrets, and workspace credential paths. The harvest also covered API keys, webhook URLs, wallet RPC credentials, database connection strings, Solana wallets, and WireGuard configurations on disk. No procfs reads on this profile (the harvest pattern relies on environment and filesystem, not runner memory).
Notable absences. No binary_self_deletion — the .pth file stayed on disk after the interpreter exited. No completed outbound to the off-cloud destinations (NXDOMAIN at run time). No fork-bomb recovery on this run — the recursive .pth triggers fan-out that the record captures but does not interrupt.
Analysis
The interesting property of this record is that the trigger is interpreter startup, not import — every Python process in the environment carries the same harvest sequence regardless of whether litellm is referenced. The double-Python ancestry, the cloud-metadata probes, and the credential-file access are all visible in the lineage; nothing in the headline python -c "import litellm" command anticipates them. The record is what makes a startup-level trigger legible without re-running the workload.
Garnet records process ancestry, file access, and network egress straight from the kernel for every workflow run by the Garnet GitHub Action. Startup hooks, child processes, metadata probes, and outbound destinations all appear in the same artifact.
More field notes: Telnyx · TanStack runtime profiles · Axios.