aegis-privacy-proxy 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AEGISMCP contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,186 @@
1
+ Metadata-Version: 2.4
2
+ Name: aegis-privacy-proxy
3
+ Version: 0.1.0
4
+ Summary: Developer-first security and privacy proxy for AI workflows
5
+ License-Expression: MIT
6
+ Classifier: Development Status :: 3 - Alpha
7
+ Classifier: Environment :: Web Environment
8
+ Classifier: Framework :: FastAPI
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Security
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: fastapi<1,>=0.115
21
+ Requires-Dist: uvicorn<1,>=0.30
22
+ Requires-Dist: redis<7,>=5
23
+ Requires-Dist: cryptography<46,>=42
24
+ Requires-Dist: httpx<1,>=0.27
25
+ Requires-Dist: click<9,>=8.1
26
+ Requires-Dist: python-dotenv<2,>=1
27
+ Provides-Extra: test
28
+ Requires-Dist: pytest<9,>=8; extra == "test"
29
+ Requires-Dist: pytest-asyncio<2,>=0.24; extra == "test"
30
+ Provides-Extra: pii
31
+ Requires-Dist: presidio-analyzer<3,>=2.2; extra == "pii"
32
+ Requires-Dist: spacy<4,>=3.7; extra == "pii"
33
+ Dynamic: license-file
34
+
35
+ # AEGISMCP
36
+
37
+ **Developer-first security and privacy proxy for AI workflows.**
38
+
39
+ AEGISMCP is an OpenAI-compatible local proxy that detects selected secrets and personal data, replaces them with scoped placeholders before forwarding prompts, and restores values in responses locally. Its encrypted Redis vault stores temporary mappings with a short TTL.
40
+
41
+ > Phase 1 is an alpha prototype. Review the security notes below before using it with real data.
42
+
43
+ ## Why AEGISMCP
44
+
45
+ Prompts can accidentally include API keys, credentials, or personal information. Once sent to an external model, that content has left the developer's environment. AEGISMCP aims to reduce that exposure while preserving prompt context: the model sees placeholders such as `[API_KEY_01]`, and the trusted proxy can restore them in the response.
46
+
47
+ ## Detection coverage
48
+
49
+ The default detector runs locally and offline. Its rules cover common provider keys and tokens (OpenAI-style, AWS access keys, GitHub, GitLab, Slack, Stripe, Google API keys), bearer and Basic-auth credentials, JWTs, private-key blocks, labeled passwords/secrets, one-time/PIN codes, and credentials embedded in database or web URLs. It also checks for email addresses, phone numbers, payment cards (with Luhn validation), IBANs (with MOD-97 validation), UPI IDs, IP and MAC addresses, and labeled government IDs, dates of birth, and street addresses. India-specific rules include Aadhaar, PAN, and GSTIN formats; additional labeled rules cover identifiers such as SSNs, ITINs, passports, and driver's licenses.
50
+
51
+ To add local name and location recognition plus Presidio's larger regional recognizer set, install the optional PII extra and its small English spaCy model:
52
+
53
+ ```powershell
54
+ python -m pip install -e ".[pii]"
55
+ python -m spacy download en_core_web_sm
56
+ $env:AEGIS_PII_ENGINE = 'presidio'
57
+ aegismcp proxy --upstream-base-url https://api.openai.com/v1
58
+ ```
59
+
60
+ Presidio combines patterns, checksums, context, and named-entity recognition, and supports custom recognizers and country-specific entities. Its supported entity list varies by release and locale; see the [Presidio supported entities](https://microsoft.github.io/presidio/supported_entities/) and [Analyzer documentation](https://microsoft.github.io/presidio/analyzer/). For programmatic use, exact names and organization-specific identifiers can be added locally:
61
+
62
+ ```python
63
+ from aegismcp.detectors import PatternDetector
64
+
65
+ detector = PatternDetector(
66
+ known_names=["Ada Lovelace"],
67
+ custom_patterns={"EMPLOYEE_ID": r"\bEMP-\d{6}\b"},
68
+ )
69
+ ```
70
+
71
+ No detector can find every sensitive fact in arbitrary text. Whether information identifies a person can depend on context and combinations of fields such as location and birth date, as NIST discusses in [SP 800-122](https://csrc.nist.gov/pubs/sp/800/122/final). Regex rules can miss unknown formats; NER can miss names or locations, especially across languages. The default mode does not send text to an external detection service. Test against your own data types and add organization-specific recognizers before relying on it.
72
+
73
+ ## Quickstart
74
+
75
+ Requirements: Python 3.10+, Docker Desktop with Compose, and the repository checkout.
76
+
77
+ To install the published distribution from PyPI:
78
+
79
+ ```powershell
80
+ python -m pip install aegis-privacy-proxy
81
+ ```
82
+
83
+ 1. **Prepare and start ephemeral local Redis.** Generate local TLS/ACL credentials once, then start Redis:
84
+
85
+ ```powershell
86
+ python scripts/prepare_live_redis.py
87
+ docker compose up -d
88
+ ```
89
+
90
+ Keep the generated `.env.redis`, `docker/users.acl`, and `secrets/redis-tls/` files private. If you have already generated them, skip the setup script.
91
+
92
+ 2. **Install AEGISMCP and its CLI.** A virtual environment is recommended:
93
+
94
+ ```powershell
95
+ python -m venv .venv
96
+ .\.venv\Scripts\Activate.ps1
97
+ python -m pip install -e .
98
+ ```
99
+
100
+ 3. **Start the proxy.** Configure an upstream URL and provider first. For the local mock demo, use the URL below; for a real provider, set its API base URL instead.
101
+
102
+ ```powershell
103
+ aegismcp proxy --upstream-base-url http://127.0.0.1:8101/v1
104
+ ```
105
+
106
+ The proxy listens on `http://127.0.0.1:8000`. In a second terminal, run the no-provider-key demo:
107
+
108
+ ```powershell
109
+ python examples/chat_test.py
110
+ ```
111
+
112
+ The example starts a mock upstream, prints the sanitized prompt it receives, and then prints the response after local restoration. It uses only a fake key and does not call an external model.
113
+
114
+ ## OpenAI-compatible client
115
+
116
+ Point an OpenAI SDK client at the local proxy. Keep the real provider credential in an environment variable; the proxy consumes `X-Upstream-Api-Key` and forwards it upstream.
117
+
118
+ ```python
119
+ import os
120
+ from openai import OpenAI
121
+
122
+ client = OpenAI(
123
+ base_url="http://localhost:8000/v1",
124
+ api_key="proxy-placeholder", # Required by the SDK; proxy does not use this value.
125
+ default_headers={"X-Upstream-Api-Key": os.environ["MODEL_API_KEY"]},
126
+ )
127
+
128
+ result = client.chat.completions.create(
129
+ model="gpt-4o-mini",
130
+ messages=[{"role": "user", "content": "Summarize this text..."}],
131
+ )
132
+ print(result.choices[0].message.content)
133
+ ```
134
+
135
+ The current ingress API is OpenAI-compatible `POST /v1/chat/completions`. OpenAI-compatible clients can use the proxy with OpenAI, Ollama, or the included basic Anthropic upstream adapter. The native Anthropic SDK `/v1/messages` ingress is not implemented; Anthropic upstream requests are made through AEGISMCP's OpenAI-compatible interface.
136
+
137
+ ## Configuration
138
+
139
+ The proxy reads Redis and vault settings from `.env.redis` by default. Common settings can also be supplied as environment variables or CLI options:
140
+
141
+ ```powershell
142
+ $env:AEGIS_UPSTREAM_PROVIDER = 'openai' # openai, anthropic, or ollama
143
+ $env:AEGIS_MODE = 'enforce' # enforce or warn
144
+ $env:AEGIS_UPSTREAM_BASE_URL = 'https://api.openai.com/v1'
145
+ aegismcp proxy
146
+ ```
147
+
148
+ You can also pass `--provider`, `--mode`, `--host`, `--port`, and `--env-file` to `aegismcp proxy`. In `enforce` mode, tokenization and restoration errors fail closed. `warn` mode logs detected entity categories/counts and forwards original content unchanged; use it only with synthetic data.
149
+
150
+ ## Security notes and limitations
151
+
152
+ - Regex and pattern-based detectors are experimental. They can miss sensitive values and produce false positives; names in particular are not reliably identified by regex alone.
153
+ - Optional Presidio detection runs locally when installed and enabled; it adds coverage but does not make detection exhaustive. The default detector remains offline and rule-based.
154
+ - The local Compose setup publishes Redis only on `127.0.0.1:6380` so a host-installed proxy can reach it; it still requires TLS/mTLS, ACLs, in-memory operation, and strict TTLs. Do not bind Redis to public interfaces. In production, place Redis on a private network beside the proxy. The Compose setup is a development example, not a production deployment blueprint.
155
+ - AEGISMCP is not a substitute for access control, secret management, or data-loss prevention. Audit detector behavior, proxy configuration, tenant identity handling, and failure modes before production use.
156
+ - The proxy process is inside the trusted boundary. Python cannot reliably zeroize immutable plaintext or key objects in memory.
157
+ - Multi-tenant deployments need authenticated tenant identity middleware. Do not derive tenant identity from prompt text or an untrusted request field.
158
+
159
+ ## Tests
160
+
161
+ Run unit and mocked-upstream tests locally with the test extra:
162
+
163
+ ```powershell
164
+ python -m pip install -e ".[test]"
165
+ python -m pytest -q
166
+ ```
167
+
168
+ To run the real optional name/location NER test, install the PII extra and English model first. The test skips when that optional model is not installed:
169
+
170
+ ```powershell
171
+ python -m pip install -e ".[test,pii]"
172
+ python -m spacy download en_core_web_sm
173
+ python -m pytest -q tests/test_detectors.py
174
+ ```
175
+
176
+ To include the TLS Redis integration test in the Compose environment:
177
+
178
+ ```powershell
179
+ docker compose --profile test run --rm redis-test
180
+ ```
181
+
182
+ Stop the local Redis service with `docker compose down` when finished.
183
+
184
+ ## License
185
+
186
+ AEGISMCP is released under the [MIT License](LICENSE).
@@ -0,0 +1,152 @@
1
+ # AEGISMCP
2
+
3
+ **Developer-first security and privacy proxy for AI workflows.**
4
+
5
+ AEGISMCP is an OpenAI-compatible local proxy that detects selected secrets and personal data, replaces them with scoped placeholders before forwarding prompts, and restores values in responses locally. Its encrypted Redis vault stores temporary mappings with a short TTL.
6
+
7
+ > Phase 1 is an alpha prototype. Review the security notes below before using it with real data.
8
+
9
+ ## Why AEGISMCP
10
+
11
+ Prompts can accidentally include API keys, credentials, or personal information. Once sent to an external model, that content has left the developer's environment. AEGISMCP aims to reduce that exposure while preserving prompt context: the model sees placeholders such as `[API_KEY_01]`, and the trusted proxy can restore them in the response.
12
+
13
+ ## Detection coverage
14
+
15
+ The default detector runs locally and offline. Its rules cover common provider keys and tokens (OpenAI-style, AWS access keys, GitHub, GitLab, Slack, Stripe, Google API keys), bearer and Basic-auth credentials, JWTs, private-key blocks, labeled passwords/secrets, one-time/PIN codes, and credentials embedded in database or web URLs. It also checks for email addresses, phone numbers, payment cards (with Luhn validation), IBANs (with MOD-97 validation), UPI IDs, IP and MAC addresses, and labeled government IDs, dates of birth, and street addresses. India-specific rules include Aadhaar, PAN, and GSTIN formats; additional labeled rules cover identifiers such as SSNs, ITINs, passports, and driver's licenses.
16
+
17
+ To add local name and location recognition plus Presidio's larger regional recognizer set, install the optional PII extra and its small English spaCy model:
18
+
19
+ ```powershell
20
+ python -m pip install -e ".[pii]"
21
+ python -m spacy download en_core_web_sm
22
+ $env:AEGIS_PII_ENGINE = 'presidio'
23
+ aegismcp proxy --upstream-base-url https://api.openai.com/v1
24
+ ```
25
+
26
+ Presidio combines patterns, checksums, context, and named-entity recognition, and supports custom recognizers and country-specific entities. Its supported entity list varies by release and locale; see the [Presidio supported entities](https://microsoft.github.io/presidio/supported_entities/) and [Analyzer documentation](https://microsoft.github.io/presidio/analyzer/). For programmatic use, exact names and organization-specific identifiers can be added locally:
27
+
28
+ ```python
29
+ from aegismcp.detectors import PatternDetector
30
+
31
+ detector = PatternDetector(
32
+ known_names=["Ada Lovelace"],
33
+ custom_patterns={"EMPLOYEE_ID": r"\bEMP-\d{6}\b"},
34
+ )
35
+ ```
36
+
37
+ No detector can find every sensitive fact in arbitrary text. Whether information identifies a person can depend on context and combinations of fields such as location and birth date, as NIST discusses in [SP 800-122](https://csrc.nist.gov/pubs/sp/800/122/final). Regex rules can miss unknown formats; NER can miss names or locations, especially across languages. The default mode does not send text to an external detection service. Test against your own data types and add organization-specific recognizers before relying on it.
38
+
39
+ ## Quickstart
40
+
41
+ Requirements: Python 3.10+, Docker Desktop with Compose, and the repository checkout.
42
+
43
+ To install the published distribution from PyPI:
44
+
45
+ ```powershell
46
+ python -m pip install aegis-privacy-proxy
47
+ ```
48
+
49
+ 1. **Prepare and start ephemeral local Redis.** Generate local TLS/ACL credentials once, then start Redis:
50
+
51
+ ```powershell
52
+ python scripts/prepare_live_redis.py
53
+ docker compose up -d
54
+ ```
55
+
56
+ Keep the generated `.env.redis`, `docker/users.acl`, and `secrets/redis-tls/` files private. If you have already generated them, skip the setup script.
57
+
58
+ 2. **Install AEGISMCP and its CLI.** A virtual environment is recommended:
59
+
60
+ ```powershell
61
+ python -m venv .venv
62
+ .\.venv\Scripts\Activate.ps1
63
+ python -m pip install -e .
64
+ ```
65
+
66
+ 3. **Start the proxy.** Configure an upstream URL and provider first. For the local mock demo, use the URL below; for a real provider, set its API base URL instead.
67
+
68
+ ```powershell
69
+ aegismcp proxy --upstream-base-url http://127.0.0.1:8101/v1
70
+ ```
71
+
72
+ The proxy listens on `http://127.0.0.1:8000`. In a second terminal, run the no-provider-key demo:
73
+
74
+ ```powershell
75
+ python examples/chat_test.py
76
+ ```
77
+
78
+ The example starts a mock upstream, prints the sanitized prompt it receives, and then prints the response after local restoration. It uses only a fake key and does not call an external model.
79
+
80
+ ## OpenAI-compatible client
81
+
82
+ Point an OpenAI SDK client at the local proxy. Keep the real provider credential in an environment variable; the proxy consumes `X-Upstream-Api-Key` and forwards it upstream.
83
+
84
+ ```python
85
+ import os
86
+ from openai import OpenAI
87
+
88
+ client = OpenAI(
89
+ base_url="http://localhost:8000/v1",
90
+ api_key="proxy-placeholder", # Required by the SDK; proxy does not use this value.
91
+ default_headers={"X-Upstream-Api-Key": os.environ["MODEL_API_KEY"]},
92
+ )
93
+
94
+ result = client.chat.completions.create(
95
+ model="gpt-4o-mini",
96
+ messages=[{"role": "user", "content": "Summarize this text..."}],
97
+ )
98
+ print(result.choices[0].message.content)
99
+ ```
100
+
101
+ The current ingress API is OpenAI-compatible `POST /v1/chat/completions`. OpenAI-compatible clients can use the proxy with OpenAI, Ollama, or the included basic Anthropic upstream adapter. The native Anthropic SDK `/v1/messages` ingress is not implemented; Anthropic upstream requests are made through AEGISMCP's OpenAI-compatible interface.
102
+
103
+ ## Configuration
104
+
105
+ The proxy reads Redis and vault settings from `.env.redis` by default. Common settings can also be supplied as environment variables or CLI options:
106
+
107
+ ```powershell
108
+ $env:AEGIS_UPSTREAM_PROVIDER = 'openai' # openai, anthropic, or ollama
109
+ $env:AEGIS_MODE = 'enforce' # enforce or warn
110
+ $env:AEGIS_UPSTREAM_BASE_URL = 'https://api.openai.com/v1'
111
+ aegismcp proxy
112
+ ```
113
+
114
+ You can also pass `--provider`, `--mode`, `--host`, `--port`, and `--env-file` to `aegismcp proxy`. In `enforce` mode, tokenization and restoration errors fail closed. `warn` mode logs detected entity categories/counts and forwards original content unchanged; use it only with synthetic data.
115
+
116
+ ## Security notes and limitations
117
+
118
+ - Regex and pattern-based detectors are experimental. They can miss sensitive values and produce false positives; names in particular are not reliably identified by regex alone.
119
+ - Optional Presidio detection runs locally when installed and enabled; it adds coverage but does not make detection exhaustive. The default detector remains offline and rule-based.
120
+ - The local Compose setup publishes Redis only on `127.0.0.1:6380` so a host-installed proxy can reach it; it still requires TLS/mTLS, ACLs, in-memory operation, and strict TTLs. Do not bind Redis to public interfaces. In production, place Redis on a private network beside the proxy. The Compose setup is a development example, not a production deployment blueprint.
121
+ - AEGISMCP is not a substitute for access control, secret management, or data-loss prevention. Audit detector behavior, proxy configuration, tenant identity handling, and failure modes before production use.
122
+ - The proxy process is inside the trusted boundary. Python cannot reliably zeroize immutable plaintext or key objects in memory.
123
+ - Multi-tenant deployments need authenticated tenant identity middleware. Do not derive tenant identity from prompt text or an untrusted request field.
124
+
125
+ ## Tests
126
+
127
+ Run unit and mocked-upstream tests locally with the test extra:
128
+
129
+ ```powershell
130
+ python -m pip install -e ".[test]"
131
+ python -m pytest -q
132
+ ```
133
+
134
+ To run the real optional name/location NER test, install the PII extra and English model first. The test skips when that optional model is not installed:
135
+
136
+ ```powershell
137
+ python -m pip install -e ".[test,pii]"
138
+ python -m spacy download en_core_web_sm
139
+ python -m pytest -q tests/test_detectors.py
140
+ ```
141
+
142
+ To include the TLS Redis integration test in the Compose environment:
143
+
144
+ ```powershell
145
+ docker compose --profile test run --rm redis-test
146
+ ```
147
+
148
+ Stop the local Redis service with `docker compose down` when finished.
149
+
150
+ ## License
151
+
152
+ AEGISMCP is released under the [MIT License](LICENSE).
@@ -0,0 +1,186 @@
1
+ Metadata-Version: 2.4
2
+ Name: aegis-privacy-proxy
3
+ Version: 0.1.0
4
+ Summary: Developer-first security and privacy proxy for AI workflows
5
+ License-Expression: MIT
6
+ Classifier: Development Status :: 3 - Alpha
7
+ Classifier: Environment :: Web Environment
8
+ Classifier: Framework :: FastAPI
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Security
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: fastapi<1,>=0.115
21
+ Requires-Dist: uvicorn<1,>=0.30
22
+ Requires-Dist: redis<7,>=5
23
+ Requires-Dist: cryptography<46,>=42
24
+ Requires-Dist: httpx<1,>=0.27
25
+ Requires-Dist: click<9,>=8.1
26
+ Requires-Dist: python-dotenv<2,>=1
27
+ Provides-Extra: test
28
+ Requires-Dist: pytest<9,>=8; extra == "test"
29
+ Requires-Dist: pytest-asyncio<2,>=0.24; extra == "test"
30
+ Provides-Extra: pii
31
+ Requires-Dist: presidio-analyzer<3,>=2.2; extra == "pii"
32
+ Requires-Dist: spacy<4,>=3.7; extra == "pii"
33
+ Dynamic: license-file
34
+
35
+ # AEGISMCP
36
+
37
+ **Developer-first security and privacy proxy for AI workflows.**
38
+
39
+ AEGISMCP is an OpenAI-compatible local proxy that detects selected secrets and personal data, replaces them with scoped placeholders before forwarding prompts, and restores values in responses locally. Its encrypted Redis vault stores temporary mappings with a short TTL.
40
+
41
+ > Phase 1 is an alpha prototype. Review the security notes below before using it with real data.
42
+
43
+ ## Why AEGISMCP
44
+
45
+ Prompts can accidentally include API keys, credentials, or personal information. Once sent to an external model, that content has left the developer's environment. AEGISMCP aims to reduce that exposure while preserving prompt context: the model sees placeholders such as `[API_KEY_01]`, and the trusted proxy can restore them in the response.
46
+
47
+ ## Detection coverage
48
+
49
+ The default detector runs locally and offline. Its rules cover common provider keys and tokens (OpenAI-style, AWS access keys, GitHub, GitLab, Slack, Stripe, Google API keys), bearer and Basic-auth credentials, JWTs, private-key blocks, labeled passwords/secrets, one-time/PIN codes, and credentials embedded in database or web URLs. It also checks for email addresses, phone numbers, payment cards (with Luhn validation), IBANs (with MOD-97 validation), UPI IDs, IP and MAC addresses, and labeled government IDs, dates of birth, and street addresses. India-specific rules include Aadhaar, PAN, and GSTIN formats; additional labeled rules cover identifiers such as SSNs, ITINs, passports, and driver's licenses.
50
+
51
+ To add local name and location recognition plus Presidio's larger regional recognizer set, install the optional PII extra and its small English spaCy model:
52
+
53
+ ```powershell
54
+ python -m pip install -e ".[pii]"
55
+ python -m spacy download en_core_web_sm
56
+ $env:AEGIS_PII_ENGINE = 'presidio'
57
+ aegismcp proxy --upstream-base-url https://api.openai.com/v1
58
+ ```
59
+
60
+ Presidio combines patterns, checksums, context, and named-entity recognition, and supports custom recognizers and country-specific entities. Its supported entity list varies by release and locale; see the [Presidio supported entities](https://microsoft.github.io/presidio/supported_entities/) and [Analyzer documentation](https://microsoft.github.io/presidio/analyzer/). For programmatic use, exact names and organization-specific identifiers can be added locally:
61
+
62
+ ```python
63
+ from aegismcp.detectors import PatternDetector
64
+
65
+ detector = PatternDetector(
66
+ known_names=["Ada Lovelace"],
67
+ custom_patterns={"EMPLOYEE_ID": r"\bEMP-\d{6}\b"},
68
+ )
69
+ ```
70
+
71
+ No detector can find every sensitive fact in arbitrary text. Whether information identifies a person can depend on context and combinations of fields such as location and birth date, as NIST discusses in [SP 800-122](https://csrc.nist.gov/pubs/sp/800/122/final). Regex rules can miss unknown formats; NER can miss names or locations, especially across languages. The default mode does not send text to an external detection service. Test against your own data types and add organization-specific recognizers before relying on it.
72
+
73
+ ## Quickstart
74
+
75
+ Requirements: Python 3.10+, Docker Desktop with Compose, and the repository checkout.
76
+
77
+ To install the published distribution from PyPI:
78
+
79
+ ```powershell
80
+ python -m pip install aegis-privacy-proxy
81
+ ```
82
+
83
+ 1. **Prepare and start ephemeral local Redis.** Generate local TLS/ACL credentials once, then start Redis:
84
+
85
+ ```powershell
86
+ python scripts/prepare_live_redis.py
87
+ docker compose up -d
88
+ ```
89
+
90
+ Keep the generated `.env.redis`, `docker/users.acl`, and `secrets/redis-tls/` files private. If you have already generated them, skip the setup script.
91
+
92
+ 2. **Install AEGISMCP and its CLI.** A virtual environment is recommended:
93
+
94
+ ```powershell
95
+ python -m venv .venv
96
+ .\.venv\Scripts\Activate.ps1
97
+ python -m pip install -e .
98
+ ```
99
+
100
+ 3. **Start the proxy.** Configure an upstream URL and provider first. For the local mock demo, use the URL below; for a real provider, set its API base URL instead.
101
+
102
+ ```powershell
103
+ aegismcp proxy --upstream-base-url http://127.0.0.1:8101/v1
104
+ ```
105
+
106
+ The proxy listens on `http://127.0.0.1:8000`. In a second terminal, run the no-provider-key demo:
107
+
108
+ ```powershell
109
+ python examples/chat_test.py
110
+ ```
111
+
112
+ The example starts a mock upstream, prints the sanitized prompt it receives, and then prints the response after local restoration. It uses only a fake key and does not call an external model.
113
+
114
+ ## OpenAI-compatible client
115
+
116
+ Point an OpenAI SDK client at the local proxy. Keep the real provider credential in an environment variable; the proxy consumes `X-Upstream-Api-Key` and forwards it upstream.
117
+
118
+ ```python
119
+ import os
120
+ from openai import OpenAI
121
+
122
+ client = OpenAI(
123
+ base_url="http://localhost:8000/v1",
124
+ api_key="proxy-placeholder", # Required by the SDK; proxy does not use this value.
125
+ default_headers={"X-Upstream-Api-Key": os.environ["MODEL_API_KEY"]},
126
+ )
127
+
128
+ result = client.chat.completions.create(
129
+ model="gpt-4o-mini",
130
+ messages=[{"role": "user", "content": "Summarize this text..."}],
131
+ )
132
+ print(result.choices[0].message.content)
133
+ ```
134
+
135
+ The current ingress API is OpenAI-compatible `POST /v1/chat/completions`. OpenAI-compatible clients can use the proxy with OpenAI, Ollama, or the included basic Anthropic upstream adapter. The native Anthropic SDK `/v1/messages` ingress is not implemented; Anthropic upstream requests are made through AEGISMCP's OpenAI-compatible interface.
136
+
137
+ ## Configuration
138
+
139
+ The proxy reads Redis and vault settings from `.env.redis` by default. Common settings can also be supplied as environment variables or CLI options:
140
+
141
+ ```powershell
142
+ $env:AEGIS_UPSTREAM_PROVIDER = 'openai' # openai, anthropic, or ollama
143
+ $env:AEGIS_MODE = 'enforce' # enforce or warn
144
+ $env:AEGIS_UPSTREAM_BASE_URL = 'https://api.openai.com/v1'
145
+ aegismcp proxy
146
+ ```
147
+
148
+ You can also pass `--provider`, `--mode`, `--host`, `--port`, and `--env-file` to `aegismcp proxy`. In `enforce` mode, tokenization and restoration errors fail closed. `warn` mode logs detected entity categories/counts and forwards original content unchanged; use it only with synthetic data.
149
+
150
+ ## Security notes and limitations
151
+
152
+ - Regex and pattern-based detectors are experimental. They can miss sensitive values and produce false positives; names in particular are not reliably identified by regex alone.
153
+ - Optional Presidio detection runs locally when installed and enabled; it adds coverage but does not make detection exhaustive. The default detector remains offline and rule-based.
154
+ - The local Compose setup publishes Redis only on `127.0.0.1:6380` so a host-installed proxy can reach it; it still requires TLS/mTLS, ACLs, in-memory operation, and strict TTLs. Do not bind Redis to public interfaces. In production, place Redis on a private network beside the proxy. The Compose setup is a development example, not a production deployment blueprint.
155
+ - AEGISMCP is not a substitute for access control, secret management, or data-loss prevention. Audit detector behavior, proxy configuration, tenant identity handling, and failure modes before production use.
156
+ - The proxy process is inside the trusted boundary. Python cannot reliably zeroize immutable plaintext or key objects in memory.
157
+ - Multi-tenant deployments need authenticated tenant identity middleware. Do not derive tenant identity from prompt text or an untrusted request field.
158
+
159
+ ## Tests
160
+
161
+ Run unit and mocked-upstream tests locally with the test extra:
162
+
163
+ ```powershell
164
+ python -m pip install -e ".[test]"
165
+ python -m pytest -q
166
+ ```
167
+
168
+ To run the real optional name/location NER test, install the PII extra and English model first. The test skips when that optional model is not installed:
169
+
170
+ ```powershell
171
+ python -m pip install -e ".[test,pii]"
172
+ python -m spacy download en_core_web_sm
173
+ python -m pytest -q tests/test_detectors.py
174
+ ```
175
+
176
+ To include the TLS Redis integration test in the Compose environment:
177
+
178
+ ```powershell
179
+ docker compose --profile test run --rm redis-test
180
+ ```
181
+
182
+ Stop the local Redis service with `docker compose down` when finished.
183
+
184
+ ## License
185
+
186
+ AEGISMCP is released under the [MIT License](LICENSE).
@@ -0,0 +1,22 @@
1
+ LICENSE
2
+ README.md
3
+ proxy_server.py
4
+ pyproject.toml
5
+ aegis_privacy_proxy.egg-info/PKG-INFO
6
+ aegis_privacy_proxy.egg-info/SOURCES.txt
7
+ aegis_privacy_proxy.egg-info/dependency_links.txt
8
+ aegis_privacy_proxy.egg-info/entry_points.txt
9
+ aegis_privacy_proxy.egg-info/requires.txt
10
+ aegis_privacy_proxy.egg-info/top_level.txt
11
+ aegismcp/__init__.py
12
+ aegismcp/cli.py
13
+ aegismcp/crypto.py
14
+ aegismcp/detectors.py
15
+ aegismcp/engine.py
16
+ aegismcp/redis_vault.py
17
+ aegismcp/vault.py
18
+ tests/test_detectors.py
19
+ tests/test_proxy.py
20
+ tests/test_redis_integration.py
21
+ tests/test_redis_vault.py
22
+ tests/test_tokenization.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ aegismcp = aegismcp.cli:main
@@ -0,0 +1,15 @@
1
+ fastapi<1,>=0.115
2
+ uvicorn<1,>=0.30
3
+ redis<7,>=5
4
+ cryptography<46,>=42
5
+ httpx<1,>=0.27
6
+ click<9,>=8.1
7
+ python-dotenv<2,>=1
8
+
9
+ [pii]
10
+ presidio-analyzer<3,>=2.2
11
+ spacy<4,>=3.7
12
+
13
+ [test]
14
+ pytest<9,>=8
15
+ pytest-asyncio<2,>=0.24
@@ -0,0 +1,2 @@
1
+ aegismcp
2
+ proxy_server
@@ -0,0 +1,6 @@
1
+ """AEGISMCP Phase 1 prototype components."""
2
+
3
+ from .engine import TokenizationEngine, TokenizationResult
4
+ from .vault import InMemoryTokenVault, VaultError
5
+
6
+ __all__ = ["TokenizationEngine", "TokenizationResult", "InMemoryTokenVault", "VaultError"]
@@ -0,0 +1,44 @@
1
+ """Command-line entry point for AEGISMCP."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+
7
+ import click
8
+
9
+
10
+ @click.group()
11
+ @click.version_option(package_name="aegis-privacy-proxy")
12
+ def main() -> None:
13
+ """Developer-first security and privacy proxy for AI workflows."""
14
+
15
+
16
+ @main.command("proxy")
17
+ @click.option("--host", default=lambda: os.getenv("AEGIS_PROXY_HOST", "127.0.0.1"), show_default=True)
18
+ @click.option("--port", type=click.IntRange(1, 65535),
19
+ default=lambda: int(os.getenv("AEGIS_PROXY_PORT", "8000")), show_default=True)
20
+ @click.option("--upstream-base-url", envvar="AEGIS_UPSTREAM_BASE_URL",
21
+ help="Provider URL, for example https://api.openai.com/v1.")
22
+ @click.option("--provider", type=click.Choice(["openai", "anthropic", "ollama"], case_sensitive=False),
23
+ default=lambda: os.getenv("AEGIS_UPSTREAM_PROVIDER", "openai"), show_default=True)
24
+ @click.option("--mode", type=click.Choice(["enforce", "warn"], case_sensitive=False),
25
+ default=lambda: os.getenv("AEGIS_MODE", "enforce"), show_default=True)
26
+ @click.option("--env-file", envvar="AEGIS_ENV_FILE", default=".env.redis", show_default=True,
27
+ help="Local file containing Redis and vault settings.")
28
+ @click.option("--reload", is_flag=True, help="Enable Uvicorn auto-reload for local development.")
29
+ def proxy(host: str, port: int, upstream_base_url: str | None, provider: str,
30
+ mode: str, env_file: str, reload: bool) -> None:
31
+ """Start the local OpenAI-compatible proxy server."""
32
+ if upstream_base_url:
33
+ os.environ["AEGIS_UPSTREAM_BASE_URL"] = upstream_base_url
34
+ os.environ["AEGIS_UPSTREAM_PROVIDER"] = provider.lower()
35
+ os.environ["AEGIS_MODE"] = mode.lower()
36
+ os.environ["AEGIS_ENV_FILE"] = env_file
37
+
38
+ if not os.getenv("AEGIS_UPSTREAM_BASE_URL"):
39
+ raise click.UsageError("set --upstream-base-url or AEGIS_UPSTREAM_BASE_URL")
40
+
41
+ import uvicorn
42
+
43
+ click.echo(f"Starting AEGISMCP proxy on http://{host}:{port} ({mode} mode, {provider} upstream)")
44
+ uvicorn.run("proxy_server:app", host=host, port=port, reload=reload)