Policy-driven context firewall for AI workflows — scan and redact sensitive data before prompts, logs, or traces leave your environment.
Project description
ContextDuty
The AI context firewall. Stop secrets from reaching any AI tool — before the prompt is assembled.
What is ContextDuty?
ContextDuty is a local-first security product that prevents secrets, API keys, and PII from leaking into AI coding assistants. It works with every AI tool — Cursor, GitHub Copilot, Claude, Windsurf, Cody, Amazon Q — current and future.
One install. Every AI tool. Zero cloud dependencies.
pip install contextduty
contextduty protect # blocks secrets from ALL AI tools at once
contextduty proxy start # intercepts HTTPS traffic to 21 AI APIs
Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ YOUR WORKSPACE │
│ │
│ .env config.py fixtures/ keys/ terraform.tfvars │
└───────────────────────────┬─────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────��┐ ┌────────────┐ ┌──────────────────┐
│ LAYER 1 │ │ LAYER 2 │ │ LAYER 3 │
│ Upstream Block │ │ Git Hook │ │ HTTPS Proxy │
│ │ │ │ │ │
│ .cursorignore │ │ pre-commit │ │ Intercepts 21 │
│ .copilotignore │ │ blocks │ │ AI API endpoints │
│ .codeiumignore │ │ commits │ │ Redacts secrets │
│ .tabnine_ignore │ │ with │ │ in-flight before │
│ .amazonq/ignore │ │ secrets │ │ they reach any │
│ .cody/ignore │ │ │ │ AI model │
└──────────────────┘ └────────────┘ └──────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────┐
│ AI TOOLS (all protected) │
│ Cursor · Copilot · Claude · Windsurf · Cody · Amazon Q │
│ + any future tool that reads workspaces or calls AI APIs │
└─────────────────────────────────────────────────────────────────────┘
Layer 1 — Upstream Block: Generates ignore files for 6 AI tools so they never index sensitive files.
Layer 2 — Git Hook: Pre-commit scan blocks secrets from entering version history.
Layer 3 — HTTPS Proxy: Intercepts all AI API traffic and redacts secrets from the request body in real-time.
Plus: MCP server for Cursor/Claude tool-call interception, CI/CD integration, and audit dashboard.
Quick start
pip install contextduty
# Try the interactive demo (20 seconds)
contextduty demo
# Protect your workspace from ALL AI tools
cd your-project/
contextduty protect
# Install git pre-commit hook
contextduty install-hooks
# Start the HTTPS proxy (intercepts Cursor, Copilot, Claude API calls)
pip install 'contextduty[proxy]'
contextduty proxy setup
contextduty proxy start
See it in 20 seconds
$ contextduty demo
▶ Scene 1 — Developer creates config.py with real credentials
DATABASE_URL = "postgresql://admin:Sup3rS3cr3t!@prod-db.internal:5432/customers"
AWS_ACCESS_KEY_ID = "AKIAIOSFODNN7EXAMPLE"
OPENAI_API_KEY = "sk-proj-EXAMPLEcontextdutyDEMO..."
▶ Scene 2 — Scanning → 6 findings detected
▶ Scene 3 — Redacting (safe to pass to AI)
DATABASE_URL = "<DB_DSN_33213ab6f0>"
AWS_ACCESS_KEY_ID = "<AWS_KEY_1a5d44a2dc>"
OPENAI_API_KEY = "<OPENAI_KEY_5f04681e46>"
✓ Real values replaced with deterministic masks — safe to paste into any AI tool
▶ Scene 4 — Pre-commit hook blocks the commit
[ContextDuty] BLOCKED: config.py
aws_key: 1 finding(s)
openai_key: 1 finding(s)
✓ Commit rejected — secrets never entered git history
Layer 1 — Universal workspace protection
One command generates ignore files for every AI tool:
$ contextduty protect
────────────────────────────────────────────────────────
ContextDuty — Universal AI Workspace Protection
────────────────────────────────────────────────────────
⚠ 12 file(s) contain secrets/PII
✓ Written 6 ignore files:
✓ .cursorignore Cursor
✓ .copilotignore GitHub Copilot
✓ .codeiumignore Codeium / Windsurf
✓ .tabnine_ignore Tabnine
✓ .amazonq/ignore Amazon Q
✓ .cody/ignore Sourcegraph Cody
Watch mode — auto-updates when files change:
contextduty protect watch # runs continuously, updates all 6 ignore files
Future-proof: When a new AI tool launches, we add 3 lines to the registry. Your workspace is instantly protected.
Layer 2 — Pre-commit hook
contextduty install-hooks
Every git commit is scanned. If secrets are found, the commit is rejected:
$ git commit -m "add deployment config"
[ContextDuty] BLOCKED: config.py
aws_key: 1 finding(s)
openai_key: 1 finding(s)
╔══════════════════════════════════════════════════════════════╗
║ ContextDuty blocked this commit. ║
║ Remove or redact them before committing. ║
╚══════════════════════════════════════════════════════════════╝
Layer 3 — HTTPS proxy (real-time interception)
The proxy sits between your AI tools and their API endpoints. It intercepts requests to 21 AI API hosts and redacts secrets from the request body before they leave your machine.
pip install 'contextduty[proxy]'
contextduty proxy setup # one-time: install CA cert
contextduty proxy start # start intercepting
──────────────────────────────────────────────────────
ContextDuty Proxy
──────────────────────────────────────────────────────
Listening on 127.0.0.1:8080
Intercepting 21 AI API endpoints
Policy .contextduty.json
What it intercepts:
| Provider | Endpoints |
|---|---|
| OpenAI | api.openai.com |
| Anthropic (Claude) | api.anthropic.com |
| Cursor | cursor.sh, api2.cursor.sh |
| GitHub Copilot | copilot.github.com, api.githubcopilot.com |
| Google (Gemini) | generativelanguage.googleapis.com, aiplatform.googleapis.com |
| Azure OpenAI | openai.azure.com |
| Codeium / Windsurf | server.codeium.com |
| Amazon Q | codewhisperer.us-east-1.amazonaws.com |
| Sourcegraph Cody | sourcegraph.com |
| Others | Cohere, Mistral, Groq, Together, Perplexity, DeepSeek, Fireworks, Tabnine |
Declarative field walker — the proxy knows exactly where each provider puts user content in their JSON payload (messages, context, system prompts) and only scans those fields. Adding a new provider = adding field paths, zero code changes.
Layer 4 — MCP server (Cursor / Claude / VS Code)
ContextDuty runs as an MCP server. When AI agents fetch files or database results via tools, ContextDuty intercepts the response:
// ~/.cursor/mcp.json or ~/.claude/claude_desktop_config.json
{
"mcpServers": {
"contextduty": { "command": "contextduty-mcp" }
}
}
Agent calls: read_file("customers.json")
Tool returns: {"name": "Jane Smith", "ssn": "123-45-6789"}
ContextDuty: {"name": "<PERSON_a3f2>", "ssn": "<SSN_b7c1>"}
→ Real values never enter the prompt. Never reach the AI model.
Layer 5 — CI/CD enforcement
# .github/workflows/contextduty.yml
- name: ContextDuty scan
run: |
pip install contextduty
contextduty scan src/ --policy .contextduty.json
With "mode": "block", the pipeline exits non-zero. PR cannot merge.
Detection: 25 built-in detectors
| Category | Detectors |
|---|---|
| PII | email, phone |
| Generic tokens | api_key, bearer_token, env_secret |
| Cloud | aws_key, aws_secret, gcp_service_account, azure_storage_key, google_oauth_token |
| VCS | github_pat |
| AI/ML | openai_key, anthropic_key, huggingface_token |
| SaaS | slack_token, stripe_webhook, sendgrid_key, mailchimp_key, npm_token, twilio_sid |
| Databases | db_dsn (postgres, mysql, mongodb, redis — only when credentials present) |
| Crypto | ssh_private_key, pgp_private_key, private_key_pem, jwt |
Deterministic masks: AKIAIOSFODNN7EXAMPLE always becomes <AWS_KEY_1a5d44a2dc> — same value, same mask, everywhere. Audit logs stay correlatable without storing raw secrets.
Custom detectors — add your own regex patterns:
{
"custom_detectors": {
"employee_id": "\\bEMP-[0-9]{6}\\b",
"patient_mrn": "\\bMRN-[0-9]{8}\\b"
}
}
Policy system
contextduty init # creates .contextduty.json
{
"mode": "redact",
"detectors": ["email", "phone", "aws_key", "openai_key", "github_pat", "db_dsn"],
"custom_detectors": {},
"detector_modes": { "aws_key": "block", "openai_key": "block" },
"allow_patterns": { "email": ["@example\\.com$", "@test\\.internal$"] }
}
| Mode | Behavior |
|---|---|
redact |
Replace matched values with deterministic masks |
warn |
Log findings, don't modify, don't block |
block |
Exit non-zero — for CI and pre-commit hard stops |
Policy layering — team baseline + repo override:
{ "extends": "../../policies/org-baseline.json", "mode": "block" }
Compliance baselines included: policies/soc2-baseline.json, policies/hipaa-baseline.json
Audit dashboard
contextduty dashboard --demo # try it with synthetic data
contextduty dashboard # reads ~/.contextduty/audit.jsonl
Local web UI with dark theme: findings by detector, 30-day timeline, blocked commits, developer activity, CSV export. Zero dependencies, all data stays on your machine.
All commands
| Command | Description |
|---|---|
contextduty demo |
Interactive demo — catches secrets in 20 seconds |
contextduty protect |
Write ignore files for ALL 6 AI tools at once |
contextduty protect watch |
Background daemon, auto-update on file changes |
contextduty protect status |
Show what's protected and what's not |
contextduty proxy setup |
One-time CA cert install |
contextduty proxy start |
Start HTTPS interception proxy |
contextduty proxy stop |
Stop the proxy |
contextduty proxy status |
Check if proxy is running |
contextduty cursor setup |
Cursor-specific workspace protection |
contextduty cursor watch |
Cursor-specific watch mode |
contextduty scan <file|dir> |
Scan and print JSON findings |
contextduty redact --in <f> --out <f> |
Redact file, write clean copy |
contextduty install-hooks |
Install git pre-commit hook |
contextduty uninstall-hooks |
Remove the hook |
contextduty dashboard |
Open local audit dashboard |
contextduty report |
Summarize an audit log |
contextduty policy validate |
Validate and resolve policy file |
contextduty init |
Create default .contextduty.json |
Project structure
src/contextduty/
├── config.py # Centralized paths, env vars, constants
├── engine.py # Core scan/redact engine (25 detectors)
├── detectors.py # Regex detector definitions
├── policy.py # Policy loading, validation, inheritance
├── cli.py # CLI entry point (18 commands)
├── protect.py # Universal workspace protection
├── cursor.py # Cursor-specific shortcut
├── demo.py # Interactive demo
├── dashboard.py # Local audit web UI
├── core/
│ ├── __init__.py # Public API (lazy imports)
│ └── exceptions.py # Typed exception hierarchy
├── ui/
│ └── output.py # NO_COLOR-compliant terminal formatting
├── adapters/
│ └── ide.py # AI tool registry + ignore file generation
└── proxy/
├── scope.py # 21 AI API hosts (single source of truth)
├── interceptor.py # Declarative JSON field walker
├── addon.py # mitmproxy request handler
├── server.py # Proxy lifecycle (start/stop/daemon)
├── ca.py # CA certificate management
├── system.py # OS proxy configuration
└── feed.py # Live terminal feed for interceptions
How it compares
| ContextDuty | LLM Gateways | .gitignore | |
|---|---|---|---|
| Blocks AI indexing (Cursor, Copilot, etc.) | ✅ 6 tools | ❌ | ❌ |
| Pre-commit secret scanning | ✅ | ❌ | ❌ |
| HTTPS proxy (intercepts any AI API) | ✅ 21 endpoints | ✅ (different purpose) | ❌ |
| MCP tool-call interception | ✅ | ❌ | ❌ |
| Runs 100% locally | ✅ | ❌ | ✅ |
| Policy-as-code | ✅ | Partial | ❌ |
| Works offline / air-gapped | ✅ | ❌ | ✅ |
| Your data sent to third parties | Never | Sometimes | N/A |
Local development
git clone https://github.com/SHUBHAGYTA24/contextduty
cd contextduty
pip install -e ".[dev]"
make check # format + lint + 258 tests
Roadmap
- 25 built-in detectors
- Pre-commit hook (
contextduty install-hooks) - MCP server (Cursor, Claude, VS Code)
- Directory scanning (
contextduty scan src/) - Audit dashboard (
contextduty dashboard) - Per-detector modes and allow patterns
- Policy layering with
extends - Interactive demo (
contextduty demo) - Universal workspace protection (
contextduty protect) — 6 AI tools - HTTPS proxy intercepting 21 AI API endpoints
- Declarative field walker (new AI provider = add paths, zero code)
- Enterprise architecture (config, exceptions, UI, adapters)
- VS Code / Cursor extension
- Presidio integration for NLP-based PII detection
- PyPI publish
- Prometheus metrics endpoint
License
MIT. Issues and PRs welcome. Open an issue if a detector is missing or misfiring.
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 contextduty-0.2.1.tar.gz.
File metadata
- Download URL: contextduty-0.2.1.tar.gz
- Upload date:
- Size: 81.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2142edc33553ef3d7bb3532f0b0650e47806d1965b83cdb09ae4c9dadbaa9e31
|
|
| MD5 |
1765068cf38cf6d28a32e0e69cbfd43d
|
|
| BLAKE2b-256 |
b366db31e977f146ad3ff84892d417fdca561f21dc6ff65edc3b2691c39d507f
|
Provenance
The following attestation bundles were made for contextduty-0.2.1.tar.gz:
Publisher:
publish.yml on SHUBHAGYTA24/contextduty
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
contextduty-0.2.1.tar.gz -
Subject digest:
2142edc33553ef3d7bb3532f0b0650e47806d1965b83cdb09ae4c9dadbaa9e31 - Sigstore transparency entry: 1554525748
- Sigstore integration time:
-
Permalink:
SHUBHAGYTA24/contextduty@f8b6aa76911f79b5f54585d9f1a4d3113dfbad81 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/SHUBHAGYTA24
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f8b6aa76911f79b5f54585d9f1a4d3113dfbad81 -
Trigger Event:
push
-
Statement type:
File details
Details for the file contextduty-0.2.1-py3-none-any.whl.
File metadata
- Download URL: contextduty-0.2.1-py3-none-any.whl
- Upload date:
- Size: 69.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1fd7acd3a16dea4d684106c10d398cf1671e836e7670a8ab6f63064005be5cb
|
|
| MD5 |
5e341d852659d15c02b39068e8aec8e7
|
|
| BLAKE2b-256 |
e84ad86f19f7618862d60202ade074b7e42afbc04a0c586ad5619e62ddb49b65
|
Provenance
The following attestation bundles were made for contextduty-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on SHUBHAGYTA24/contextduty
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
contextduty-0.2.1-py3-none-any.whl -
Subject digest:
e1fd7acd3a16dea4d684106c10d398cf1671e836e7670a8ab6f63064005be5cb - Sigstore transparency entry: 1554525761
- Sigstore integration time:
-
Permalink:
SHUBHAGYTA24/contextduty@f8b6aa76911f79b5f54585d9f1a4d3113dfbad81 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/SHUBHAGYTA24
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f8b6aa76911f79b5f54585d9f1a4d3113dfbad81 -
Trigger Event:
push
-
Statement type: