decon — clone an untrusted repo and get it running inside a throwaway sandbox: no host secrets, network off by default, setup commands gated.
Project description
decon
Clone a repo you don't trust and get it running — inside a throwaway sandbox, with no host secrets and network off by default.
A repo can look clean and still be dangerous. The malicious payload need not live in the source: setup instructions (README, error handlers, postinstall hooks, a "run this to fix it" command) can fetch the real payload at runtime — from a DNS TXT record, a pastebin, a "license check" endpoint — and open a reverse shell. Static review and scanners miss it because there is nothing malicious in the tree. This is a live indirect prompt-injection risk for AI coding agents with shell, file, and network access: the agent reads the "fix" as an instruction and runs it, dialing your machine home to an attacker.
decon draws the boundary where it belongs — the sandbox, not anyone's judgement (yours or an agent's):
- The clone runs on the host in a stripped git environment — hooks disabled, submodules off, credential helpers and
url.*.insteadOfrewrites ignored,ext::/local-file protocols blocked, no terminal prompt. No repo-controlled code executes during fetch. - All work runs in a throwaway sandbox with no host secrets (no SSH keys, tokens,
~/.env, cloud creds), a non-inherited environment, and network egress OFF by default. Egress is an explicit, informed opt-in — because that is the reverse-shell channel. - A pre-flight scan surfaces the exact trigger surfaces (
curl | bash, DNS-TXT config pulls,base64 -d | bash,/dev/tcpreverse shells, committed binaries, setup files) so you eyeball them before the sandbox opens. It reports signal, never a "safe" verdict.
Install
pipx install decon-cli # recommended
# or
pip install decon-cli
Requires git and a sandbox backend:
- docker — strongest isolation, used by default when the daemon is reachable.
- bubblewrap (
bwrap) — daemonless fallback.
Use
# clone, scan, drop into a shell with NO network and NO secrets
decon https://github.com/owner/repo
# run the (dangerous) setup step deliberately, with network but still no secrets
decon https://github.com/owner/repo --allow-network -- pip install -e .
# a specific ref, and keep the clone afterwards
decon https://github.com/owner/repo --ref v1.2.3 --keep
Everything after -- runs as the command inside the sandbox instead of an interactive shell.
Options
| flag | meaning |
|---|---|
--allow-network |
give the work phase network egress (still no host secrets). Off by default. |
--ref REF |
branch, tag, or commit to check out |
--backend {auto,docker,bwrap} |
sandbox backend (default auto) |
--image IMG |
docker image for the work phase (default python:3.12-slim) |
--shell SH |
shell to launch (default bash, falls back to sh) |
--no-scan |
skip the pre-flight trigger-surface scan |
--yes, -y |
don't pause at the "eyeball the findings" gate |
--no-harden |
drop the extra docker hardening flags |
--keep |
don't delete the throwaway clone on exit |
--print-cmd |
print the sandbox command that would run, then exit |
What it is not
It does not prove a repo is safe — it can't, because the payload may arrive at runtime. It removes the reward: no secrets to steal, no egress to phone home over, nothing persistent left behind. Treat every clone as hostile and this makes "hostile" cheap to handle.
Threat model & guarantees
| vector | mitigation |
|---|---|
| hook / submodule execution on clone | host clone with core.hooksPath=/dev/null, --no-recurse-submodules, hooks dir wiped |
| token/credential theft via gitconfig | GIT_CONFIG_GLOBAL/SYSTEM=/dev/null, credential helper disabled, empty env |
ext:: / local-file protocol tricks |
protocol.ext/file.allow=never, GIT_ALLOW_PROTOCOL=http:https |
| runtime-fetched payload / reverse shell | network egress denied by default |
| secret exfiltration | no SSH keys / tokens / .env / cloud creds mounted; host env not inherited |
| persistence | ephemeral container + throwaway clone, deleted on exit |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file decon_cli-0.1.0.tar.gz.
File metadata
- Download URL: decon_cli-0.1.0.tar.gz
- Upload date:
- Size: 14.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40455eb892f03bbadc3555bac9a43179c6f5e1ef6f02adcb6a607af867e89c5f
|
|
| MD5 |
63b1d9ef9d659050335b991277e709d3
|
|
| BLAKE2b-256 |
ccdbde26569016f9092f704043fb10cccf94bd667d8d463ff7b814c69dd8a20d
|
File details
Details for the file decon_cli-0.1.0-py3-none-any.whl.
File metadata
- Download URL: decon_cli-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3515bd71c90c6f331ba466f5777a3250e1685961e6a51d950f41d12af5fb941b
|
|
| MD5 |
5deda42d82909c920931df05fd176b49
|
|
| BLAKE2b-256 |
89106ad16e160ccf08d0663236823b221d662e7d2262b9e79b87b30eb5827d88
|