Local-first redaction engine for AI egress security
Project description
EgressAI
EgressAI is a local-first redaction engine for AI egress security.
The first package takes text, detects secrets, replaces them with stable placeholders, and returns structured findings without exposing plaintext secret values in the public result.
Install
pip install egressai
The package depends on egressai-detect-secrets for provider-aware secret detection.
Python API
Redact text:
from egressai import RedactionEngine
secret = "sk-proj-" + "a" * 40
engine = RedactionEngine()
result = engine.redact(f"OPENAI_API_KEY={secret}")
print(result.redacted_text)
Output:
OPENAI_API_KEY={{EGRESSAI_SECRET_OPENAI_001}}
Inspect structured findings:
for finding in result.findings:
print(finding.type, finding.line, finding.column, finding.placeholder)
Output:
secret.openai_api_key 1 16 {{EGRESSAI_SECRET_OPENAI_001}}
Restore redacted text during the same engine session:
restored = engine.restore(result.redacted_text)
The restore map is memory-only and is not included in structured output.
Structured result:
payload = result.to_dict()
The structured output includes:
redacted_textfindingsstats
Each finding includes zero-based character offsets (start, end) plus
one-based line and column metadata for locating the sensitive value in files,
logs, and pasted diffs.
Plaintext secret values are not included in result.to_dict().
Redact a larger pasted context:
text = """
OPENAI_API_KEY=sk-proj-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
GITHUB_TOKEN=ghp_bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
DATABASE_URL=postgres://admin:password@prod.internal:5432/app
"""
result = RedactionEngine().redact(text)
print(result.redacted_text)
Output:
OPENAI_API_KEY={{EGRESSAI_SECRET_OPENAI_001}}
GITHUB_TOKEN={{EGRESSAI_SECRET_GITHUB_001}}
DATABASE_URL={{EGRESSAI_SECRET_DB_URL_001}}
CLI
Redact inline text:
egressai redact "OPENAI_API_KEY=sk-proj-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Output:
OPENAI_API_KEY={{EGRESSAI_SECRET_OPENAI_001}}
Redact a file:
egressai redact ./prompt.txt
Redact stdin:
cat ./logs.txt | egressai redact
Existing file paths are read from disk. Any other input is treated as literal text, including large multi-line contexts passed as one argument. For very large prompts or logs, stdin is usually the most reliable shell interface.
Return the full redaction result as JSON:
egressai redact --json ./sample.env
Scan without printing redacted text:
egressai scan ./sample.env
Return findings and stats as JSON:
egressai scan --json ./sample.env
Example JSON shape:
{
"findings": [
{
"category": "secret",
"column": 16,
"confidence": 0.99,
"detector": "egressai.openai_key",
"end": 63,
"id": "finding_000001",
"line": 1,
"placeholder": "{{EGRESSAI_SECRET_OPENAI_001}}",
"severity": "critical",
"start": 15,
"type": "secret.openai_api_key"
}
],
"stats": {
"findings_count": 1,
"pii_count": 0,
"secrets_count": 1
}
}
Return one finding per JSON Lines record:
egressai scan --jsonl ./sample.env
Example JSONL record:
{"category":"secret","column":16,"confidence":0.99,"detector":"egressai.openai_key","end":63,"id":"finding_000001","line":1,"placeholder":"{{EGRESSAI_SECRET_OPENAI_001}}","severity":"critical","start":15,"type":"secret.openai_api_key"}
Fail when findings are present:
egressai scan --fail-on-findings ./sample.env
Use a custom placeholder prefix:
egressai redact --placeholder-prefix SAFE ./prompt.txt
Codex Integration
The repo includes a hook-only Codex plugin at plugins/egressai.
The plugin does not include skills. It uses local hooks as the enforcement boundary:
UserPromptSubmitscans user prompts.PreToolUsescans tool inputs.PostToolUsescans tool outputs.
Install the local package before using the hooks:
python3 -m pip install --upgrade "egressai>=0.1.5"
Then add this repository marketplace to Codex, restart Codex, open /plugins,
and install EgressAI:
codex plugin marketplace add .
After installing, open /hooks to review and trust the EgressAI hook
definitions.
Larger Context Example
The fixture at tests/fixtures/messy_context.txt contains a pasted support/debug
report with a code diff, request headers, curl command, JSON payload, env vars,
repeated provider keys, JWTs, database URLs, and an Azure connection string.
Run it through the CLI:
egressai redact tests/fixtures/messy_context.txt
The redacted output preserves the surrounding debugging context while replacing secrets with provider-aware placeholders such as:
OPENAI_API_KEY="{{EGRESSAI_SECRET_OPENAI_001}}"
GITHUB_TOKEN="{{EGRESSAI_SECRET_GITHUB_001}}"
"Authorization": "Bearer {{EGRESSAI_TOKEN_JWT_001}}"
DATABASE_URL="{{EGRESSAI_SECRET_DB_URL_001}}"
Exit Codes
By default, CLI commands exit 0 even when findings are detected.
With --fail-on-findings:
- exits
0when no findings are detected - exits
1when findings are detected - exits
2for CLI usage errors
Supported Secret Types
Initial support includes:
- OpenAI API keys
- Anthropic API keys
- Google/Gemini API keys
- GitHub tokens
- GitLab tokens
- AWS access keys
- Stripe keys
- Slack tokens
- npm tokens, including
.npmrcauth tokens andNPM_TOKEN=npm_...env values - PyPI tokens
- Hugging Face tokens
- JWTs, including JWT-like tokens with non-base64url signature suffixes
- private key blocks
- database URLs, including JSON-escaped URL values such as
postgres:\/\/... - Azure connection strings
- generic
.env-style secret assignments
Provider mappings are covered by tests so each supported detector returns the expected EgressAI type, detector name, and placeholder subtype.
The test suite includes a messy real-world fixture with a pasted user report, code diff, curl commands, runtime env vars, JSON payloads, repeated secrets, and multiple provider token types.
Release Notes
0.1.5
- Added hook-only Codex plugin scaffolding.
- Added local
egressai.codex_hookhook runner andegressai-codex-hookconsole script.
0.1.4
- Expanded README examples and usage documentation.
0.1.3
- Added finding
lineandcolumnmetadata. - Added same-session restore support through
RedactionEngine.restore(). - Added a messy real-world fixture corpus.
- Added JSON-escaped database URL redaction.
- Added
egressai scan --jsonl.
Maintainer Notes
Every user-visible change should update this README in the same change set.
Before publishing:
python3 -m pytest
python3 -m build
python3 -m twine check dist/egressai-*
Publish the current release artifacts:
LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 PYTHONIOENCODING=utf-8 python3 -m twine upload dist/egressai-0.1.5*
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 egressai-0.1.5.tar.gz.
File metadata
- Download URL: egressai-0.1.5.tar.gz
- Upload date:
- Size: 19.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
80f88d97ed9925d1ccd3f9b0cc11e18d642a38e5cdaf77b20a82f7cfb920fd0c
|
|
| MD5 |
592bab77d96f49755524f947f005b56d
|
|
| BLAKE2b-256 |
f24bacde97ab26330ce0c2927c9fbf720f8db5d4899fb2396f8a41e5d33a0302
|
File details
Details for the file egressai-0.1.5-py3-none-any.whl.
File metadata
- Download URL: egressai-0.1.5-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b7e1ccf47cdb8eca20cb0d2ecc6d07b6deefe1398c9a899dc5864814282e43b8
|
|
| MD5 |
cdb3498a10450bebfbef3efc372e9922
|
|
| BLAKE2b-256 |
b5a98c579040e06b8aca0d69acdb4559f85d2b4b41cd4bc7e1ede748c276ad96
|