11# Airlock
22
3+ [ ![ CI] ( https://github.com/gatewaybuddy/agentpier/actions/workflows/ci.yml/badge.svg )] ( https://github.com/gatewaybuddy/agentpier/actions/workflows/ci.yml )
4+ [ ![ License] ( https://img.shields.io/badge/license-Apache%202.0-blue.svg )] ( LICENSE )
5+ [ ![ Python] ( https://img.shields.io/badge/python-3.10%20|%203.11%20|%203.12-blue.svg )] ( pyproject.toml )
6+ [ ![ PyPI] ( https://img.shields.io/pypi/v/agentpier-airlock.svg )] ( https://pypi.org/project/agentpier-airlock/ )
7+
38** Redaction engine + MCP server for AI agent traces. By AgentPier.**
49
510Airlock is the missing seam between your secret scanner and your PII redactor.
@@ -13,6 +18,96 @@ published without the infra details that would make them a reconnaissance target
1318
1419---
1520
21+ ## Quickstart
22+
23+ ``` bash
24+ pip install agentpier-airlock
25+ python -c " from airlock.scrubber import scrub; print(scrub('account 123456789012 at 10.0.0.5'))"
26+ # → account <ACCOUNT_ID> at <PRIVATE_IP>
27+ ```
28+
29+ Or run the demo:
30+
31+ ``` bash
32+ git clone https://github.com/gatewaybuddy/agentpier.git
33+ cd agentpier
34+ python examples/demo.py
35+ ```
36+
37+ ---
38+
39+ ## Demo output
40+
41+ ```
42+ ========================================================================
43+ AIRLOCK — Redaction Demo
44+ ========================================================================
45+
46+ --- BEFORE (raw agent trace) -------------------------------------------
47+ [2026-06-24T14:32:01Z] AgentRun#7f3a2c1e — inventory task started
48+ Caller identity: arn:aws:iam::123456789012:user/deploy-agent
49+ Account: 123456789012 Region: us-east-1
50+
51+ Probing EC2 in us-east-1...
52+ → Instance i-0abc1234def56789 at 203.0.113.42 (public), 10.0.1.55 (private)
53+ → Security group sg-0123456789abcdef0 allows 0.0.0.0/0:443
54+
55+ S3 buckets found:
56+ s3://example-prod-data/logs/2026-06/
57+ s3://example-backups/snapshots/
58+ Cross-account replication target: --bucket-name example-dr-replica
59+
60+ Secrets Manager: arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/db-creds-xK8mP2
61+ Retrieved value: {"password": "s3cr3tP@ssw0rd!", "host": "db.internal.example.net"}
62+
63+ Lambda env vars on arn:aws:lambda:us-east-1:123456789012:function:data-processor:
64+ AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
65+ AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
66+
67+ Notification endpoint: ops-alerts@example.com
68+ On-call SMS: 407-555-0192
69+ Internal dashboard: https://monitoring.internal.example.net/dashboard
70+
71+ [2026-06-24T14:32:04Z] Inventory complete — 2 instances, 3 buckets, 1 function
72+
73+ --- AFTER (scrubbed) ---------------------------------------------------
74+ [2026-06-24T14:32:01Z] AgentRun#7f3a2c1e — inventory task started
75+ Caller identity: <ARN>
76+ Account: <ACCOUNT_ID> Region: us-east-1
77+
78+ Probing EC2 in us-east-1...
79+ → Instance i-0abc1234def56789 at <PUBLIC_IP> (public), <PRIVATE_IP> (private)
80+ → Security group sg-0123456789abcdef0 allows <PUBLIC_IP>/0:443
81+
82+ S3 buckets found:
83+ <BUCKET><PATH>
84+ <BUCKET><PATH>
85+ Cross-account replication target: --<BUCKET>
86+
87+ Secrets Manager: <ARN>
88+ Retrieved value: {"password": "s3cr3tP@ssw0rd!", "host": "<FQDN>"}
89+
90+ Lambda env vars on <ARN>
91+ AWS_ACCESS_KEY_ID=<ACCESS_KEY>
92+ AWS_SECRET_ACCESS_KEY=<SECRET>
93+
94+ Notification endpoint: <EMAIL>
95+ On-call SMS: <PHONE>
96+ Internal dashboard: https://<FQDN>/dashboard
97+
98+ [2026-06-24T14:32:04Z] Inventory complete — 2 instances, 3 buckets, 1 function
99+
100+ --- GATE RESULT --------------------------------------------------------
101+ clean: False status: DIRTY — quarantined
102+ findings: 22
103+
104+ ========================================================================
105+ 22 sensitive tokens redacted. The lesson survives; the identifiers don't.
106+ ========================================================================
107+ ```
108+
109+ ---
110+
16111## What it catches
17112
18113| Category | Examples | Placeholder |
@@ -34,13 +129,7 @@ published without the infra details that would make them a reconnaissance target
34129
35130---
36131
37- ## Quick start
38-
39- ``` bash
40- git clone https://github.com/agentpier/airlock.git
41- cd airlock
42- python3 -m pytest airlock/tests/ -v
43- ```
132+ ## Usage
44133
45134### Scrub a string
46135
@@ -70,13 +159,17 @@ Or via environment variable (for MCP server deployments):
70159
71160``` bash
72161export AIRLOCK_BUCKET_DENYLIST=" my-prod-bucket,internal.corp.net,staging-data"
73- python3 -m airlock.server
162+ airlock-mcp
74163```
75164
76165### Start the MCP server
77166
78167``` bash
79- PYTHONPATH=/path/to/parent-of-airlock python3 airlock/server.py
168+ # As a console script (after pip install):
169+ AIRLOCK_BUCKET_DENYLIST=" my-bucket" airlock-mcp
170+
171+ # Or directly from the repo:
172+ PYTHONPATH=. python airlock/server.py
80173```
81174
82175See ` airlock/SKILL.md ` for Claude Code / Cursor install config.
@@ -95,7 +188,7 @@ completely or it is quarantined.
95188
96189** Denylist is empty by default** : Airlock ships with zero hardcoded infra names.
97190You bring your own via ` AIRLOCK_BUCKET_DENYLIST ` or ` add_to_denylist() ` . This
98- keeps the OSS release from embedding any org's topology.
191+ keeps the library from embedding any org's topology.
99192
100193---
101194
@@ -125,7 +218,8 @@ See `airlock/STORY_TEMPLATE.md` for the fill-in-the-blanks template.
125218## Running tests
126219
127220``` bash
128- PYTHONPATH=/path/to/parent-of-airlock python3 -m pytest airlock/tests/ -v
221+ # From the repo root
222+ PYTHONPATH=. python -m pytest airlock/tests/ -v
129223```
130224
131225The test suite includes unit tests for the scrubber (41 tests), handler tests
0 commit comments