guardledger 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.
Files changed (71) hide show
  1. guardledger-0.1.0/.claude/launch.json +11 -0
  2. guardledger-0.1.0/.env.example +14 -0
  3. guardledger-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
  4. guardledger-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +13 -0
  5. guardledger-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +10 -0
  6. guardledger-0.1.0/.github/workflows/ci.yml +24 -0
  7. guardledger-0.1.0/.github/workflows/release.yml +25 -0
  8. guardledger-0.1.0/.gitignore +32 -0
  9. guardledger-0.1.0/ARCHITECTURE.md +148 -0
  10. guardledger-0.1.0/CHANGELOG.md +40 -0
  11. guardledger-0.1.0/COMPLIANCE.md +90 -0
  12. guardledger-0.1.0/CONTRIBUTING.md +30 -0
  13. guardledger-0.1.0/DECISIONS.md +85 -0
  14. guardledger-0.1.0/DEMO.md +90 -0
  15. guardledger-0.1.0/INTEGRATIONS.md +85 -0
  16. guardledger-0.1.0/LAUNCH.md +112 -0
  17. guardledger-0.1.0/LICENSE +173 -0
  18. guardledger-0.1.0/Makefile +22 -0
  19. guardledger-0.1.0/PKG-INFO +180 -0
  20. guardledger-0.1.0/PRD.md +97 -0
  21. guardledger-0.1.0/PUBLISHING.md +46 -0
  22. guardledger-0.1.0/README.md +149 -0
  23. guardledger-0.1.0/RESEARCH.md +282 -0
  24. guardledger-0.1.0/ROADMAP.md +62 -0
  25. guardledger-0.1.0/SECURITY.md +60 -0
  26. guardledger-0.1.0/examples/benchmark.py +48 -0
  27. guardledger-0.1.0/examples/generic_agent.py +140 -0
  28. guardledger-0.1.0/examples/trading_agent.py +138 -0
  29. guardledger-0.1.0/launch/outreach.md +42 -0
  30. guardledger-0.1.0/launch/reddit.md +29 -0
  31. guardledger-0.1.0/launch/show-hn.md +34 -0
  32. guardledger-0.1.0/launch/x-thread.md +37 -0
  33. guardledger-0.1.0/policies/example.yaml +41 -0
  34. guardledger-0.1.0/policies/starter.yaml +38 -0
  35. guardledger-0.1.0/pyproject.toml +56 -0
  36. guardledger-0.1.0/site/index.html +120 -0
  37. guardledger-0.1.0/src/sentinel/__init__.py +53 -0
  38. guardledger-0.1.0/src/sentinel/api.py +126 -0
  39. guardledger-0.1.0/src/sentinel/approvals.py +122 -0
  40. guardledger-0.1.0/src/sentinel/audit.py +171 -0
  41. guardledger-0.1.0/src/sentinel/cli.py +166 -0
  42. guardledger-0.1.0/src/sentinel/compliance.py +77 -0
  43. guardledger-0.1.0/src/sentinel/config.py +46 -0
  44. guardledger-0.1.0/src/sentinel/dashboard/index.html +197 -0
  45. guardledger-0.1.0/src/sentinel/db.py +19 -0
  46. guardledger-0.1.0/src/sentinel/detector.py +97 -0
  47. guardledger-0.1.0/src/sentinel/frameworks.py +239 -0
  48. guardledger-0.1.0/src/sentinel/killswitch.py +58 -0
  49. guardledger-0.1.0/src/sentinel/mcp_proxy.py +61 -0
  50. guardledger-0.1.0/src/sentinel/mcp_server.py +79 -0
  51. guardledger-0.1.0/src/sentinel/models.py +88 -0
  52. guardledger-0.1.0/src/sentinel/otel.py +80 -0
  53. guardledger-0.1.0/src/sentinel/policy.py +128 -0
  54. guardledger-0.1.0/src/sentinel/py.typed +0 -0
  55. guardledger-0.1.0/src/sentinel/ratelimit.py +46 -0
  56. guardledger-0.1.0/src/sentinel/redaction.py +46 -0
  57. guardledger-0.1.0/src/sentinel/sentinel.py +191 -0
  58. guardledger-0.1.0/tests/test_api.py +111 -0
  59. guardledger-0.1.0/tests/test_approvals.py +74 -0
  60. guardledger-0.1.0/tests/test_audit.py +82 -0
  61. guardledger-0.1.0/tests/test_compliance.py +25 -0
  62. guardledger-0.1.0/tests/test_db.py +19 -0
  63. guardledger-0.1.0/tests/test_detector.py +71 -0
  64. guardledger-0.1.0/tests/test_frameworks.py +49 -0
  65. guardledger-0.1.0/tests/test_killswitch.py +28 -0
  66. guardledger-0.1.0/tests/test_mcp_proxy.py +119 -0
  67. guardledger-0.1.0/tests/test_mcp_server.py +62 -0
  68. guardledger-0.1.0/tests/test_otel.py +49 -0
  69. guardledger-0.1.0/tests/test_policy.py +109 -0
  70. guardledger-0.1.0/tests/test_ratelimit.py +41 -0
  71. guardledger-0.1.0/tests/test_sentinel.py +245 -0
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": "0.0.1",
3
+ "configurations": [
4
+ {
5
+ "name": "sentinel",
6
+ "runtimeExecutable": "./.venv/bin/sentinel",
7
+ "runtimeArgs": ["serve"],
8
+ "port": 8787
9
+ }
10
+ ]
11
+ }
@@ -0,0 +1,14 @@
1
+ # Sentinel configuration (copy to .env; .env is git-ignored)
2
+
3
+ # Where the tamper-evident audit log lives (SQLite).
4
+ SENTINEL_DB_PATH=./data/sentinel.db
5
+
6
+ # Active policy file (YAML).
7
+ SENTINEL_POLICY_PATH=./policies/starter.yaml
8
+
9
+ # Minimal control API / dashboard.
10
+ SENTINEL_API_HOST=127.0.0.1
11
+ SENTINEL_API_PORT=8787
12
+
13
+ # Comma-separated arg keys whose values are redacted before they ever hit the audit log.
14
+ SENTINEL_REDACT_KEYS=api_key,apikey,token,password,passwd,secret,authorization,access_token,private_key
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Bug report
3
+ about: Something isn't working as documented
4
+ labels: bug
5
+ ---
6
+
7
+ **What happened**
8
+
9
+ **What you expected**
10
+
11
+ **Steps to reproduce**
12
+ 1.
13
+ 2.
14
+
15
+ **Environment**
16
+ - Sentinel version / commit:
17
+ - Python version:
18
+ - OS:
19
+
20
+ **Logs / output** (do NOT paste live secrets or customer data)
@@ -0,0 +1,13 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea or improvement
4
+ labels: enhancement
5
+ ---
6
+
7
+ **The problem / use case** (what are you trying to do?)
8
+
9
+ **Proposed solution**
10
+
11
+ **Alternatives you considered**
12
+
13
+ **Which framework / agent are you using?** (LangChain, OpenAI Agents, CrewAI, MCP, plain Python, …)
@@ -0,0 +1,10 @@
1
+ ## What this changes
2
+
3
+ ## Why
4
+
5
+ ## Checklist
6
+ - [ ] `pytest` is green
7
+ - [ ] `ruff check src tests` is clean
8
+ - [ ] Added/updated tests (security-critical code — policy, audit, kill switch — is tests-first)
9
+ - [ ] Docs updated if behavior changed
10
+ - [ ] No secrets committed; the audit log stays append-only / tamper-evident
@@ -0,0 +1,24 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ python-version: ["3.11", "3.12", "3.13"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: ${{ matrix.python-version }}
19
+ - name: Install
20
+ run: pip install -e ".[dev]"
21
+ - name: Lint
22
+ run: ruff check src tests
23
+ - name: Test
24
+ run: pytest
@@ -0,0 +1,25 @@
1
+ name: release
2
+
3
+ # Publishes to PyPI when a version tag (v*) is pushed, using PyPI Trusted Publishing
4
+ # (OIDC — no API token stored in the repo). See PUBLISHING.md for the one-time setup.
5
+ on:
6
+ push:
7
+ tags: ["v*"]
8
+
9
+ jobs:
10
+ publish:
11
+ runs-on: ubuntu-latest
12
+ environment: pypi
13
+ permissions:
14
+ id-token: write # required for Trusted Publishing
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+ - name: Build
21
+ run: |
22
+ pip install build
23
+ python -m build
24
+ - name: Publish to PyPI
25
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,32 @@
1
+ # Secrets
2
+ .env
3
+ .env.*
4
+ !.env.example
5
+
6
+ # Dependencies
7
+ node_modules/
8
+ __pycache__/
9
+ .venv/
10
+ venv/
11
+ *.egg-info/
12
+
13
+ # Build / artifacts
14
+ dist/
15
+ build/
16
+ *.log
17
+ .wrangler/
18
+
19
+ # Local audit/data stores (do not commit runtime data)
20
+ *.db
21
+ *.db-wal
22
+ *.db-shm
23
+ *.sqlite
24
+ *.sqlite-wal
25
+ *.sqlite-shm
26
+ *.sqlite3
27
+ data/
28
+
29
+ # OS / editor
30
+ .DS_Store
31
+ .idea/
32
+ .vscode/
@@ -0,0 +1,148 @@
1
+ # ARCHITECTURE.md — Sentinel MVP
2
+
3
+ > v0.1 · Phase 2. Stack ו-interception אושרו 2026-06-13. כולל threat model.
4
+
5
+ ---
6
+
7
+ ## 1. עקרונות מנחים
8
+
9
+ 1. **Default-deny** — פעולה שלא הותרה במפורש נחסמת.
10
+ 2. **Fail-closed** — אם שכבת ההכרעה עצמה נכשלת (שגיאה ב-policy/audit), הפעולה **נחסמת**, לא רצה. אבטחה > זמינות.
11
+ 3. **Append-only + tamper-evident** — ה-audit לא נמחק ולא משתנה; כל שינוי מתגלה ב-`verify`.
12
+ 4. **Interceptor מופשט** — הליבה (policy/audit/kill/detect) לא יודעת איך יורטה הפעולה. SDK wrapper היום, MCP-proxy מחר — אותה ליבה.
13
+ 5. **Sentinel הוא נקודת כשל high-value** — מתייחסים לקוד שלנו עצמו כמשטח תקיפה (סעיף 6).
14
+
15
+ ## 2. Stack (אושר)
16
+
17
+ | רכיב | בחירה | נימוק |
18
+ |---|---|---|
19
+ | שפה | **Python 3.11+** | העולם של MeiroX + ecosystem הסוכנים; מסלול מהיר |
20
+ | Interception | **SDK wrapper** (decorator/wrap) מאחורי `Interceptor` interface | מכסה את ה-tools הישירים של MeiroX, framework-agnostic, דטרמיניסטי ל-tests-first; MCP-proxy נכנס כ-adapter בלי שכתוב |
21
+ | Audit store | **SQLite** + hash-chain | embeddable, tamper-evident פשוט, משדרג ל-Postgres |
22
+ | Policy | **YAML** (`yaml.safe_load`) | declarative, קריא ללקוח, ניתן לעריכה ב-dashboard |
23
+ | API/Dashboard | **FastAPI** + עמוד HTML מינימלי | קל, async, OpenAPI חינם |
24
+ | בדיקות | **pytest** | tests-first על הליבה הקריטית |
25
+
26
+ ## 3. דיאגרמת רכיבים + data flow
27
+
28
+ ```
29
+ agent (למשל trading_agent)
30
+ │ tool_call(name, args)
31
+
32
+ ┌─────────────────────────────────────────────────────────┐
33
+ │ Interceptor (SDK wrapper) → sentinel.check(ToolCall) │
34
+ └───────────────────────────────┬─────────────────────────┘
35
+
36
+ ┌──────────────────────────────────────────┐
37
+ │ 1. KillSwitch.active? → block(reason=kill)│ (fail-closed)
38
+ │ 2. Detector.inspect() → flags[] │ (מסמן, לא חוסם)
39
+ │ 3. Policy.evaluate() → allow/block/ │ (default-deny)
40
+ │ require_approval │
41
+ │ 4. combine → Decision │
42
+ └───────────────┬────────────────────────────┘
43
+ allow ───────┤────── block / require_approval
44
+ │ │
45
+ execute tool_fn │ (לא מבוצע)
46
+ (try/except) │
47
+ │ │
48
+ ▼ ▼
49
+ ┌──────────────────────────────────────────┐
50
+ │ AuditLog.append(record) (hash-chained, │
51
+ │ redacted, compliance-mapped) │
52
+ └───────────────┬────────────────────────────┘
53
+
54
+ ┌──────────────────────────────────────────┐
55
+ │ FastAPI: /actions /audit/verify /export │
56
+ │ /policy /kill /status + dashboard│
57
+ └────────────────────────────────────────────┘
58
+ ```
59
+
60
+ **רצף לקריאה מותרת:** check → allow → execute → append record (status=`executed`/`error`).
61
+ **רצף לקריאה חסומה:** check → block → append record (status=`blocked`/`killed`/`pending_approval`), ה-tool **לא** מבוצע.
62
+
63
+ ## 4. מודל הנתונים — רשומת Audit (לב המוצר)
64
+
65
+ ```
66
+ AuditRecord
67
+ seq int # מונוטוני
68
+ ts float/iso # זמן
69
+ agent_id str
70
+ session_id str
71
+ tool str
72
+ args dict # אחרי redaction
73
+ decision enum # allow | block | require_approval
74
+ policy_rule str|null # id הכלל שהתאים (או null=default-deny)
75
+ reason str
76
+ flags [str] # מה-Detector
77
+ status enum # executed | blocked | error | pending_approval | killed
78
+ error str|null
79
+ compliance {eu_ai_act_art12: bool, owasp_agentic: [str]}
80
+ prev_hash str(64)
81
+ hash str(64) # sha256( prev_hash + canonical_json(payload) )
82
+ ```
83
+
84
+ **Hash-chain:** רשומת genesis עם `prev_hash="0"*64`. כל רשומה: `hash = sha256(prev_hash + canonical_json(הכל חוץ מ-hash))`. `verify()` מחשב מחדש את כל השרשרת ובודק (א) כל hash תואם, (ב) כל `prev_hash` תואם ל-hash הקודם. כל עריכה/מחיקה/שינוי-סדר באמצע → מתגלה. (truncation של הזנב — מיטיגציה ב-`ROADMAP.md`: anchoring חיצוני תקופתי.)
85
+
86
+ > הערה: רשומה אחת לכל tool call, נכתבת אחרי ניסיון הביצוע (עטוף ב-try/except, כך ששגיאת tool עדיין נרשמת). הפער היחיד: process kill באמצע ביצוע. מיטיגציה (roadmap): two-phase logging (intent לפני, outcome אחרי).
87
+
88
+ ## 5. מודל ה-Policy (YAML)
89
+
90
+ ```yaml
91
+ version: 1
92
+ default: deny # default-deny
93
+ rules:
94
+ - id: allow-reads
95
+ match: { tool: ["get_*", "read_*"] } # glob
96
+ action: allow
97
+ - id: cap-order
98
+ match:
99
+ tool: place_order
100
+ args: { amount: { gt: 500 } } # comparators: gt/gte/lt/lte/eq/in/contains
101
+ action: require_approval
102
+ - id: rate-limit-orders
103
+ match: { tool: place_order }
104
+ rate_limit: { max: 5, per_seconds: 60 } # מעל הסף → block
105
+ action: allow
106
+ - id: forbid-deletes
107
+ match: { tool: "delete_*" }
108
+ action: block
109
+ ```
110
+
111
+ הכרעה: **first-match-wins** (לפי סדר), אחרת `default`. תמיכה: glob על שם tool, comparators על args, rate_limit (sliding window in-memory ל-MVP), ו-`on_flag: block` אופציונלי להסלמה על flag מה-Detector.
112
+
113
+ ## 6. Threat Model (Sentinel עצמו כמשטח תקיפה)
114
+
115
+ | # | איום | מיטיגציה ב-MVP | סטטוס/roadmap |
116
+ |---|---|---|---|
117
+ | T1 | **Bypass** — קריאה ל-tool לא-עטוף | helper `wrap_all` + תיעוד; default-deny על מה שמוכר | מגבלת SDK-mode; proxy/egress עתידי הופך bypass לבלתי-אפשרי |
118
+ | T2 | **Audit tampering** — עריכת ה-DB | hash-chain → `verify` מגלה כל edit/reorder/delete | anchoring חיצוני נגד truncation (roadmap) |
119
+ | T3 | **Log-as-exfil / log injection** | redaction לפני כתיבה; args כ-data בלבד; canonical JSON | — |
120
+ | T4 | **Policy evasion** — args שמתחמקים מ-match | **default-deny** + טסטים על matchers | — |
121
+ | T5 | **Kill switch failure** | נבדק בכל קריאה, **persisted** (שורד restart), **fail-closed** אם לא נקרא | — |
122
+ | T6 | **Sentinel כ-vector** — ReDoS/YAML | `yaml.safe_load`, regexes חסומים | — |
123
+ | T7 | **Secrets handling** | redaction; אין סודות בלוג; `.env` (לא מקומיט) | — |
124
+ | T8 | **Fail-open** — שגיאה בליבה → tool רץ? | **fail-closed**: כל חריגה ב-check → block (נבדק בטסט) | — |
125
+
126
+ ## 7. מבנה הפרויקט
127
+
128
+ ```
129
+ sentinel/
130
+ src/sentinel/
131
+ models.py # ToolCall, Decision, AuditRecord
132
+ redaction.py # redaction של סודות
133
+ policy.py # טעינה + הכרעת YAML (default-deny, glob, comparators, rate-limit)
134
+ audit.py # AuditLog: SQLite, hash-chain, verify, export
135
+ killswitch.py # KillSwitch persisted (fail-closed)
136
+ detector.py # heuristics v1 (lethal-trifecta, off-baseline, injection sigs)
137
+ compliance.py # מיפוי Art.12 / OWASP Agentic
138
+ sentinel.py # הליבה: check() + wrap() (Interceptor)
139
+ api.py # FastAPI + dashboard
140
+ config.py
141
+ policies/example.yaml
142
+ examples/trading_agent.py # סוכן דמו (beachhead פיננסי)
143
+ tests/ # tests-first על policy/audit/kill
144
+ ```
145
+
146
+ ## 8. למה זה לא נועל אותנו
147
+
148
+ `Interceptor` הוא interface. SDK wrapper הוא מימוש אחד; הליבה (`check()`) מקבלת `ToolCall` ולא יודעת מאיפה הגיע. MCP-proxy עתידי = adapter שבונה `ToolCall` מתעבורת MCP וקורא לאותו `check()`. אפס שכתוב של policy/audit/kill.
@@ -0,0 +1,40 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 (unreleased)
4
+
5
+ MVP of the audit/flight-recorder wedge, plus first hardening pass.
6
+
7
+ ### Core
8
+ - Declarative, default-deny **policy engine** (YAML): glob + arg comparators + rate limits.
9
+ - Append-only, hash-chained **audit trail** (SQLite) with `verify` (tamper-evident) and a compliance `export`.
10
+ - **Two-phase logging**: intent (pre-exec) + outcome (post-exec) records linked by `action_id`.
11
+ - Persisted **kill switch** (global / per-agent) and `fail-closed` enforcement.
12
+ - **Detector** heuristics: full lethal-trifecta (untrusted-content tracking), off-baseline, injection signatures, dangerous-arg (cmd/SQL/path/URL), PII-in-arg.
13
+ - Secret **redaction** at write time; compliance mapping (EU AI Act Art. 12, OWASP Agentic).
14
+ - **Monitor mode** (observe-only): logs the would-be verdict, never blocks — but the kill switch still enforces. The trust bridge before flipping to enforcement.
15
+
16
+ ### Interception
17
+ - **SDK wrapper** (`@sentinel.guard`) — the default interceptor.
18
+ - **MCP proxy** (`MCPProxy`) — second interceptor over the same `enforce()` path; no bypass.
19
+ - **Sentinel-guarded MCP server** (`SentinelMCPServer`) — expose tools over real MCP with enforcement built in (optional `mcp` extra).
20
+ - **Upstream MCP proxy** (`AsyncMCPProxy`) — man-in-the-middle over a live `mcp.ClientSession` (async `aenforce`).
21
+ - **Framework-agnostic by default**: generic `policies/starter.yaml` + a generic demo (`sentinel demo`); `Sentinel.wrap_all()` guards a whole toolset; INTEGRATIONS.md covers plain functions / LangChain / OpenAI Agents / CrewAI / MCP. (Trading is now just a vertical example.)
22
+
23
+ ### Control plane
24
+ - FastAPI **dashboard** + API: live feed, integrity verify, policy editor, kill switch, approvals.
25
+ - **API auth** via `SENTINEL_API_TOKEN` on mutating endpoints; `sentinel serve` auto-generates one.
26
+ - **Read-endpoint protection** (`SENTINEL_API_PROTECT_READS`) — gate the sensitive audit reads behind the token too.
27
+ - **Human-in-the-loop approvals**: `require_approval` parks a call; operator approves; next identical call runs once.
28
+ - Persistent **rate limiter** (survives restart / shared across processes).
29
+
30
+ ### Tooling
31
+ - CLI: `serve | verify | export [--format json|otel] | kill | unkill | approvals | approve | demo`.
32
+ - **Retention**: approval TTL + `sentinel gc` purges stale approvals / rate-limit state (audit log untouched).
33
+ - **Multi-framework compliance mapping** (`sentinel compliance`): EU AI Act, GDPR, NIST AI RMF, ISO 42001, Colorado AI Act, SEC/FINRA — honest full/partial/none coverage (COMPLIANCE.md).
34
+ - **EU AI Act Art.12 report** (`export --format art12`); OpenTelemetry GenAI export (JSON spans + real SDK emission).
35
+ - **PyPI release automation** (Trusted Publishing) — see PUBLISHING.md.
36
+ - Optional extras: `pip install "sentinel[mcp,otel]"`. Clean wheel/sdist build.
37
+ - Pre-launch security: dashboard HTML-escaping (anti-XSS), disclaimers (alpha / not legal advice), concurrency-safe audit append.
38
+ - CI (GitHub Actions, py3.11–3.13) with a ruff lint gate. Concurrency-safe SQLite (WAL + busy_timeout). Apache-2.0.
39
+
40
+ 78 tests passing.
@@ -0,0 +1,90 @@
1
+ # COMPLIANCE.md — how Sentinel maps to existing AI / data law
2
+
3
+ > ⚠️ **Indicative engineering mapping — not legal advice or a conformity assessment.**
4
+ > Coverage describes what Sentinel *provides*, not whether *you* are compliant. Verify
5
+ > against the current legal texts. `sentinel compliance` is the machine-readable source
6
+ > of truth; this file mirrors it.
7
+ >
8
+ > Legend: **full** = Sentinel provides the control · **partial** = Sentinel provides
9
+ > evidence/infrastructure, you do the rest · **none** = out of scope (listed honestly).
10
+
11
+ ## Coverage at a glance
12
+
13
+ | Framework | Jurisdiction | full | partial | none |
14
+ |---|---|:--:|:--:|:--:|
15
+ | EU AI Act (2024/1689) | EU | 1 | 4 | 2 |
16
+ | GDPR (2016/679) | EU/EEA | 0 | 4 | 1 |
17
+ | NIST AI RMF 1.0 | US (voluntary) | 0 | 3 | 1 |
18
+ | ISO/IEC 42001:2023 | International | 0 | 3 | 1 |
19
+ | Colorado AI Act (SB 24-205) | US — Colorado | 0 | 3 | 1 |
20
+ | SEC 17a-4 / FINRA 4511 | US — securities | 0 | 3 | 0 |
21
+
22
+ Sentinel is an **evidence + control-plane** layer: it makes the *logging, oversight,
23
+ and audit* obligations satisfiable. It does **not** do risk classification, conformity
24
+ assessment, DPIAs, user-facing disclosure, or your organisational processes.
25
+
26
+ ## EU AI Act (Regulation 2024/1689)
27
+
28
+ | Article | Requirement (paraphrased) | Coverage | How |
29
+ |---|---|---|---|
30
+ | Art. 12 | Automatic event logs over the system lifetime | **full** | Append-only hash-chained audit; `export --format art12` |
31
+ | Art. 14 | Human oversight / stop button | partial | Kill switch + approvals; you design the oversight process |
32
+ | Art. 19 / 26(6) | Retain logs (deployers ≥ 6 months) | partial | Durable + tamper-evident; you set retention/backup |
33
+ | Art. 26 | Deployer monitoring, logs, oversight | partial | Action feed + audit + kill/approvals |
34
+ | Art. 72 | Post-market monitoring | partial | Audit + detector flags are the raw data |
35
+ | Art. 50 | Transparency to users / content marking | none | Sentinel governs actions, not disclosure |
36
+ | Art. 9 / Annex IV | Risk-management system & technical docs | none | Organisational process |
37
+
38
+ ## GDPR (2016/679)
39
+
40
+ | Article | Requirement | Coverage | How |
41
+ |---|---|---|---|
42
+ | Art. 5(1)(c) | Data minimisation | partial | Secret/PII redaction before logging; PII detector |
43
+ | Art. 22 | Human intervention in automated decisions | partial | Approvals + kill provide the checkpoint |
44
+ | Art. 30 | Records of processing | partial | Per-action audit trail |
45
+ | Art. 32 | Security of processing | partial | Token-gated plane + tamper-evident logs |
46
+ | Art. 17 | Right to erasure | none | Audit is append-only — keep PII out (redaction); erase in source systems |
47
+
48
+ ## NIST AI RMF 1.0 (+ GenAI profile)
49
+
50
+ | Function | Coverage | How |
51
+ |---|---|---|
52
+ | GOVERN | partial | Default-deny policy + immutable audit |
53
+ | MAP | none | Analytical/process activity |
54
+ | MEASURE | partial | Detector flags + action feed = continuous monitoring |
55
+ | MANAGE | partial | Kill switch + forensic audit for response/recovery |
56
+
57
+ ## ISO/IEC 42001:2023
58
+
59
+ | Control theme | Coverage | How |
60
+ |---|---|---|
61
+ | Operational controls & monitoring | partial | Runtime enforcement + live monitoring + audit |
62
+ | Event logging & records | partial | Tamper-evident audit; auditor export |
63
+ | Incident management | partial | Detector + kill + audit |
64
+ | Management-system processes (Cl. 4-10) | none | Organisational AIMS |
65
+
66
+ ## Colorado AI Act (SB 24-205, eff. 2026-06-30)
67
+
68
+ | Obligation | Coverage | How |
69
+ |---|---|---|
70
+ | Risk-management program | partial | Policy + audit are core evidence |
71
+ | Recordkeeping | partial | Per-action audit trail |
72
+ | AG notice of algorithmic discrimination (≤90 days) | partial | Detector + audit help detect/evidence; notice is yours |
73
+ | Consumer notice / right to contest | none | User-facing process |
74
+
75
+ ## SEC Rule 17a-4 / FINRA Rule 4511 (broker-dealer recordkeeping — for trading agents)
76
+
77
+ | Obligation | Coverage | How |
78
+ |---|---|---|
79
+ | Non-rewriteable records / audit-trail alternative | partial | Hash-chained tamper-evident audit; true WORM needs object-lock storage (roadmap) |
80
+ | Retention periods | partial | Durable store; configure long-term archival |
81
+ | Supervision of automated trading | partial | Action feed + kill + approvals |
82
+
83
+ ## Generate live, evidence-backed reports
84
+
85
+ ```bash
86
+ sentinel compliance --all # coverage summary (all frameworks)
87
+ sentinel compliance --framework eu_ai_act # full mapping + your audit evidence
88
+ sentinel export --format art12 # EU AI Act Art. 12 record-keeping report
89
+ ```
90
+ Set `SENTINEL_SYSTEM_NAME` and `SENTINEL_PROVIDER` to stamp reports with your system identity.
@@ -0,0 +1,30 @@
1
+ # Contributing to Sentinel
2
+
3
+ Thanks for looking! Sentinel is an early (alpha) open-source project — issues, ideas, and
4
+ PRs are all welcome.
5
+
6
+ ## Dev setup
7
+
8
+ ```bash
9
+ make install # venv + editable install with dev extras
10
+ make test # pytest
11
+ make lint # ruff
12
+ ```
13
+
14
+ ## Ground rules
15
+
16
+ - **Tests-first on security-critical code** (policy engine, audit integrity, kill switch).
17
+ Add a test with (or before) the change.
18
+ - Keep `ruff check src tests` clean and `pytest` green — CI enforces both (3.11–3.13).
19
+ - The audit log is **append-only and tamper-evident** — never add anything that mutates
20
+ past records or breaks the hash chain.
21
+ - Be honest in docs: compliance mappings are *indicative engineering aids, not legal advice*.
22
+
23
+ ## Security issues
24
+
25
+ Report privately — see [SECURITY.md](SECURITY.md). Do not open a public issue for an
26
+ unfixed vulnerability.
27
+
28
+ ## License
29
+
30
+ By contributing, you agree your contributions are licensed under Apache-2.0.
@@ -0,0 +1,85 @@
1
+ # DECISIONS.md — יומן החלטות Sentinel
2
+
3
+ פורמט: תאריך · החלטה · נימוק · סטטוס.
4
+
5
+ ---
6
+
7
+ ## 2026-06-13 · Phase 0 — מתודולוגיית המחקר
8
+ **החלטה:** מחקר תחרותי דרך 4 זרמים מקבילים (runtime security / identity+payments / standards+OSS / market+regulation), כל אחד מחזיר digest ממוקד עם מקורות אמיתיים בלבד.
9
+ **נימוק:** כיסוי רחב במהירות + הפרדה בין איסוף-מודיעין (delegated) לבין הסינתזה האסטרטגית ודירוג ה-wedge (נשאר אצלי).
10
+ **סטטוס:** ✅ הושלם → `RESEARCH.md`.
11
+
12
+ ## 2026-06-13 · ממצא מרכזי — ה-wedge המקורי תפוס
13
+ **החלטה:** לא להיכנס דרך "Runtime Control Plane / AI firewall" גנרי כ-positioning ראשי.
14
+ **נימוק:** 9 רכישות ב-12 חודשים, OSS חינמי (NeMo/Guardrails AI), bundling בענן, ו-CodeIntegrity (seed) בונה מוצר כמעט-זהה. תחרות מול חינם + מאות מיליוני $.
15
+ **סטטוס:** ✅ הוכרע במחקר.
16
+
17
+ ## 2026-06-13 · בחירת wedge — **מאושר** ✅
18
+ **החלטה:** wedge = **"compliance-grade flight recorder + kill switch"** — interception שמפיק audit trail חתום וממופה-רגולציה. **מוצר אופקי**, beachhead ראשון = סוכנים פיננסיים/מסחר אוטונומיים (MeiroX-style), ואז התרחבות.
19
+ **נימוק:** השכבה הכי פחות צפופה, מגובה ב-deadline רגולטורי (EU AI Act Art. 12 — 2.8.2026), בת-ביצוע לבנאי יחיד, וזורעת את ה-Trust Graph דרך הדאטה. ראה `RESEARCH.md` §8.
20
+ **סטטוס:** ✅ **אושר ע"י Itamar (2026-06-13).** עוברים ל-PRD.
21
+
22
+ ## 2026-06-13 · Phase 1 — PRD
23
+ **החלטה:** הפרדה חדה: PRD מגדיר *מה* (תרחישים, scope, DoD); *איך* מיירטים (proxy/SDK/middleware) נדחה במכוון ל-ARCHITECTURE (נקודת החלטה נפרדת).
24
+ **נימוק:** מנגנון ה-interception הוא ההחלטה הארכיטקטונית הכי קשה-להפוך — לא לקבע אותה ב-PRD לפני שמציגים trade-offs.
25
+ **סטטוס:** ✅ `PRD.md` נכתב.
26
+
27
+ ## 2026-06-13 · Phase 2 — Stack ו-Interception — **מאושר** ✅
28
+ **החלטה:** Python 3.11+ · interception = **SDK wrapper** מאחורי `Interceptor` interface (MCP-proxy כ-adapter עתידי) · audit = **SQLite + hash-chain** · policy = **YAML** · API = **FastAPI** + dashboard מינימלי · בדיקות = **pytest**.
29
+ **נימוק:** ה-beachhead (סוכנים פיננסיים/MeiroX) משתמש ב-tools של קריאות ישירות, לא MCP — SDK wrapper מכסה אותם, framework-agnostic, ודטרמיניסטי ל-tests-first. עקרונות: default-deny, fail-closed, append-only. ראה `ARCHITECTURE.md`.
30
+ **סטטוס:** ✅ אושר ע"י Itamar. עוברים לבנייה (Phase 3).
31
+
32
+ ## עקרונות אבטחה שנקבעו (מחייבים את כל הקוד)
33
+ - **Fail-closed:** חריגה בליבת ההכרעה → block, לא execute.
34
+ - **Default-deny:** אין כלל מתאים → block.
35
+ - **Tests-first** על policy / kill switch / audit-integrity (קוד קריטי).
36
+ - **Sentinel עצמו = משטח תקיפה** — threat model ב-`ARCHITECTURE.md` §6.
37
+
38
+ ## 2026-06-13 · Phase 3 — שינוי כפוי: HTTP layer
39
+ **החלטה:** נבדק ש-FastAPI+uvicorn+pydantic מותקנים נקי על Python 3.14.3 → נשארנו עם FastAPI כמתוכנן (לא נפלנו ל-stdlib).
40
+ **נימוק:** הסיכון היה wheels חסרים ל-3.14; אומת בפועל לפני התחייבות.
41
+ **סטטוס:** ✅
42
+
43
+ ## 2026-06-13 · Phase 4 — בדיקות, demo, אבטחה — הושלם
44
+ **החלטה:** 32 טסטים עוברים; E2E demo (5 תרחישים) עובד; tamper detection אומת חי; compliance export עובד; self-security check נקי (`SECURITY.md`).
45
+ **הערה כנה:** ה-dashboard אומת פונקציונלית (טסטים + curl חי), אבל ה-preview-MCP לא הצליח להריץ אותו כי ה-sandbox חוסם גישה ל-.venv — מגבלת סביבה, לא באג. רץ תקין תחת `sentinel serve`.
46
+ **סטטוס:** ✅ MVP הושלם.
47
+
48
+ ## 2026-06-13 · Post-MVP — הכל חוץ מחיבור MeiroX (לבקשת Itamar)
49
+ **החלטה:** Itamar בחר לבצע את כל ההמשך **חוץ** מחיבור הבוט האמיתי — "רק בנינו את זה, אני לא סומך על זה ב-100%". החלטה נכונה: לא לשים שכבת בקרה לא-בדוקה לפני כסף אמיתי. תואם [[feedback_account_anxiety]].
50
+ **בוצע ב-3 workstreams:**
51
+ - **A (הקשחה):** auth לדאשבורד (Bearer token, `SENTINEL_API_TOKEN`), rate-limit מתמשך (SQLite), two-phase logging (intent+outcome, action_id), approval flow (HITL — park→approve→run-once).
52
+ - **B (MCP-proxy):** `MCPProxy` מעל `Sentinel.enforce` משותף (refactor) — אין נתיב bypass.
53
+ - **C (OSS):** Apache-2.0, OTel GenAI export (`gen_ai.*`), CI (3.11–3.13), classifiers, CHANGELOG.
54
+ **סטטוס:** ✅ 51 טסטים עוברים. חיבור MeiroX נדחה במכוון עד שיש אמון מוכח.
55
+
56
+ ## 2026-06-13 · "תמשיך עד המטרה" — monitor mode, MCP server, OTel SDK, wheel
57
+ **החלטה:** להמשיך אוטונומית עד סגירת כל הסקופ הבר-בנייה (בלי MeiroX, בלי פרסום חיצוני שדורש הרשאות).
58
+ - **Monitor mode** (`mode="monitor"` / `SENTINEL_MODE=monitor`): observe-only — מתעד את ההכרעה-שהייתה אבל לא חוסם; ה-kill switch עדיין אוכף. גשר האמון: אפשר "shadow" על סוכן אמיתי בלי סיכון — בלי לגעת ב-MeiroX החי.
59
+ - **SentinelMCPServer**: שרת MCP אמיתי (חבילת `mcp`, optional extra) שחושף tools עם אכיפה מובנית; `handle_call` טהור ונבדק בלי תלות ב-mcp.
60
+ - **OTel SDK exporter** (`record_spans`, extra `otel`): פולט spans אמיתיים, לא רק JSON.
61
+ - **wheel + sdist** נבנו ואומתו בהתקנה ל-venv נקי → `pip install sentinel` עובד.
62
+ **סטטוס:** ✅ 58 טסטים. נשאר רק לא-קוד (design partner אמיתי) + פרסום PyPI (דורש חשבון — לא מבוצע אוטומטית).
63
+
64
+ ## 2026-06-13 · Trust hardening (תשובה ל"מה עוד נשאר")
65
+ **החלטה:** לסגור 3 פערים אמיתיים שמעלים אמינות (לא gold-plating): (1) SQLite **WAL + busy_timeout** דרך `db.py` משותף — מונע "database is locked" כשהדאשבורד קורא בזמן שסוכן כותב; (2) `SENTINEL_API_PROTECT_READS` לנעילת קריאות ה-audit הרגישות מאחורי token; (3) **ruff** lint gate ב-CI.
66
+ **הערה כנה:** בקומיט הראשון של הסבב טענתי בטעות "lint clean" — ruff מצא 5 (B008/B904). תוקן בקומיט עוקב; עכשיו נקי באמת (exit 0).
67
+ **סטטוס:** ✅ 61 טסטים, ruff נקי. **מכאן והלאה עוד קוד = תשואה פוחתת בלי משתמש אמיתי** — ההמלצה לעצור את הגולת-זהב ולתקֵף עם monitor-mode dogfood.
68
+
69
+ ## 2026-06-13 · "תעשה את שאר הדברים" (חוץ מ-MeiroX) — סבב אחרון
70
+ **החלטה:** Itamar ביקש מפורשות: לא לחבר את הבוט, אבל לבנות את כל השאר. בוצע:
71
+ - **detector חזק** — full trifecta (untrusted-content tracking), dangerous-arg (cmd/SQL/path/URL), PII.
72
+ - **Retention** — approval TTL + purge, rate-limit purge, `sentinel gc`. (ה-audit לא נמחק לעולם — רשומת compliance; מחיקה תשבור את השרשרת.)
73
+ - **Upstream MCP MITM אמיתי** — `AsyncMCPProxy` מעל `mcp.ClientSession` חי (refactor ל-`aenforce` async; ה-sync לא השתנה).
74
+ - **EU AI Act Art.12 report** רציני (`export --format art12`).
75
+ - **release ל-PyPI** (Trusted Publishing) + PUBLISHING.md — מוכן, **לא בוצע** (דורש חשבון PyPI; פעולה כלפי-חוץ).
76
+ **סטטוס:** ✅ 71 טסטים, ruff נקי. נשאר: פרסום (שלך), design partner (אנושי), MeiroX (הוחרג מפורשות).
77
+
78
+ ## 2026-06-13 · Pre-launch hardening + שכבת compliance רב-מסגרתית
79
+ **החלטה:** לפני השקה — (א) תיקון ממצאי pre-launch: XSS בדאשבורד (escaping), disclaimers (alpha/not-legal-advice ב-README + Art.12), retry על כתיבת audit מקבילית, מדיניות disclosure. (ב) "כל מה שחסר לפי החוקים ל-AI": `frameworks.py` — קטלוג של 6 רגולציות אמיתיות (EU AI Act, GDPR, NIST AI RMF, ISO 42001, Colorado AI Act, SEC/FINRA) עם מיפוי **כֵּן** full/partial/none, `sentinel compliance` CLI, ו-COMPLIANCE.md.
80
+ **כנות:** מתוך 27 חובות — רק 1 full, 20 partial, 6 none. Sentinel = שכבת evidence/control, *לא* "הופך אותך ל-compliant". הכל מסומן indicative/not-legal-advice.
81
+ **סטטוס:** ✅ 78 טסטים, ruff נקי. נשאר רק: מילוי איש קשר אבטחה, שם PyPI, push ל-CI — ואז השקה.
82
+
83
+ ## 2026-06-14 · הכללה: לכל סוכן AI, לא רק MeiroX/מסחר
84
+ **החלטה:** Itamar ביקש שזה יהיה לכל סוכן שאנשים בונים עם AI, לא רק הבוט שלו. בוצע: `policies/starter.yaml` גנרי (read/write/destructive/payments/egress/code-exec), `examples/generic_agent.py` כ-demo הראשי (`sentinel demo` מצביע עליו), `Sentinel.wrap_all()` לעטיפת toolset שלם, ו-`INTEGRATIONS.md` (plain/LangChain/OpenAI/CrewAI/LlamaIndex/MCP). default policy ב-Config שונה ל-starter.yaml; trading_agent נשאר כדוגמה vertical (מצמיד example.yaml). README/DEMO/PyPI שם = guardledger.
85
+ **סטטוס:** ✅ 79 טסטים, ruff נקי. שני ה-demos עובדים (גנרי + מסחר).
@@ -0,0 +1,90 @@
1
+ # DEMO.md — running Sentinel end-to-end
2
+
3
+ ## Setup (once)
4
+
5
+ ```bash
6
+ cd sentinel
7
+ python3 -m venv .venv && source .venv/bin/activate
8
+ pip install -e ".[dev]"
9
+ cp .env.example .env # optional; sensible defaults work without it
10
+ ```
11
+
12
+ ## 1. The end-to-end demo (the headline)
13
+
14
+ ```bash
15
+ sentinel demo # a GENERIC agent; vertical example: python examples/trading_agent.py
16
+ ```
17
+
18
+ A generic AI agent runs **through** Sentinel (the trading version shows the same controls
19
+ for a financial agent). You'll see the same scenarios either way:
20
+
21
+ | Scenario | Tool call | What Sentinel does |
22
+ |---|---|---|
23
+ | Normal trading | `get_quote`, `get_balance`, `place_order($100)` | **allowed** + logged |
24
+ | Oversized order | `place_order(TSLA, $5000)` | **blocked** — policy needs approval above $500 |
25
+ | Suspicious (trifecta) | `read_api_secret()` then `http_post(...)` | **allowed but FLAGGED** — secret-then-egress |
26
+ | Suspicious (injection) | `get_news("…ignore previous instructions…")` | **allowed but FLAGGED** — injection signature |
27
+ | Destructive | `delete_account()` | **blocked** — forbidden by policy |
28
+ | Kill switch | `get_quote()` after `kill` | **blocked** — agent stopped |
29
+
30
+ It ends by printing the audit summary and confirming the hash chain is intact.
31
+
32
+ ## 2. Prove the audit is tamper-evident
33
+
34
+ ```bash
35
+ sentinel verify # -> ok: true
36
+
37
+ # now tamper with the SQLite log directly (simulating an attacker hiding a trade)
38
+ python - <<'PY'
39
+ import sqlite3
40
+ c = sqlite3.connect("data/sentinel.db")
41
+ c.execute("UPDATE audit SET args=? WHERE seq=4", ('{"amount": 1}',))
42
+ c.commit(); c.close()
43
+ PY
44
+
45
+ sentinel verify # -> ok: false, first_bad_seq: 4 (exit code 1)
46
+ ```
47
+
48
+ This is the wedge: you cannot quietly rewrite what the agent did.
49
+
50
+ ## 3. Export a compliance report
51
+
52
+ ```bash
53
+ sentinel export --out report.json
54
+ ```
55
+
56
+ Every record carries an integrity status plus `eu_ai_act_art12` and OWASP Agentic
57
+ tags — hand it to a compliance reviewer or auditor.
58
+
59
+ ## 4. The dashboard (live control plane)
60
+
61
+ ```bash
62
+ sentinel serve # -> http://127.0.0.1:8787
63
+ ```
64
+
65
+ The dashboard polls the same audit DB, so:
66
+
67
+ - **watch** actions land live with their decision, status, flags, and matched rule;
68
+ - click **VERIFY CHAIN** to re-check integrity on demand;
69
+ - click **KILL ALL** — then in another terminal run `sentinel demo` again: the agent
70
+ is **blocked on its next call**, because the kill state is shared through SQLite.
71
+ This is a real cross-process kill switch, not a toy.
72
+ - edit the **policy** YAML and save (validated before it's written).
73
+
74
+ > Note: the live dashboard couldn't be auto-screenshotted here because the preview
75
+ > sandbox blocks the project's `.venv`; it runs fine under plain `sentinel serve`,
76
+ > and its endpoints are covered by `tests/test_api.py`.
77
+
78
+ ## 5. Measure the overhead
79
+
80
+ ```bash
81
+ python examples/benchmark.py # ~0.4 ms/call on a dev laptop (incl. 2 durable audit writes)
82
+ ```
83
+
84
+ ## 6. See the compliance mapping
85
+
86
+ ```bash
87
+ sentinel compliance --all # full/partial/none across 6 regulations
88
+ sentinel compliance --framework eu_ai_act # mapping + your audit evidence
89
+ ```
90
+