autopil 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 (34) hide show
  1. autopil-0.1.0/LICENSE +66 -0
  2. autopil-0.1.0/PKG-INFO +619 -0
  3. autopil-0.1.0/README.md +506 -0
  4. autopil-0.1.0/autopil/__init__.py +5 -0
  5. autopil-0.1.0/autopil/api/__init__.py +3 -0
  6. autopil-0.1.0/autopil/api/app.py +368 -0
  7. autopil-0.1.0/autopil/api/key_store.py +11 -0
  8. autopil-0.1.0/autopil/api/schemas.py +147 -0
  9. autopil-0.1.0/autopil/api/static/index.html +799 -0
  10. autopil-0.1.0/autopil/audit_log.py +10 -0
  11. autopil-0.1.0/autopil/cli.py +79 -0
  12. autopil-0.1.0/autopil/db/__init__.py +42 -0
  13. autopil-0.1.0/autopil/db/base.py +105 -0
  14. autopil-0.1.0/autopil/db/postgres.py +479 -0
  15. autopil-0.1.0/autopil/db/sqlite.py +446 -0
  16. autopil-0.1.0/autopil/guard.py +116 -0
  17. autopil-0.1.0/autopil/models.py +46 -0
  18. autopil-0.1.0/autopil/policy_engine.py +68 -0
  19. autopil-0.1.0/autopil.egg-info/PKG-INFO +619 -0
  20. autopil-0.1.0/autopil.egg-info/SOURCES.txt +32 -0
  21. autopil-0.1.0/autopil.egg-info/dependency_links.txt +1 -0
  22. autopil-0.1.0/autopil.egg-info/entry_points.txt +2 -0
  23. autopil-0.1.0/autopil.egg-info/requires.txt +27 -0
  24. autopil-0.1.0/autopil.egg-info/top_level.txt +1 -0
  25. autopil-0.1.0/pyproject.toml +86 -0
  26. autopil-0.1.0/setup.cfg +4 -0
  27. autopil-0.1.0/tests/test_api.py +224 -0
  28. autopil-0.1.0/tests/test_audit_log.py +148 -0
  29. autopil-0.1.0/tests/test_auth.py +162 -0
  30. autopil-0.1.0/tests/test_guard.py +250 -0
  31. autopil-0.1.0/tests/test_policy_editor.py +215 -0
  32. autopil-0.1.0/tests/test_policy_engine.py +151 -0
  33. autopil-0.1.0/tests/test_postgres.py +133 -0
  34. autopil-0.1.0/tests/test_tenants.py +151 -0
