Audit hooks

sys · Expert · 11 min

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.connect calls 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 tests

Remember

  • sys.addaudithook sees 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.

Check yourself

  1. What happens if an audit hook raises an exception for the 'open' event?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.python.org/3/library/sys.html#sys.addaudithook