Metadata-Version: 2.4
Name: ptrace-approve
Version: 3.1.1
Summary: Intercept and approve filesystem-modifying syscalls
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: python-ptrace>=0.9.9
Requires-Dist: pyperclip>=1.8.0
Requires-Dist: pytest

# ptrace-approve
Approve a programs actions from the command-line. Remeber choices.

Claude code approval system *for the code generated by claude code*.

This is ai-generated unreviewed code. I have used it a coouple of times.

## Caveats
AI-generated code, unreviewed, *slow*. This runs python code on every system call so for some use cases is *very slow* and breaks parallelization, think lots of system calls in parallel threads.

Processes and not traced after an exec (`--trace-children`), but you will have approved the exec. I had issues getting filenames (due to not being able to access memory) when we exec'd into other processes. This specifically happened for git. But this is not the normal mode of execution.

## Motivation
I wanted to rub some vibe coded apps over my code and not have it destroy my code.

## Alternatives and prior work
This is influenced form a UI perspective by cluade code, where you approve individual commands as claude wishes to run them, optionally adding exceptions. There is a tool called `maybe` which is a similar idea and has been declared as unmaintained by it's previous maintainer.

`ptrace-approve` uses ptrace and apparmor does similar things. Apparmor is faster, and can record rules to allow - but not does not have this sort of interactive real time approval.  `ptrace-approve` use the `python-pytrace` library which does all the fiddly work. This does the last mile of making something useful and doing pattern matching.

Tools like austral can place limits at the module or function level using a type systems.

## Installation
pipx install ptrace-approve

## Usage
` ptrace-approve app`

By default all reads are allowed for `app`

Individually approve rules or add patterns. `.` in patterns does not match ,'s or brackets. Use `(.|[.(),])` for the conventional meaning of . in regexps

the abolsute path to app app is found and a default profile is stored for the app based on this path.

ptrace-approve --clear app

Here are some patterns:

`/regexp/` `/` which the regexp work - the regexp is determined by commas or forward slashes.
`**/__pycache__/*` 
`*` does not match forwards slashes, `**` matches forward slashses.
"*" - literal
... - remaining arguments
_ - any argument

To always use `ptrace-approve` with a python app you can use `ptrace-pipx install app`

You can run the executable one the clipboard with `ptrace-clip`


## Running non-interactively

`ptapp` (ptrace-approve) is meant to make it *easy* to sandbox processes
for easy things. A common case is command-line tools, which works well —
you are prompted for options directly in the shell.

But some programs don't run in the shell. For those, we provide a
programmatic mode where another process can monitor what is going on and
make approval decisions. This was specifically written with execution from
Claude Code in mind.

If you are using an LLM (or any non-interactive caller), set
`PTAPP_NO_BLOCK=1` in its environment so you can't accidentally run
`ptapp` in blocking mode — it will exit 3 with an error instead of
hanging silently on a prompt.

For Claude Code, put this in `settings.json`:

    {
      "env": {
        "PTAPP_NO_BLOCK": "1"
      }
    }

To run non-interactively you use `--background-dir` (`PTAPP_NO_BLOCK`
makes this mandatory). Using this you start a process in the background
and can then query it to see if it requires permissions. See
`ptrace-approve --help` for the full protocol:

    ptrace-approve --background-dir DIR -- CMD &    # start
    ptrace-approve --background-wait DIR            # block until next event
    ptrace-approve --background-respond DIR SEQ ACT # reply, wait for next

Events are JSON (`{"status": "pending", "seq": N, ...}` or
`{"status": "done", "exit_code": N}`). `--background-respond` exits with
the subprocess's exit code when the run finishes.


## Change log
2.0.0 - Change match format
3.0.0 - Don't trace after exec, but trace after the initial fork.