autopil-0.1.0/LICENSE ADDED
@@ -0,0 +1,66 @@
1
+ Business Source License 1.1
2
+
3
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
4
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
5
+
6
+ Parameters
7
+
8
+ Licensor: Anil Solleti / VibrantCapital.ai
9
+ Licensed Work: AutoPIL 0.1.0 and later versions
10
+ The Licensed Work is (c) 2026 Anil Solleti / VibrantCapital.ai
11
+ Additional Use Grant: You may use the Licensed Work for any purpose other than
12
+ a Production Use that is a Competing Use. A "Competing Use"
13
+ means offering the Licensed Work or a substantially similar
14
+ product as a commercial managed service or SaaS product to
15
+ third parties.
16
+ Change Date: 2030-03-25
17
+ Change License: MIT License
18
+
19
+ For information about alternative licensing arrangements, contact:
20
+ anil@vibrantcapital.ai
21
+
22
+ ---
23
+
24
+ Business Source License 1.1
25
+
26
+ Terms
27
+
28
+ The Licensor hereby grants you the right to copy, modify, create derivative
29
+ works, redistribute, and make non-production use of the Licensed Work. The
30
+ Licensor may make an Additional Use Grant, above, permitting limited production
31
+ use.
32
+
33
+ Effective on the Change Date, or the fourth anniversary of the first publicly
34
+ available distribution of a specific version of the Licensed Work under this
35
+ License, whichever comes first, the Licensor hereby grants you rights under
36
+ the terms of the Change License, and the rights granted in the paragraph
37
+ above terminate.
38
+
39
+ If your use of the Licensed Work does not comply with the requirements
40
+ currently in effect as described in this License, you must purchase a
41
+ commercial license from the Licensor, its affiliated entities, or authorized
42
+ resellers, or you must refrain from using the Licensed Work.
43
+
44
+ All copies of the original and modified Licensed Work, and derivative works
45
+ of the Licensed Work, are subject to this License. This License applies
46
+ separately for each version of the Licensed Work and the Change Date may vary
47
+ for each version of the Licensed Work released by Licensor.
48
+
49
+ You must conspicuously display this License on each original or modified copy
50
+ of the Licensed Work. If you receive the Licensed Work in original or modified
51
+ form from a third party, the terms and conditions set forth in this License
52
+ apply to your use of that work.
53
+
54
+ Any use of the Licensed Work in violation of this License will automatically
55
+ terminate your rights under this License for the current and all future
56
+ versions of the Licensed Work.
57
+
58
+ This License does not grant you any right in any trademark or logo of Licensor
59
+ or its affiliates (provided that you may use a trademark or logo of Licensor
60
+ as expressly required by this License).
61
+
62
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
63
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
64
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
65
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
66
+ TITLE.
autopil-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,619 @@
1
+ Metadata-Version: 2.4
2
+ Name: autopil
3
+ Version: 0.1.0
4
+ Summary: Platform Intelligence Layer — context governance for autonomous agents
5
+ Author-email: Anil Solleti <anil@vibrantcapital.ai>
6
+ License: Business Source License 1.1
7
+
8
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
9
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
10
+
11
+ Parameters
12
+
13
+ Licensor: Anil Solleti / VibrantCapital.ai
14
+ Licensed Work: AutoPIL 0.1.0 and later versions
15
+ The Licensed Work is (c) 2026 Anil Solleti / VibrantCapital.ai
16
+ Additional Use Grant: You may use the Licensed Work for any purpose other than
17
+ a Production Use that is a Competing Use. A "Competing Use"
18
+ means offering the Licensed Work or a substantially similar
19
+ product as a commercial managed service or SaaS product to
20
+ third parties.
21
+ Change Date: 2030-03-25
22
+ Change License: MIT License
23
+
24
+ For information about alternative licensing arrangements, contact:
25
+ anil@vibrantcapital.ai
26
+
27
+ ---
28
+
29
+ Business Source License 1.1
30
+
31
+ Terms
32
+
33
+ The Licensor hereby grants you the right to copy, modify, create derivative
34
+ works, redistribute, and make non-production use of the Licensed Work. The
35
+ Licensor may make an Additional Use Grant, above, permitting limited production
36
+ use.
37
+
38
+ Effective on the Change Date, or the fourth anniversary of the first publicly
39
+ available distribution of a specific version of the Licensed Work under this
40
+ License, whichever comes first, the Licensor hereby grants you rights under
41
+ the terms of the Change License, and the rights granted in the paragraph
42
+ above terminate.
43
+
44
+ If your use of the Licensed Work does not comply with the requirements
45
+ currently in effect as described in this License, you must purchase a
46
+ commercial license from the Licensor, its affiliated entities, or authorized
47
+ resellers, or you must refrain from using the Licensed Work.
48
+
49
+ All copies of the original and modified Licensed Work, and derivative works
50
+ of the Licensed Work, are subject to this License. This License applies
51
+ separately for each version of the Licensed Work and the Change Date may vary
52
+ for each version of the Licensed Work released by Licensor.
53
+
54
+ You must conspicuously display this License on each original or modified copy
55
+ of the Licensed Work. If you receive the Licensed Work in original or modified
56
+ form from a third party, the terms and conditions set forth in this License
57
+ apply to your use of that work.
58
+
59
+ Any use of the Licensed Work in violation of this License will automatically
60
+ terminate your rights under this License for the current and all future
61
+ versions of the Licensed Work.
62
+
63
+ This License does not grant you any right in any trademark or logo of Licensor
64
+ or its affiliates (provided that you may use a trademark or logo of Licensor
65
+ as expressly required by this License).
66
+
67
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
68
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
69
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
70
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
71
+ TITLE.
72
+
73
+ Project-URL: Homepage, https://autopil.ai
74
+ Project-URL: Repository, https://github.com/anil-solleti/autopil
75
+ Project-URL: Issues, https://github.com/anil-solleti/autopil/issues
76
+ Project-URL: Changelog, https://github.com/anil-solleti/autopil/releases
77
+ Keywords: ai,agents,governance,context,policy,langgraph,langchain,audit,enterprise
78
+ Classifier: Development Status :: 3 - Alpha
79
+ Classifier: Intended Audience :: Developers
80
+ Classifier: Programming Language :: Python :: 3
81
+ Classifier: Programming Language :: Python :: 3.11
82
+ Classifier: Programming Language :: Python :: 3.12
83
+ Classifier: Operating System :: OS Independent
84
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
85
+ Classifier: Topic :: Security
86
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
87
+ Requires-Python: >=3.11
88
+ Description-Content-Type: text/markdown
89
+ License-File: LICENSE
90
+ Requires-Dist: pyyaml>=6.0
91
+ Provides-Extra: server
92
+ Requires-Dist: fastapi>=0.115; extra == "server"
93
+ Requires-Dist: uvicorn>=0.30; extra == "server"
94
+ Provides-Extra: langgraph
95
+ Requires-Dist: langgraph>=0.2; extra == "langgraph"
96
+ Requires-Dist: langchain-core>=0.3; extra == "langgraph"
97
+ Requires-Dist: langchain-community>=0.3; extra == "langgraph"
98
+ Provides-Extra: postgres
99
+ Requires-Dist: psycopg2-binary>=2.9; extra == "postgres"
100
+ Provides-Extra: all
101
+ Requires-Dist: fastapi>=0.115; extra == "all"
102
+ Requires-Dist: uvicorn>=0.30; extra == "all"
103
+ Requires-Dist: langgraph>=0.2; extra == "all"
104
+ Requires-Dist: langchain-core>=0.3; extra == "all"
105
+ Requires-Dist: langchain-community>=0.3; extra == "all"
106
+ Requires-Dist: psycopg2-binary>=2.9; extra == "all"
107
+ Provides-Extra: dev
108
+ Requires-Dist: pytest>=8.0; extra == "dev"
109
+ Requires-Dist: httpx>=0.27; extra == "dev"
110
+ Requires-Dist: fastapi>=0.115; extra == "dev"
111
+ Requires-Dist: uvicorn>=0.30; extra == "dev"
112
+ Dynamic: license-file
113
+
114
+ # AutoPIL — Platform Intelligence Layer
115
+
116
+ Context governance middleware for autonomous AI agents.
117
+
118
+ AutoPIL sits between your agents and your data sources, enforcing who can retrieve what, under what conditions — and logging every access decision with an immutable audit trail.
119
+
120
+ ```
121
+ Agent → @guard.protect(...) → Policy Engine → Data Source
122
+
123
+ Audit Log (SQLite / Postgres)
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Why AutoPIL
129
+
130
+ As enterprises deploy multi-agent AI systems, the gap that emerges isn't in the LLMs — it's in what context they're allowed to retrieve. Most governance tools operate at the output layer (content filtering, hallucination detection). AutoPIL operates at the **retrieval layer**, before sensitive data ever enters the agent's context window.
131
+
132
+ Key problems it solves:
133
+
134
+ - An underwriting agent accessing another customer's credit data
135
+ - A customer service bot retrieving internal risk models it has no business seeing
136
+ - One agent in a pipeline hijacking another agent's session context
137
+ - No audit trail of what data was retrieved and when
138
+
139
+ ---
140
+
141
+ ## Architecture
142
+
143
+ ```
144
+ ┌─────────────────────────────────────────────────────────┐
145
+ │ Your Agent │
146
+ └────────────────────────┬────────────────────────────────┘
147
+ │ @guard.protect(...)
148
+ ┌────────────────────────▼────────────────────────────────┐
149
+ │ ContextGuard │
150
+ │ 1. Cross-agent session isolation check │
151
+ │ 2. Policy evaluation (allow / deny) │
152
+ │ 3. Execute retrieval (if allowed) │
153
+ │ 4. Hash context for provenance │
154
+ │ 5. Record immutable audit event │
155
+ └──────────────┬────────────────────────┬─────────────────┘
156
+ │ │
157
+ ┌──────────────▼──────┐ ┌─────────────▼───────────────┐
158
+ │ PolicyEngine │ │ Storage Backend │
159
+ │ YAML-based rules │ │ SQLite (default) │
160
+ │ Deny by default │ │ Postgres (production) │
161
+ └─────────────────────┘ └─────────────────────────────┘
162
+ ```
163
+
164
+ **Five enforcement mechanisms:**
165
+
166
+ | Mechanism | Description |
167
+ |---|---|
168
+ | Source allowlist | Agent can only access explicitly permitted data sources |
169
+ | Source denylist | Certain sources are always blocked, regardless of allowlist |
170
+ | Sensitivity ceiling | Each role has a maximum data sensitivity level it can access |
171
+ | Cross-agent isolation | A session belongs to the first agent that used it — others are denied |
172
+ | Default deny | No matching policy = access denied |
173
+
174
+ ---
175
+
176
+ ## Quickstart
177
+
178
+ ### Install
179
+
180
+ ```bash
181
+ pip install -e .
182
+ ```
183
+
184
+ For Postgres support:
185
+
186
+ ```bash
187
+ pip install -e ".[postgres]"
188
+ ```
189
+
190
+ ### Define a policy
191
+
192
+ ```yaml
193
+ # policies/my_policy.yaml
194
+ policies:
195
+ - name: analyst_policy
196
+ agent_role: analyst
197
+ allowed_sources:
198
+ - reports
199
+ - market_data
200
+ denied_sources:
201
+ - executive_comms
202
+ max_sensitivity: high
203
+ ```
204
+
205
+ ### Wrap your retrieval functions
206
+
207
+ ```python
208
+ from autopil import ContextGuard, SensitivityLevel
209
+
210
+ guard = ContextGuard(
211
+ policy_path="policies/my_policy.yaml",
212
+ audit_db="autopil.db",
213
+ )
214
+
215
+ @guard.protect(
216
+ agent_role="analyst",
217
+ user_id="user_123",
218
+ source_id="reports",
219
+ sensitivity_level=SensitivityLevel.HIGH,
220
+ session_id="session_abc",
221
+ )
222
+ def retrieve_reports(query: str) -> list:
223
+ return vectorstore.search(query)
224
+
225
+ # Authorized — returns results
226
+ results = retrieve_reports("Q3 performance")
227
+
228
+ # Unauthorized — raises PermissionError, logs the denial
229
+ results = retrieve_reports_from_exec_comms("board notes")
230
+ ```
231
+
232
+ ### View the audit trail
233
+
234
+ ```python
235
+ events = guard.get_audit_trail("session_abc")
236
+ for e in events:
237
+ print(e.decision, e.source_id, e.context_hash)
238
+ ```
239
+
240
+ ---
241
+
242
+ ## Running the API Server
243
+
244
+ ### First start
245
+
246
+ On first start, AutoPIL creates a `default` tenant and prints a one-time superadmin API key:
247
+
248
+ ```
249
+ AutoPIL API Server
250
+ Policy : policies/financial_services.yaml
251
+ Database : sqlite @ autopil_audit.db
252
+
253
+ ⚠ First start — created 'default' tenant and superadmin key:
254
+ apl_<your-key-here>
255
+ Save this — it will not be shown again.
256
+
257
+ Docs : http://localhost:8000/docs
258
+ ```
259
+
260
+ Use this key in the `X-API-Key` header for all API requests.
261
+
262
+ ### Local
263
+
264
+ ```bash
265
+ python serve.py --policy policies/financial_services.yaml
266
+ ```
267
+
268
+ ### With Postgres
269
+
270
+ ```bash
271
+ export DATABASE_URL=postgresql://user:pass@localhost:5432/autopil
272
+ python serve.py --policy policies/financial_services.yaml
273
+ ```
274
+
275
+ ### Docker
276
+
277
+ ```bash
278
+ docker compose up --build
279
+ ```
280
+
281
+ The server starts on `http://localhost:8000`.
282
+
283
+ - **Dashboard**: http://localhost:8000
284
+ - **API docs**: http://localhost:8000/docs
285
+
286
+ ---
287
+
288
+ ## API Authentication
289
+
290
+ All `/v1/*` endpoints require an API key in the `X-API-Key` header:
291
+
292
+ ```bash
293
+ curl -H "X-API-Key: apl_yourkey" http://localhost:8000/v1/policies
294
+ ```
295
+
296
+ ### Key management
297
+
298
+ ```bash
299
+ # Create a new key (scoped to your tenant)
300
+ curl -X POST http://localhost:8000/v1/keys \
301
+ -H "X-API-Key: apl_yourkey" \
302
+ -H "Content-Type: application/json" \
303
+ -d '{"name": "production_agent"}'
304
+
305
+ # List keys for your tenant
306
+ curl http://localhost:8000/v1/keys \
307
+ -H "X-API-Key: apl_yourkey"
308
+
309
+ # Revoke a key
310
+ curl -X DELETE http://localhost:8000/v1/keys/{key_id} \
311
+ -H "X-API-Key: apl_yourkey"
312
+ ```
313
+
314
+ Keys are hashed (SHA-256) at rest. The plaintext is returned once at creation and never stored.
315
+
316
+ ---
317
+
318
+ ## Multi-Tenancy
319
+
320
+ AutoPIL supports multiple tenants with row-level data isolation. Each tenant's audit events, API keys, and stats are fully isolated.
321
+
322
+ ### Create a tenant (superadmin required)
323
+
324
+ ```bash
325
+ curl -X POST http://localhost:8000/v1/admin/tenants \
326
+ -H "X-API-Key: apl_superadminkey" \
327
+ -H "Content-Type: application/json" \
328
+ -d '{"name": "acme_corp"}'
329
+ ```
330
+
331
+ Response includes `tenant_id` and `admin_key` — the initial key for that tenant. Save it; it won't be shown again.
332
+
333
+ ### Tenant admin routes
334
+
335
+ | Method | Path | Description |
336
+ |---|---|---|
337
+ | `POST` | `/v1/admin/tenants` | Create tenant + initial admin key |
338
+ | `GET` | `/v1/admin/tenants` | List all tenants |
339
+ | `DELETE` | `/v1/admin/tenants/{id}` | Deactivate a tenant |
340
+
341
+ All admin routes require a superadmin key (`is_superadmin=true`).
342
+
343
+ ---
344
+
345
+ ## Project Structure
346
+
347
+ ```
348
+ autopil/
349
+ ├── autopil/
350
+ │ ├── __init__.py # Public API: ContextGuard, Decision, SensitivityLevel
351
+ │ ├── models.py # Dataclasses: ContextRequest, AuditEvent, enums
352
+ │ ├── policy_engine.py # YAML policy loader and evaluator
353
+ │ ├── audit_log.py # Shim → SQLiteAuditLog
354
+ │ ├── guard.py # ContextGuard decorator — core enforcement
355
+ │ ├── db/
356
+ │ │ ├── __init__.py # create_stores() factory
357
+ │ │ ├── base.py # AuditLogBase, KeyStoreBase, TenantStoreBase ABCs
358
+ │ │ ├── sqlite.py # SQLite backend (default)
359
+ │ │ └── postgres.py # Postgres backend (production)
360
+ │ └── api/
361
+ │ ├── app.py # FastAPI application factory
362
+ │ ├── key_store.py # Shim → SQLiteKeyStore
363
+ │ ├── schemas.py # Pydantic request/response models
364
+ │ └── static/
365
+ │ └── index.html # Control plane dashboard UI
366
+ ├── policies/
367
+ │ ├── financial_services.yaml # Loan underwriting roles
368
+ │ └── wealth_onboarding.yaml # 4-agent onboarding pipeline roles
369
+ ├── examples/
370
+ │ ├── langgraph_demo.py # Single agent with LangGraph
371
+ │ └── multi_agent_demo.py # Cross-agent isolation in action
372
+ ├── tests/
373
+ │ ├── conftest.py # Shared fixtures
374
+ │ ├── test_policy_engine.py # 14 policy evaluation tests
375
+ │ ├── test_audit_log.py # 14 audit persistence tests
376
+ │ ├── test_guard.py # 16 ContextGuard enforcement tests
377
+ │ ├── test_api.py # 20 REST API endpoint tests
378
+ │ ├── test_auth.py # 15 API key authentication tests
379
+ │ ├── test_tenants.py # 13 multi-tenancy and isolation tests
380
+ │ └── test_postgres.py # 11 Postgres backend tests (skipped unless DATABASE_URL set)
381
+ ├── Dockerfile
382
+ ├── docker-compose.yml
383
+ └── serve.py
384
+ ```
385
+
386
+ ---
387
+
388
+ ## Policy Reference
389
+
390
+ A policy file is a YAML document with a top-level `policies` list. Each entry maps to one agent role.
391
+
392
+ ```yaml
393
+ policies:
394
+ - name: my_policy # Unique identifier, appears in audit log
395
+ agent_role: analyst # Must match agent_role passed to guard.protect()
396
+ allowed_sources: # Empty list [] = allow all non-denied sources (admin wildcard)
397
+ - reports
398
+ - market_data
399
+ denied_sources: # Always blocked, takes priority over allowed_sources
400
+ - executive_comms
401
+ max_sensitivity: high # Ceiling: low | medium | high | restricted
402
+ ```
403
+
404
+ **Evaluation order** (first match wins):
405
+
406
+ 1. Is `source_id` in `denied_sources`? → **DENY**
407
+ 2. Is `allowed_sources` non-empty and `source_id` not in it? → **DENY**
408
+ 3. Does `sensitivity_level` exceed `max_sensitivity`? → **DENY**
409
+ 4. No issues found → **ALLOW**
410
+ 5. No policy matched for this `agent_role` → **DENY** (default deny)
411
+
412
+ ---
413
+
414
+ ## REST API Reference
415
+
416
+ Base URL: `http://localhost:8000`
417
+
418
+ All `/v1/*` routes require `X-API-Key` header. `/health` is exempt.
419
+
420
+ ### Evaluate a context request
421
+
422
+ ```
423
+ POST /v1/context/evaluate
424
+ X-API-Key: apl_yourkey
425
+ ```
426
+
427
+ ```json
428
+ {
429
+ "query": "Q3 loss rates",
430
+ "agent_role": "loan_underwriter",
431
+ "user_id": "user_001",
432
+ "source_id": "credit_scores",
433
+ "sensitivity_level": "high",
434
+ "session_id": "optional-uuid"
435
+ }
436
+ ```
437
+
438
+ Response:
439
+
440
+ ```json
441
+ {
442
+ "decision": "ALLOW",
443
+ "policy_name": "loan_underwriter_policy",
444
+ "reason": "Access granted",
445
+ "event_id": "uuid",
446
+ "session_id": "uuid",
447
+ "timestamp": "2026-03-25T06:00:00"
448
+ }
449
+ ```
450
+
451
+ ### Key management
452
+
453
+ ```
454
+ POST /v1/keys — create key (scoped to calling tenant)
455
+ GET /v1/keys — list keys for calling tenant
456
+ DELETE /v1/keys/{key_id} — revoke a key
457
+ ```
458
+
459
+ ### Tenant management (superadmin)
460
+
461
+ ```
462
+ POST /v1/admin/tenants — create tenant + initial admin key
463
+ GET /v1/admin/tenants — list all tenants
464
+ DELETE /v1/admin/tenants/{id} — deactivate tenant
465
+ ```
466
+
467
+ ### Audit
468
+
469
+ ```
470
+ GET /v1/audit/sessions/{session_id}
471
+ GET /v1/audit/events?decision=DENY&agent_role=analyst&limit=100
472
+ GET /v1/audit/stats
473
+ ```
474
+
475
+ ### Policies
476
+
477
+ ```
478
+ GET /v1/policies
479
+ POST /v1/policies/reload
480
+ ```
481
+
482
+ ---
483
+
484
+ ## Storage Backends
485
+
486
+ ### SQLite (default)
487
+
488
+ Zero configuration. Used for development and single-instance deployments.
489
+
490
+ ```bash
491
+ python serve.py --policy policies/financial_services.yaml --db /data/autopil.db
492
+ ```
493
+
494
+ ### Postgres (production)
495
+
496
+ ```bash
497
+ pip install autopil[postgres]
498
+ export DATABASE_URL=postgresql://user:pass@host:5432/autopil
499
+ python serve.py
500
+ ```
501
+
502
+ Schema is created automatically on first start. Supports horizontal scaling — multiple instances can share one Postgres database.
503
+
504
+ ### Docker Compose (Postgres)
505
+
506
+ ```bash
507
+ docker compose up --build
508
+ ```
509
+
510
+ The default `docker-compose.yml` starts AutoPIL with a `postgres:16-alpine` service wired via `DATABASE_URL`.
511
+
512
+ ---
513
+
514
+ ## Docker Reference
515
+
516
+ ### Build
517
+
518
+ ```bash
519
+ docker build -t autopil:0.1.0 .
520
+ ```
521
+
522
+ ### Run with environment overrides
523
+
524
+ ```bash
525
+ docker run -d \
526
+ -p 8000:8000 \
527
+ -v $(pwd)/policies:/app/policies:ro \
528
+ -v autopil-data:/data \
529
+ -e AUTOPIL_POLICY=/app/policies/wealth_onboarding.yaml \
530
+ autopil:0.1.0
531
+ ```
532
+
533
+ ### Environment variables
534
+
535
+ | Variable | Default | Description |
536
+ |---|---|---|
537
+ | `DATABASE_URL` | _(unset)_ | `postgresql://...` — uses Postgres if set, otherwise SQLite |
538
+ | `AUTOPIL_POLICY` | `/app/policies/financial_services.yaml` | Policy file path inside container |
539
+ | `AUTOPIL_DB` | `/data/autopil_audit.db` | SQLite audit DB path (ignored if `DATABASE_URL` is set) |
540
+ | `AUTOPIL_HOST` | `0.0.0.0` | Bind host |
541
+ | `AUTOPIL_PORT` | `8000` | Listen port |
542
+
543
+ ---
544
+
545
+ ## Running the Examples
546
+
547
+ ### LangGraph demo — loan underwriting agent
548
+
549
+ ```bash
550
+ python examples/langgraph_demo.py
551
+ ```
552
+
553
+ Runs a 3-node LangGraph pipeline that makes 4 retrieval attempts (2 allowed, 2 denied) and prints the full audit trail.
554
+
555
+ ### Multi-agent demo — cross-agent isolation
556
+
557
+ ```bash
558
+ python examples/multi_agent_demo.py
559
+ ```
560
+
561
+ Runs a 4-agent wealth onboarding pipeline (intake → KYC → risk → compliance) and demonstrates 4 isolation violations being blocked while the legitimate pipeline still reaches an APPROVED decision.
562
+
563
+ ---
564
+
565
+ ## Running the Test Suite
566
+
567
+ ```bash
568
+ pip install -e ".[dev]"
569
+ pytest tests/ -v
570
+ ```
571
+
572
+ 92 tests, all passing. Coverage:
573
+
574
+ | File | Tests | What it covers |
575
+ |---|---|---|
576
+ | `test_policy_engine.py` | 14 | Allow/deny paths, sensitivity ceiling, admin wildcard, policy reload |
577
+ | `test_audit_log.py` | 14 | Persistence, session isolation, session owner, context hash |
578
+ | `test_guard.py` | 16 | Decorator enforcement, audit creation, context hash, cross-agent isolation |
579
+ | `test_api.py` | 20 | All REST endpoints, filtering, stats, policy reload |
580
+ | `test_auth.py` | 15 | API key creation, listing, revocation, auth enforcement |
581
+ | `test_tenants.py` | 13 | Tenant lifecycle, data isolation, superadmin enforcement |
582
+
583
+ Postgres tests (11) run automatically when `DATABASE_URL` is set.
584
+
585
+ ---
586
+
587
+ ## Sensitivity Levels
588
+
589
+ Ordered from least to most sensitive:
590
+
591
+ | Level | Value | Example data |
592
+ |---|---|---|
593
+ | Low | `low` | Public product catalogs, FAQ knowledge bases |
594
+ | Medium | `medium` | Account summaries, transaction history |
595
+ | High | `high` | Credit scores, identity records, loan history |
596
+ | Restricted | `restricted` | Regulatory filings, internal risk models, audit logs |
597
+
598
+ ---
599
+
600
+ ## License
601
+
602
+ AutoPIL is licensed under the [Business Source License 1.1](LICENSE).
603
+
604
+ **What this means in practice:**
605
+
606
+ - **Free to use** for development, research, evaluation, and any non-commercial purpose
607
+ - **Free for internal production use** — deploy it inside your own organization without restriction
608
+ - **Commercial restriction** — you may not offer AutoPIL or a substantially similar product as a managed service or SaaS to third parties without a commercial license
609
+ - **Converts to MIT on March 25, 2030** — the full codebase becomes open source automatically on that date
610
+
611
+ BSL is not an OSI-approved open source license. It is a source-available license designed to allow broad community use while protecting against cloud vendors and competitors commoditizing the work before the project can sustain itself commercially.
612
+
613
+ For commercial licensing, partnership inquiries, or enterprise deployments: **anil@vibrantcapital.ai**
614
+
615
+ ---
616
+
617
+ ## Version
618
+
619
+ `0.1.0` — initial release