Skip to main content

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_text
  • findings
  • stats

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 event-specific Codex hook behavior:

  • UserPromptSubmit blocks sensitive prompts and returns a redacted prompt for resubmission.
  • PreToolUse rewrites the actual tool input with placeholders and allows execution.
  • PostToolUse blocks sensitive tool results and returns only a redacted result to the model.

Hook invocations do not persist plaintext placeholder mappings. Each invocation uses an in-memory vault that is discarded when the hook exits. Same-session restoration is available through the Python library when one RedactionEngine instance owns both redaction and restoration.

Codex supports input replacement only for PreToolUse through hookSpecificOutput.updatedInput. It does not currently expose replacement fields for UserPromptSubmit or PostToolUse, so those events must block to prevent the original sensitive value from entering model context.

Install the local package before using the hooks:

python3 -m pip install --upgrade "egressai>=0.1.8"

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. PreToolUse findings should show a successful input rewrite. Prompt and post-tool findings should be blocked with only redacted feedback.

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 0 when no findings are detected
  • exits 1 when findings are detected
  • exits 2 for 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 .npmrc auth tokens and NPM_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_hook hook runner and egressai-codex-hook console script.

0.1.4

  • Expanded README examples and usage documentation.

0.1.3

  • Added finding line and column metadata.
  • 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*

Metadata

Release files for egressai 0.1.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for egressai 0.1.8
File Size Uploaded Provenance Actions
egressai-0.1.8.tar.gz 20.5 kB Without provenance Details for egressai-0.1.8.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for egressai 0.1.8
File Interpreter ABI Platform Actions
egressai-0.1.8-py3-none-any.whl Python 3 none any Details for egressai-0.1.8-py3-none-any.whl

Total release size: 33.9 kB

Release files / egressai-0.1.8.tar.gz

Download URL egressai-0.1.8.tar.gz
Size 20.5 kB
Tags Source
SHA-256 checksum
How to use checksums
0ab911ef57e705a1c3533521ca71e837d9e0c80d61a2efabf6ce87915fc9df02
BLAKE2b-256 checksum
How to use checksums
ef26b51b377d96ce00147d9bb121bdbedba2102be2d7631889c52976663a1450
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / egressai-0.1.8-py3-none-any.whl

Download URL egressai-0.1.8-py3-none-any.whl
Size 13.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
591675a75612f21ac8dc04151f83b0d7698f3e137e40288c2802887cd2772681
BLAKE2b-256 checksum
How to use checksums
2392446116a2f280cacba541b352cc3a4f58475af1be13a6990116e4c363c362
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Security for egressai 0.1.8

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page