securityagent-core 4.18.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.
- securityagent_core-4.18.0/LICENSE +8 -0
- securityagent_core-4.18.0/MANIFEST.in +4 -0
- securityagent_core-4.18.0/PKG-INFO +121 -0
- securityagent_core-4.18.0/README.md +71 -0
- securityagent_core-4.18.0/pyproject.toml +57 -0
- securityagent_core-4.18.0/setup.cfg +4 -0
- securityagent_core-4.18.0/src/endpoint_agent/__init__.py +3 -0
- securityagent_core-4.18.0/src/endpoint_agent/__main__.py +105 -0
- securityagent_core-4.18.0/src/endpoint_agent/alerting/__init__.py +0 -0
- securityagent_core-4.18.0/src/endpoint_agent/alerting/alert_manager.py +71 -0
- securityagent_core-4.18.0/src/endpoint_agent/alerting/console_handler.py +27 -0
- securityagent_core-4.18.0/src/endpoint_agent/alerting/log_handler.py +34 -0
- securityagent_core-4.18.0/src/endpoint_agent/alerting/webhook_handler.py +68 -0
- securityagent_core-4.18.0/src/endpoint_agent/cli.py +466 -0
- securityagent_core-4.18.0/src/endpoint_agent/cloud_bridge/__init__.py +0 -0
- securityagent_core-4.18.0/src/endpoint_agent/cloud_bridge/lockdown.py +87 -0
- securityagent_core-4.18.0/src/endpoint_agent/config/__init__.py +0 -0
- securityagent_core-4.18.0/src/endpoint_agent/config/privacy_mode.py +145 -0
- securityagent_core-4.18.0/src/endpoint_agent/config/settings.py +1777 -0
- securityagent_core-4.18.0/src/endpoint_agent/engine.py +307 -0
- securityagent_core-4.18.0/src/endpoint_agent/monitors/__init__.py +0 -0
- securityagent_core-4.18.0/src/endpoint_agent/monitors/behavioral_monitor.py +809 -0
- securityagent_core-4.18.0/src/endpoint_agent/monitors/file_monitor.py +146 -0
- securityagent_core-4.18.0/src/endpoint_agent/monitors/honeypot_monitor.py +155 -0
- securityagent_core-4.18.0/src/endpoint_agent/monitors/privilege_monitor.py +150 -0
- securityagent_core-4.18.0/src/endpoint_agent/monitors/process_monitor.py +334 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/__init__.py +0 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/code_fingerprint.py +357 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/content_analyzer.py +209 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/credential_scanner.py +103 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/data_flow_tracker.py +421 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/dlp_scanner.py +684 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/finding_validators.py +589 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/installation_scanner.py +170 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/knowledge_graph.py +445 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/lethal_trifecta.py +182 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/llm_analyzer.py +268 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/llm_provider.py +398 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/memory_guard.py +189 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/ml_classifier.py +647 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/model_locality.py +285 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/nist_tagger.py +323 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/prompt_analyzer.py +215 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/prompt_guard.py +183 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/rule_classifier.py +154 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/shadow_ai_detector.py +299 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/text_extractor.py +586 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/tool_call_guard.py +175 -0
- securityagent_core-4.18.0/src/endpoint_agent/scanners/vuln_scanner.py +420 -0
- securityagent_core-4.18.0/src/endpoint_agent/secure_fs.py +308 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/__init__.py +0 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_alert_manager.py +94 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_behavioral_monitor.py +873 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_cloud_bridge.py +72 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_credential_scanner.py +133 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_data_flow_tracker.py +94 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_dlp_scanner.py +391 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_engine.py +68 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_file_monitor.py +115 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_honeypot_monitor.py +126 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_installation_scanner.py +71 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_llm_analyzer.py +222 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_privilege_monitor.py +110 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_process_monitor.py +271 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_prompt_analyzer.py +484 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_prompt_guard.py +380 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_rule_classifier.py +238 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_secure_fs.py +429 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_semantic_disclosure.py +95 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_text_extractor.py +502 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_tool_call_guard.py +81 -0
- securityagent_core-4.18.0/src/endpoint_agent/tests/test_trial_manager.py +461 -0
- securityagent_core-4.18.0/src/endpoint_agent/trial_manager.py +127 -0
- securityagent_core-4.18.0/src/plugin.py +488 -0
- securityagent_core-4.18.0/src/policy/__init__.py +1 -0
- securityagent_core-4.18.0/src/policy/audit.py +91 -0
- securityagent_core-4.18.0/src/policy/chain_detector.py +402 -0
- securityagent_core-4.18.0/src/policy/engine.py +105 -0
- securityagent_core-4.18.0/src/policy/memory_bridge.py +119 -0
- securityagent_core-4.18.0/src/policy/rules.py +49 -0
- securityagent_core-4.18.0/src/policy/session.py +99 -0
- securityagent_core-4.18.0/src/scripts/secagent_check.py +537 -0
- securityagent_core-4.18.0/src/securityagent_core/__init__.py +3 -0
- securityagent_core-4.18.0/src/securityagent_core.egg-info/PKG-INFO +121 -0
- securityagent_core-4.18.0/src/securityagent_core.egg-info/SOURCES.txt +107 -0
- securityagent_core-4.18.0/src/securityagent_core.egg-info/dependency_links.txt +1 -0
- securityagent_core-4.18.0/src/securityagent_core.egg-info/entry_points.txt +2 -0
- securityagent_core-4.18.0/src/securityagent_core.egg-info/requires.txt +33 -0
- securityagent_core-4.18.0/src/securityagent_core.egg-info/top_level.txt +6 -0
- securityagent_core-4.18.0/src/skills/__init__.py +1 -0
- securityagent_core-4.18.0/src/skills/adapters/__init__.py +1 -0
- securityagent_core-4.18.0/src/skills/adapters/cli_adapter.py +45 -0
- securityagent_core-4.18.0/src/skills/adapters/mcp_server.py +158 -0
- securityagent_core-4.18.0/src/skills/adapters/mcp_sse_server.py +168 -0
- securityagent_core-4.18.0/src/skills/adapters/python_sdk.py +81 -0
- securityagent_core-4.18.0/src/skills/base.py +59 -0
- securityagent_core-4.18.0/src/skills/context.py +62 -0
- securityagent_core-4.18.0/src/skills/implementations/__init__.py +1 -0
- securityagent_core-4.18.0/src/skills/implementations/analyze_prompt.py +52 -0
- securityagent_core-4.18.0/src/skills/implementations/audit_log.py +50 -0
- securityagent_core-4.18.0/src/skills/implementations/check_policy.py +54 -0
- securityagent_core-4.18.0/src/skills/implementations/compliance_report.py +296 -0
- securityagent_core-4.18.0/src/skills/implementations/get_session_policy.py +44 -0
- securityagent_core-4.18.0/src/skills/implementations/scan_output.py +48 -0
- securityagent_core-4.18.0/src/skills/implementations/secure_exec.py +44 -0
- securityagent_core-4.18.0/src/skills/implementations/secure_read.py +67 -0
- securityagent_core-4.18.0/src/skills/implementations/token_optimize.py +128 -0
- securityagent_core-4.18.0/src/skills/registry.py +118 -0
- securityagent_core-4.18.0/tests/test_prompt_scenarios.py +698 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Copyright (c) 2026 SecureMind (securemind.live)
|
|
2
|
+
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software is proprietary. Unauthorized copying, distribution, modification,
|
|
6
|
+
or use of this software, via any medium, is strictly prohibited.
|
|
7
|
+
|
|
8
|
+
For licensing inquiries, contact: founders@securemind.live
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: securityagent-core
|
|
3
|
+
Version: 4.18.0
|
|
4
|
+
Summary: Local-first DLP engine and security layer for AI coding agents. Secures Copilot, Claude Code, Cursor, Windsurf, and any MCP-compatible agent.
|
|
5
|
+
Author-email: SecureMind <founders@securemind.live>
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Project-URL: Homepage, https://securemind.live
|
|
8
|
+
Project-URL: Documentation, https://secure-mind-live.github.io/agnostic-security-site/
|
|
9
|
+
Project-URL: Repository, https://github.com/secure-mind-live/securityagent-core
|
|
10
|
+
Project-URL: Issues, https://github.com/secure-mind-live/securityagent-core/issues
|
|
11
|
+
Keywords: security,dlp,ai-agents,llm,copilot,claude-code,cursor,mcp,pii,credentials
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Topic :: Security
|
|
15
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: watchdog
|
|
23
|
+
Requires-Dist: psutil
|
|
24
|
+
Requires-Dist: pydantic>=2.0
|
|
25
|
+
Requires-Dist: pypdf
|
|
26
|
+
Requires-Dist: openpyxl
|
|
27
|
+
Requires-Dist: python-docx
|
|
28
|
+
Requires-Dist: pyyaml
|
|
29
|
+
Provides-Extra: ml
|
|
30
|
+
Requires-Dist: sentence-transformers; extra == "ml"
|
|
31
|
+
Requires-Dist: scikit-learn; extra == "ml"
|
|
32
|
+
Requires-Dist: joblib; extra == "ml"
|
|
33
|
+
Requires-Dist: numpy; extra == "ml"
|
|
34
|
+
Provides-Extra: cloud
|
|
35
|
+
Requires-Dist: boto3; extra == "cloud"
|
|
36
|
+
Requires-Dist: PyJWT; extra == "cloud"
|
|
37
|
+
Requires-Dist: cryptography; extra == "cloud"
|
|
38
|
+
Provides-Extra: llm
|
|
39
|
+
Requires-Dist: ollama; extra == "llm"
|
|
40
|
+
Provides-Extra: ocr
|
|
41
|
+
Requires-Dist: PyMuPDF; extra == "ocr"
|
|
42
|
+
Requires-Dist: pytesseract; extra == "ocr"
|
|
43
|
+
Requires-Dist: Pillow; extra == "ocr"
|
|
44
|
+
Provides-Extra: dev
|
|
45
|
+
Requires-Dist: pytest; extra == "dev"
|
|
46
|
+
Requires-Dist: moto; extra == "dev"
|
|
47
|
+
Provides-Extra: all
|
|
48
|
+
Requires-Dist: securityagent-core[cloud,llm,ml,ocr]; extra == "all"
|
|
49
|
+
Dynamic: license-file
|
|
50
|
+
|
|
51
|
+
# securityagent-core
|
|
52
|
+
|
|
53
|
+
Shared DLP engine, security skills, and policy enforcement for AI coding agents. Used by [SecurityAgent](https://github.com/kaushikdharamshi/SecurityAgent) and [AgnosticSecurity](https://github.com/kaushikdharamshi/AgnosticSecurity).
|
|
54
|
+
|
|
55
|
+
## What's inside
|
|
56
|
+
|
|
57
|
+
| Package | What it does |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `endpoint_agent/` | DLP engine — file blocking (60+ path patterns), confidence-scored content scanning (PII, credentials, semantic disclosure detection) with structural validators (Luhn, SSA rules, entropy) and context-aware scoring, **data flow taint tracking** (tags sensitive data at ingress, detects at egress via hash/n-gram/substring matching), **tool call argument scanning** (MCP/function call DLP + taint registry), behavioral monitoring (8-signal anomaly scoring), honeypot traps, credential scanning. LLM intent analysis with llama3.1:8b default + fallback chain. Notebook-aware `.ipynb` extraction. PDF extraction via 3-tier pipeline (PyMuPDF → Tesseract OCR → pypdf fallback) with encrypted PDF detection |
|
|
60
|
+
| `skills/` | Agent-agnostic MCP skills — `secure_read`, `secure_exec`, `analyze_prompt`, `scan_output`, `check_policy`, `get_session_policy`, `audit_log` |
|
|
61
|
+
| `policy/` | Policy engine — per-session least privilege, behavioral chain detection (11 attack patterns), audit trail with agent attribution. Obsidian vault integration via `memory_bridge.py` for cross-session policy context |
|
|
62
|
+
| `obsidianMemory/` | Obsidian vault — daily session logs, second-brain knowledge base, used by `memory_bridge.py` for persistent threat/policy tracking |
|
|
63
|
+
| `plugin.py` | Standalone CLI entry point + `validate_exec()`, `validate_prompt()`, `validate_output()` pure functions |
|
|
64
|
+
|
|
65
|
+
## Install
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install git+https://github.com/kaushikdharamshi/securityagent-core.git
|
|
69
|
+
|
|
70
|
+
# With optional dependencies
|
|
71
|
+
pip install "securityagent-core[cloud] @ git+https://github.com/kaushikdharamshi/securityagent-core.git"
|
|
72
|
+
pip install "securityagent-core[llm] @ git+https://github.com/kaushikdharamshi/securityagent-core.git"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Usage
|
|
76
|
+
|
|
77
|
+
### Python SDK
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from skills.adapters.python_sdk import SecurityAgentSDK
|
|
81
|
+
|
|
82
|
+
sdk = SecurityAgentSDK(agent_id="my-agent", agent_type="langchain")
|
|
83
|
+
|
|
84
|
+
# DLP-gated file read
|
|
85
|
+
result = sdk.secure_read("/path/to/file")
|
|
86
|
+
|
|
87
|
+
# Command validation
|
|
88
|
+
result = sdk.secure_exec("ls -la")
|
|
89
|
+
|
|
90
|
+
# Prompt intent analysis
|
|
91
|
+
result = sdk.analyze_prompt("Get me all customer SSNs")
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### MCP Server
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
python -m skills.adapters.mcp_server # after pip install
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Any MCP-compatible client (Claude Code, Copilot, custom agents) can connect via stdio JSON-RPC.
|
|
101
|
+
|
|
102
|
+
### CLI
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
python -m plugin ~/.env # File read gate
|
|
106
|
+
python -m plugin --exec "cat ~/.env" # Exec validation
|
|
107
|
+
python -m plugin --prompt "Get all passwords" # Prompt analysis
|
|
108
|
+
python -m plugin --skill secure_read --params '{"path":"~/.env"}' # Skills layer
|
|
109
|
+
python -m plugin --mcp-server # MCP server
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Claude Code Integration
|
|
113
|
+
|
|
114
|
+
See [`integrations/claude_code/`](integrations/claude_code/) for PreToolUse hook configuration.
|
|
115
|
+
|
|
116
|
+
## Tests
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pip install -e ".[dev]"
|
|
120
|
+
pytest
|
|
121
|
+
```
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# securityagent-core
|
|
2
|
+
|
|
3
|
+
Shared DLP engine, security skills, and policy enforcement for AI coding agents. Used by [SecurityAgent](https://github.com/kaushikdharamshi/SecurityAgent) and [AgnosticSecurity](https://github.com/kaushikdharamshi/AgnosticSecurity).
|
|
4
|
+
|
|
5
|
+
## What's inside
|
|
6
|
+
|
|
7
|
+
| Package | What it does |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `endpoint_agent/` | DLP engine — file blocking (60+ path patterns), confidence-scored content scanning (PII, credentials, semantic disclosure detection) with structural validators (Luhn, SSA rules, entropy) and context-aware scoring, **data flow taint tracking** (tags sensitive data at ingress, detects at egress via hash/n-gram/substring matching), **tool call argument scanning** (MCP/function call DLP + taint registry), behavioral monitoring (8-signal anomaly scoring), honeypot traps, credential scanning. LLM intent analysis with llama3.1:8b default + fallback chain. Notebook-aware `.ipynb` extraction. PDF extraction via 3-tier pipeline (PyMuPDF → Tesseract OCR → pypdf fallback) with encrypted PDF detection |
|
|
10
|
+
| `skills/` | Agent-agnostic MCP skills — `secure_read`, `secure_exec`, `analyze_prompt`, `scan_output`, `check_policy`, `get_session_policy`, `audit_log` |
|
|
11
|
+
| `policy/` | Policy engine — per-session least privilege, behavioral chain detection (11 attack patterns), audit trail with agent attribution. Obsidian vault integration via `memory_bridge.py` for cross-session policy context |
|
|
12
|
+
| `obsidianMemory/` | Obsidian vault — daily session logs, second-brain knowledge base, used by `memory_bridge.py` for persistent threat/policy tracking |
|
|
13
|
+
| `plugin.py` | Standalone CLI entry point + `validate_exec()`, `validate_prompt()`, `validate_output()` pure functions |
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install git+https://github.com/kaushikdharamshi/securityagent-core.git
|
|
19
|
+
|
|
20
|
+
# With optional dependencies
|
|
21
|
+
pip install "securityagent-core[cloud] @ git+https://github.com/kaushikdharamshi/securityagent-core.git"
|
|
22
|
+
pip install "securityagent-core[llm] @ git+https://github.com/kaushikdharamshi/securityagent-core.git"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Python SDK
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from skills.adapters.python_sdk import SecurityAgentSDK
|
|
31
|
+
|
|
32
|
+
sdk = SecurityAgentSDK(agent_id="my-agent", agent_type="langchain")
|
|
33
|
+
|
|
34
|
+
# DLP-gated file read
|
|
35
|
+
result = sdk.secure_read("/path/to/file")
|
|
36
|
+
|
|
37
|
+
# Command validation
|
|
38
|
+
result = sdk.secure_exec("ls -la")
|
|
39
|
+
|
|
40
|
+
# Prompt intent analysis
|
|
41
|
+
result = sdk.analyze_prompt("Get me all customer SSNs")
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### MCP Server
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
python -m skills.adapters.mcp_server # after pip install
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Any MCP-compatible client (Claude Code, Copilot, custom agents) can connect via stdio JSON-RPC.
|
|
51
|
+
|
|
52
|
+
### CLI
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
python -m plugin ~/.env # File read gate
|
|
56
|
+
python -m plugin --exec "cat ~/.env" # Exec validation
|
|
57
|
+
python -m plugin --prompt "Get all passwords" # Prompt analysis
|
|
58
|
+
python -m plugin --skill secure_read --params '{"path":"~/.env"}' # Skills layer
|
|
59
|
+
python -m plugin --mcp-server # MCP server
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Claude Code Integration
|
|
63
|
+
|
|
64
|
+
See [`integrations/claude_code/`](integrations/claude_code/) for PreToolUse hook configuration.
|
|
65
|
+
|
|
66
|
+
## Tests
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install -e ".[dev]"
|
|
70
|
+
pytest
|
|
71
|
+
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "securityagent-core"
|
|
7
|
+
version = "4.18.0"
|
|
8
|
+
description = "Local-first DLP engine and security layer for AI coding agents. Secures Copilot, Claude Code, Cursor, Windsurf, and any MCP-compatible agent."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "Proprietary"}
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "SecureMind", email = "founders@securemind.live"},
|
|
14
|
+
]
|
|
15
|
+
keywords = ["security", "dlp", "ai-agents", "llm", "copilot", "claude-code", "cursor", "mcp", "pii", "credentials"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Topic :: Security",
|
|
20
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"watchdog",
|
|
27
|
+
"psutil",
|
|
28
|
+
"pydantic>=2.0",
|
|
29
|
+
"pypdf",
|
|
30
|
+
"openpyxl",
|
|
31
|
+
"python-docx",
|
|
32
|
+
"pyyaml",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Homepage = "https://securemind.live"
|
|
37
|
+
Documentation = "https://secure-mind-live.github.io/agnostic-security-site/"
|
|
38
|
+
Repository = "https://github.com/secure-mind-live/securityagent-core"
|
|
39
|
+
Issues = "https://github.com/secure-mind-live/securityagent-core/issues"
|
|
40
|
+
|
|
41
|
+
[project.scripts]
|
|
42
|
+
secagent = "endpoint_agent.cli:main"
|
|
43
|
+
|
|
44
|
+
[project.optional-dependencies]
|
|
45
|
+
ml = ["sentence-transformers", "scikit-learn", "joblib", "numpy"]
|
|
46
|
+
cloud = ["boto3", "PyJWT", "cryptography"]
|
|
47
|
+
llm = ["ollama"]
|
|
48
|
+
ocr = ["PyMuPDF", "pytesseract", "Pillow"]
|
|
49
|
+
dev = ["pytest", "moto"]
|
|
50
|
+
all = ["securityagent-core[ml,cloud,llm,ocr]"]
|
|
51
|
+
|
|
52
|
+
[tool.setuptools.packages.find]
|
|
53
|
+
where = ["src"]
|
|
54
|
+
|
|
55
|
+
[tool.pytest.ini_options]
|
|
56
|
+
pythonpath = ["src"]
|
|
57
|
+
testpaths = ["tests", "src/endpoint_agent/tests"]
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI entry point for the endpoint security agent.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python -m endpoint_agent watch [--watch-dirs DIR ...]
|
|
6
|
+
python -m endpoint_agent scan [DIR ...]
|
|
7
|
+
python -m endpoint_agent status
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import logging
|
|
12
|
+
import sys
|
|
13
|
+
|
|
14
|
+
from endpoint_agent.config.settings import DEFAULT_WATCH_DIRS
|
|
15
|
+
from endpoint_agent.engine import SecurityEngine
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def main():
|
|
19
|
+
parser = argparse.ArgumentParser(
|
|
20
|
+
prog="endpoint_agent",
|
|
21
|
+
description="Local endpoint security agent - detects malicious AI agents and exposed credentials",
|
|
22
|
+
)
|
|
23
|
+
parser.add_argument(
|
|
24
|
+
"--verbose",
|
|
25
|
+
"-v",
|
|
26
|
+
action="store_true",
|
|
27
|
+
help="Enable debug logging",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
|
31
|
+
|
|
32
|
+
# watch subcommand
|
|
33
|
+
watch_parser = subparsers.add_parser("watch", help="Start real-time monitoring")
|
|
34
|
+
watch_parser.add_argument(
|
|
35
|
+
"--watch-dirs",
|
|
36
|
+
nargs="+",
|
|
37
|
+
default=None,
|
|
38
|
+
help="Directories to monitor (default: home + cwd)",
|
|
39
|
+
)
|
|
40
|
+
watch_parser.add_argument(
|
|
41
|
+
"--log-file",
|
|
42
|
+
default=None,
|
|
43
|
+
help="Path for audit log (default: ~/.securityagent/audit.log)",
|
|
44
|
+
)
|
|
45
|
+
watch_parser.add_argument(
|
|
46
|
+
"--alert-webhook",
|
|
47
|
+
default=None,
|
|
48
|
+
help="Webhook URL for remote alert notifications",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# scan subcommand
|
|
52
|
+
scan_parser = subparsers.add_parser(
|
|
53
|
+
"scan", help="One-shot credential and threat scan"
|
|
54
|
+
)
|
|
55
|
+
scan_parser.add_argument(
|
|
56
|
+
"directories",
|
|
57
|
+
nargs="*",
|
|
58
|
+
default=["."],
|
|
59
|
+
help="Directories to scan (default: current directory)",
|
|
60
|
+
)
|
|
61
|
+
scan_parser.add_argument(
|
|
62
|
+
"--log-file",
|
|
63
|
+
default=None,
|
|
64
|
+
help="Path for audit log",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# status subcommand
|
|
68
|
+
subparsers.add_parser("status", help="Show current security status")
|
|
69
|
+
|
|
70
|
+
args = parser.parse_args()
|
|
71
|
+
|
|
72
|
+
# Configure logging
|
|
73
|
+
log_level = logging.DEBUG if args.verbose else logging.WARNING
|
|
74
|
+
logging.basicConfig(
|
|
75
|
+
level=log_level,
|
|
76
|
+
format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
if args.command is None:
|
|
80
|
+
parser.print_help()
|
|
81
|
+
sys.exit(1)
|
|
82
|
+
|
|
83
|
+
if args.command == "watch":
|
|
84
|
+
watch_dirs = args.watch_dirs or DEFAULT_WATCH_DIRS
|
|
85
|
+
engine = SecurityEngine(
|
|
86
|
+
watch_dirs=watch_dirs,
|
|
87
|
+
log_file=args.log_file,
|
|
88
|
+
webhook_url=args.alert_webhook,
|
|
89
|
+
)
|
|
90
|
+
engine.run_watch()
|
|
91
|
+
|
|
92
|
+
elif args.command == "scan":
|
|
93
|
+
engine = SecurityEngine(
|
|
94
|
+
watch_dirs=args.directories,
|
|
95
|
+
log_file=getattr(args, "log_file", None),
|
|
96
|
+
)
|
|
97
|
+
engine.run_scan(args.directories)
|
|
98
|
+
|
|
99
|
+
elif args.command == "status":
|
|
100
|
+
engine = SecurityEngine(watch_dirs=DEFAULT_WATCH_DIRS)
|
|
101
|
+
engine.run_status()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if __name__ == "__main__":
|
|
105
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Central alert dispatcher.
|
|
3
|
+
|
|
4
|
+
All monitors and scanners call alert_callback(severity, event_type, details)
|
|
5
|
+
which routes through this manager to registered handlers.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import time
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from typing import Any, Callable, Dict, List
|
|
12
|
+
|
|
13
|
+
from endpoint_agent.config.settings import ALERT_DEDUP_WINDOW_SECONDS
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class SecurityAlert:
|
|
20
|
+
"""Represents a single security alert."""
|
|
21
|
+
|
|
22
|
+
timestamp: float
|
|
23
|
+
severity: str
|
|
24
|
+
event_type: str
|
|
25
|
+
details: Dict[str, Any]
|
|
26
|
+
alert_id: str = ""
|
|
27
|
+
|
|
28
|
+
def __post_init__(self):
|
|
29
|
+
if not self.alert_id:
|
|
30
|
+
self.alert_id = f"{self.event_type}-{int(self.timestamp * 1000)}"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class AlertManager:
|
|
34
|
+
"""Central alert dispatcher. Routes alerts to registered handlers."""
|
|
35
|
+
|
|
36
|
+
def __init__(self):
|
|
37
|
+
self._handlers: List[Callable[[SecurityAlert], None]] = []
|
|
38
|
+
self._alert_history: List[SecurityAlert] = []
|
|
39
|
+
self._recent_keys: Dict[str, float] = {}
|
|
40
|
+
|
|
41
|
+
def register_handler(self, handler: Callable[[SecurityAlert], None]):
|
|
42
|
+
"""Register an alert handler (console, log file, webhook, etc.)."""
|
|
43
|
+
self._handlers.append(handler)
|
|
44
|
+
|
|
45
|
+
def alert(self, severity: str, event_type: str, details: Dict[str, Any]):
|
|
46
|
+
"""Create and dispatch an alert. This is the callback passed to all monitors."""
|
|
47
|
+
dedup_key = f"{event_type}:{details.get('path', '')}:{details.get('pid', '')}"
|
|
48
|
+
now = time.time()
|
|
49
|
+
|
|
50
|
+
if dedup_key in self._recent_keys:
|
|
51
|
+
if now - self._recent_keys[dedup_key] < ALERT_DEDUP_WINDOW_SECONDS:
|
|
52
|
+
return
|
|
53
|
+
self._recent_keys[dedup_key] = now
|
|
54
|
+
|
|
55
|
+
alert_obj = SecurityAlert(
|
|
56
|
+
timestamp=now,
|
|
57
|
+
severity=severity,
|
|
58
|
+
event_type=event_type,
|
|
59
|
+
details=details,
|
|
60
|
+
)
|
|
61
|
+
self._alert_history.append(alert_obj)
|
|
62
|
+
|
|
63
|
+
for handler in self._handlers:
|
|
64
|
+
try:
|
|
65
|
+
handler(alert_obj)
|
|
66
|
+
except Exception:
|
|
67
|
+
logger.exception("Alert handler failed for %s", event_type)
|
|
68
|
+
|
|
69
|
+
def get_history(self) -> List[SecurityAlert]:
|
|
70
|
+
"""Return all alerts dispatched so far."""
|
|
71
|
+
return list(self._alert_history)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Console alert handler with ANSI color-coded output."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
# Enable ANSI escape codes on Windows 10+
|
|
8
|
+
if os.name == "nt":
|
|
9
|
+
os.system("")
|
|
10
|
+
|
|
11
|
+
COLORS = {
|
|
12
|
+
"CRITICAL": "\033[91m", # Red
|
|
13
|
+
"WARNING": "\033[93m", # Yellow
|
|
14
|
+
"INFO": "\033[94m", # Blue
|
|
15
|
+
"RESET": "\033[0m",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def console_alert_handler(alert):
|
|
20
|
+
"""Print alerts to the terminal with color coding."""
|
|
21
|
+
color = COLORS.get(alert.severity, "")
|
|
22
|
+
reset = COLORS["RESET"]
|
|
23
|
+
ts = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(alert.timestamp))
|
|
24
|
+
print(
|
|
25
|
+
f"{color}[{alert.severity}]{reset} {ts} | {alert.event_type} | {alert.details}",
|
|
26
|
+
file=sys.stderr,
|
|
27
|
+
)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""JSON-lines audit log handler for persistent alert storage."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
import os
|
|
6
|
+
import time
|
|
7
|
+
|
|
8
|
+
from endpoint_agent.config.settings import DEFAULT_LOG_FILE
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def create_log_handler(log_file=None):
|
|
14
|
+
"""Factory: returns a handler function that writes alerts to a JSON log file."""
|
|
15
|
+
log_path = log_file or DEFAULT_LOG_FILE
|
|
16
|
+
os.makedirs(os.path.dirname(log_path), exist_ok=True)
|
|
17
|
+
|
|
18
|
+
def log_alert_handler(alert):
|
|
19
|
+
entry = {
|
|
20
|
+
"timestamp": time.strftime(
|
|
21
|
+
"%Y-%m-%dT%H:%M:%SZ", time.gmtime(alert.timestamp)
|
|
22
|
+
),
|
|
23
|
+
"severity": alert.severity,
|
|
24
|
+
"event_type": alert.event_type,
|
|
25
|
+
"details": alert.details,
|
|
26
|
+
"alert_id": alert.alert_id,
|
|
27
|
+
}
|
|
28
|
+
try:
|
|
29
|
+
with open(log_path, "a") as f:
|
|
30
|
+
f.write(json.dumps(entry) + "\n")
|
|
31
|
+
except OSError:
|
|
32
|
+
logger.error("Failed to write audit log to %s", log_path)
|
|
33
|
+
|
|
34
|
+
return log_alert_handler
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Webhook and AWS SNS alert handlers for cloud-side notification.
|
|
3
|
+
|
|
4
|
+
These are optional handlers - enabled via CLI flags or environment variables.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import logging
|
|
9
|
+
from urllib.error import URLError
|
|
10
|
+
from urllib.request import Request, urlopen
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def create_webhook_handler(webhook_url: str):
|
|
16
|
+
"""Factory: returns a handler that POSTs alerts to a webhook URL."""
|
|
17
|
+
|
|
18
|
+
def webhook_alert_handler(alert):
|
|
19
|
+
payload = json.dumps(
|
|
20
|
+
{
|
|
21
|
+
"severity": alert.severity,
|
|
22
|
+
"event_type": alert.event_type,
|
|
23
|
+
"details": alert.details,
|
|
24
|
+
"alert_id": alert.alert_id,
|
|
25
|
+
}
|
|
26
|
+
).encode("utf-8")
|
|
27
|
+
|
|
28
|
+
req = Request(
|
|
29
|
+
webhook_url,
|
|
30
|
+
data=payload,
|
|
31
|
+
headers={"Content-Type": "application/json"},
|
|
32
|
+
method="POST",
|
|
33
|
+
)
|
|
34
|
+
try:
|
|
35
|
+
with urlopen(req, timeout=5) as resp:
|
|
36
|
+
logger.debug("Webhook response: %d", resp.status)
|
|
37
|
+
except (URLError, OSError):
|
|
38
|
+
logger.warning("Failed to send webhook alert to %s", webhook_url)
|
|
39
|
+
|
|
40
|
+
return webhook_alert_handler
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def create_sns_handler(topic_arn: str, region: str = "us-east-1"):
|
|
44
|
+
"""Factory: returns a handler that publishes alerts to an AWS SNS topic."""
|
|
45
|
+
|
|
46
|
+
def sns_alert_handler(alert):
|
|
47
|
+
try:
|
|
48
|
+
import boto3
|
|
49
|
+
|
|
50
|
+
client = boto3.client("sns", region_name=region)
|
|
51
|
+
client.publish(
|
|
52
|
+
TopicArn=topic_arn,
|
|
53
|
+
Subject=f"[{alert.severity}] {alert.event_type}"[:100],
|
|
54
|
+
Message=json.dumps(
|
|
55
|
+
{
|
|
56
|
+
"source": "endpoint_agent",
|
|
57
|
+
"severity": alert.severity,
|
|
58
|
+
"event_type": alert.event_type,
|
|
59
|
+
"details": alert.details,
|
|
60
|
+
"alert_id": alert.alert_id,
|
|
61
|
+
},
|
|
62
|
+
indent=2,
|
|
63
|
+
),
|
|
64
|
+
)
|
|
65
|
+
except Exception:
|
|
66
|
+
logger.warning("Failed to publish SNS alert to %s", topic_arn)
|
|
67
|
+
|
|
68
|
+
return sns_alert_handler
|