Policy-driven context firewall for AI workflows — scan and redact sensitive data before prompts, logs, or traces leave your environment.
Project description
ContextDuty
A policy-driven context firewall for AI workflows. Scan and redact sensitive data before prompts, logs, or traces leave your environment — locally, with no cloud calls.
Why ContextDuty
AI coding assistants and agent workflows are spreading fast. So is accidental data leakage — API keys, emails, and PII flowing into prompts, logs, and traces that may be stored or sent to third-party services.
ContextDuty is a local-first, policy-layered primitive that fits into any workflow:
- CLI — pipe files through it in CI or pre-commit hooks
- MCP server — Cursor, VS Code, and any MCP client get automatic redaction
- Policy inheritance — teams extend org-wide baselines without copying rules
Why not Presidio?
Microsoft Presidio is great for NER-based PII detection in data pipelines. ContextDuty solves a different problem:
| ContextDuty | Presidio | |
|---|---|---|
| Target use case | AI prompts, logs, agent traces | Data pipelines, analytics |
| MCP-native | ✅ | ❌ |
Policy layering (extends) |
✅ | ❌ |
block mode for CI |
✅ | ❌ |
| Zero dependencies | ✅ | ❌ (heavy NLP stack) |
| Custom detectors (no code) | ✅ (regex in JSON) | Partial |
| Deployment | Local CLI / subprocess | Service / SDK |
Use Presidio when you need ML-based entity recognition at scale. Use ContextDuty when you need a lightweight, policy-enforceable firewall close to your AI toolchain.
Detection coverage
| Detector | Example input | Masked as |
|---|---|---|
email |
jane@corp.com |
<EMAIL_a1b2c3d4e5> |
phone |
+1 415-555-1212 |
<PHONE_f6g7h8i9j0> |
api_key |
sk_live_ABC123... |
<API_KEY_k1l2m3n4o5> |
aws_key |
AKIA1234567890ABCDEF |
<AWS_KEY_p6q7r8s9t0> |
bearer_token |
Bearer eyJhbGci... |
<BEARER_TOKEN_u1v2w3x4y5> |
Masks are deterministic — the same value always produces the same mask, so you can correlate across log lines without exposing the raw value.
Quickstart
pip install contextduty
contextduty init
Then scan and redact:
contextduty scan sample.txt --report report.json
contextduty redact --in sample.txt --out clean.txt --report report.json
Commands
| Command | Description |
|---|---|
contextduty init |
Create .contextduty.json in the current directory |
contextduty scan <file> |
Scan file, print JSON findings report |
contextduty redact --in <f> --out <f> |
Redact matches, write clean file |
contextduty policy validate --policy <f> [--strict] |
Validate and resolve a layered policy |
MCP server (Cursor / VS Code / any MCP client)
ContextDuty runs as an MCP stdio server — drop it into your editor config and every file your agent touches is scanned automatically.
contextduty-mcp
Cursor — add to ~/.cursor/mcp.json:
{
"mcpServers": {
"contextduty": {
"command": "contextduty-mcp"
}
}
}
Exposed tools:
contextduty_scan(path, optionalpolicyPath)contextduty_redact(inputPath,outputPath, optionalpolicyPath)
Policy file
Default .contextduty.json:
{
"mode": "redact",
"detectors": ["email", "phone", "api_key", "aws_key", "bearer_token"],
"custom_detectors": {}
}
Add a custom detector without touching code:
{
"mode": "redact",
"detectors": ["email"],
"custom_detectors": {
"employee_id": "\\bEMP-[0-9]{6}\\b",
"internal_ticket": "\\bTICKET-[A-Z]{3}-[0-9]{4}\\b"
}
}
custom_detectors are auto-enabled — just add the regex entry.
Policy layering for teams and enterprises:
{
"extends": "../../policies/org-baseline.json",
"mode": "block",
"detectors": ["internal_ticket"],
"custom_detectors": {
"internal_ticket": "\\bTICKET-[A-Z]{3}-[0-9]{4}\\b"
}
}
Rules:
extendscan be a string or list (relative file paths)detectorsare merged (parent + child)custom_detectorsare merged (child overrides same key)modeis overridden by the child policy- Cycles in
extendsare rejected with a clear error
Modes:
| Mode | Behaviour |
|---|---|
redact |
Replace matched values with deterministic masks |
warn |
Report findings, do not change content |
block |
Exit non-zero if findings exist (CI enforcement) |
Compliance policy packs
Ready-made baselines for common frameworks — extend them in your own policy file:
| Pack | Path | Detectors included |
|---|---|---|
| SOC 2 | policies/soc2-baseline.json |
email, phone, api_key, aws_key, bearer_token |
| HIPAA | policies/hipaa-baseline.json |
email, phone + PHI custom patterns |
Usage:
{
"extends": "./node_modules/contextduty/policies/soc2-baseline.json",
"mode": "block"
}
CI integration
Add a pre-push check to block accidental secret commits:
# .github/workflows/contextduty.yml
- name: Scan for secrets
run: |
pip install contextduty
contextduty scan . --policy .contextduty.json
Or use mode: block in your policy to make contextduty scan exit non-zero on any finding.
Roadmap
- PyPI publish (
pip install contextduty) - Streaming JSONL mode for multi-GB datasets
- VS Code extension
- Policy packs for PCI-DSS
- GitHub Action (
uses: contextduty/action@v1)
Open source
| File | Purpose |
|---|---|
LICENSE |
MIT |
SECURITY.md |
Vulnerability reporting |
CONTRIBUTING.md |
How to contribute |
CODE_OF_CONDUCT.md |
Community standards |
CHANGELOG.md |
Version history |
Contributing
Issues, PRs, and policy pack contributions are very welcome. See CONTRIBUTING.md to get started.
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.1.0.tar.gz.
File metadata
- Download URL: contextduty-0.1.0.tar.gz
- Upload date:
- Size: 16.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4670df3b1d53a062a04352dd93180613f61883fded5e86eb30cde5e74fb233ac
|
|
| MD5 |
12b147da31ee748ba7dbff39547752ed
|
|
| BLAKE2b-256 |
8d2088175f7b2b4a17d669f88e27054c5f47b44d248e1e7acd4399508a8b9180
|
Provenance
The following attestation bundles were made for contextduty-0.1.0.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.1.0.tar.gz -
Subject digest:
4670df3b1d53a062a04352dd93180613f61883fded5e86eb30cde5e74fb233ac - Sigstore transparency entry: 1432078262
- Sigstore integration time:
-
Permalink:
SHUBHAGYTA24/contextduty@8f704c4c9d1c4065a2a95fe9136463da9c1a7986 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/SHUBHAGYTA24
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8f704c4c9d1c4065a2a95fe9136463da9c1a7986 -
Trigger Event:
push
-
Statement type:
File details
Details for the file contextduty-0.1.0-py3-none-any.whl.
File metadata
- Download URL: contextduty-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.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 |
1595bed6f39d3b642d90565a346ffda13e779861db82ca6c97722aae557571d4
|
|
| MD5 |
3c75a4c5330a2f983f234a506fac6aa7
|
|
| BLAKE2b-256 |
e505d6314ba229bf2a38fb4ce56fae34923880514b0f7bf25c7f356714d68b09
|
Provenance
The following attestation bundles were made for contextduty-0.1.0-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.1.0-py3-none-any.whl -
Subject digest:
1595bed6f39d3b642d90565a346ffda13e779861db82ca6c97722aae557571d4 - Sigstore transparency entry: 1432078777
- Sigstore integration time:
-
Permalink:
SHUBHAGYTA24/contextduty@8f704c4c9d1c4065a2a95fe9136463da9c1a7986 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/SHUBHAGYTA24
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8f704c4c9d1c4065a2a95fe9136463da9c1a7986 -
Trigger Event:
push
-
Statement type: