Sandboxing experiments, compliance logging and investigating what a third-party package actually does rely on audit events.
CPython raises audit events at sensitive operations (PEP 578): open when a file is opened, import, subprocess.Popen, socket.connect, exec, compile, os.system and many more. The full list is in the "Audit events table" of the docs.
sys.addaudithook(hook) registers a function called as hook(event, args) for every event, where args is a tuple specific to the event: for open it is (path, mode, flags). Your own code can raise events with sys.audit("myapp.login", user).
Important properties:
- Hooks cannot be removed once added, and they apply to the whole process, including all threads.
- A hook that raises an exception aborts the operation that triggered it. That's how you can block, for example, all
socket.connectcalls in a test run. - Hooks are called very often; keep them fast and avoid triggering events inside the hook itself, or you will recurse.
Audit hooks are a visibility tool, not a security sandbox. Code running in the same interpreter can bypass them with ctypes or by corrupting memory. Use them to log or detect behaviour, such as reporting which files a test suite touches, and use OS-level isolation for real containment.
Example
import socket
import sys
opened = []
def hook(event, args):
if event == "open" and isinstance(args[0], str) and args[0].endswith(".cfg"):
opened.append((args[0], args[1]))
elif event == "socket.connect":
raise PermissionError("network disabled in tests")
sys.addaudithook(hook) # cannot be removed afterwards
with open("app.cfg", "w") as f:
f.write("debug=1")
print(opened) # [('app.cfg', 'w')]
try:
socket.create_connection(("127.0.0.1", 9), timeout=1)
except PermissionError as e:
print(e) # network disabled in testsRemember
sys.addaudithooksees events like open, import and socket.connect- Raising inside a hook blocks the triggering operation
- Hooks are permanent and process-wide; they aid visibility, not real sandboxing
Watch out for
- Treating audit hooks as a security boundary against malicious code in the same process.