capforge 0.4.0__py3-none-any.whl
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.
- capforge/__init__.py +50 -0
- capforge/_acm.py +491 -0
- capforge/_crypto.py +149 -0
- capforge/_delegation.py +83 -0
- capforge/_exceptions.py +21 -0
- capforge/_model.py +176 -0
- capforge/_policy.py +341 -0
- capforge/_validator.py +71 -0
- capforge/_version.py +3 -0
- capforge/cli/__init__.py +1 -0
- capforge/cli/main.py +347 -0
- capforge/py.typed +0 -0
- capforge-0.4.0.dist-info/METADATA +568 -0
- capforge-0.4.0.dist-info/RECORD +21 -0
- capforge-0.4.0.dist-info/WHEEL +5 -0
- capforge-0.4.0.dist-info/entry_points.txt +2 -0
- capforge-0.4.0.dist-info/licenses/LICENSE +201 -0
- capforge-0.4.0.dist-info/top_level.txt +2 -0
- capforge_langgraph/__init__.py +36 -0
- capforge_langgraph/_tool_wrapper.py +219 -0
- capforge_langgraph/pyproject.toml +35 -0
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: capforge
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Policy-as-Code SDK for AI agents with signed capability manifests and runtime authorization.
|
|
5
|
+
Author-email: Shashank R <shashank.r2005@gmail.com>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/shashank123r/capforge
|
|
8
|
+
Project-URL: Source, https://github.com/shashank123r/capforge
|
|
9
|
+
Project-URL: Specification, https://github.com/shashank123r/capforge/blob/main/SPEC.md
|
|
10
|
+
Keywords: capforge,acm,agent,capability,manifest,authorization,security,ai,trust
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Security
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: pydantic>=2.0
|
|
23
|
+
Requires-Dist: cryptography>=42.0
|
|
24
|
+
Provides-Extra: cli
|
|
25
|
+
Requires-Dist: click>=8.0; extra == "cli"
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
29
|
+
Requires-Dist: ruff>=0.5.0; extra == "dev"
|
|
30
|
+
Requires-Dist: mypy>=1.10.0; extra == "dev"
|
|
31
|
+
Requires-Dist: click>=8.0; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# CapForge
|
|
35
|
+
|
|
36
|
+
**Agent Capability Manifest (ACM) SDK — a standard for binding AI agent identity to authorized capabilities.**
|
|
37
|
+
|
|
38
|
+
[](LICENSE)
|
|
39
|
+
[](pyproject.toml)
|
|
40
|
+
[](pyproject.toml)
|
|
41
|
+
[](pyproject.toml)
|
|
42
|
+
[](.github/workflows/ci.yml)
|
|
43
|
+
|
|
44
|
+
**Version:** 0.5.0 | **Phase:** 5 (Production Showcase) ✅ | **Status:** Alpha
|
|
45
|
+
|
|
46
|
+
> CapForge is the **OAuth for AI agents** — a standard way for agents to
|
|
47
|
+
> declare who they are, what they're allowed to do, who is responsible for
|
|
48
|
+
> them, and what limits they operate within.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install capforge
|
|
52
|
+
capforge keygen --output my-key
|
|
53
|
+
capforge create --spiffe-id spiffe://org/agent/bot --sponsor user@org.com \
|
|
54
|
+
--capability knowledge_base:read --key-file my-key.pem
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from capforge import ACM, Capability, Constraints
|
|
59
|
+
|
|
60
|
+
manifest = ACM.create(
|
|
61
|
+
spiffe_id="spiffe://org/agent/bot",
|
|
62
|
+
sponsor="user@org.com",
|
|
63
|
+
capabilities=[Capability(resource="kb", action="read")],
|
|
64
|
+
)
|
|
65
|
+
manifest.sign("my-key.pem").save("manifest.json")
|
|
66
|
+
|
|
67
|
+
loaded = ACM.load("manifest.json")
|
|
68
|
+
loaded.verify(trusted_keys=["my-key.pub"])
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Why CapForge?
|
|
74
|
+
|
|
75
|
+
When an AI agent executes in production, there is no standard way to answer:
|
|
76
|
+
|
|
77
|
+
- **Who is this agent?** (identity)
|
|
78
|
+
- **What is it allowed to do?** (authorization scope)
|
|
79
|
+
- **Who is responsible for its actions?** (accountability)
|
|
80
|
+
- **What are its limits?** (constraints)
|
|
81
|
+
- **Can I verify this cryptographically?** (integrity)
|
|
82
|
+
|
|
83
|
+
Teams today solve this ad-hoc: hardcoded API keys, custom middleware, manual
|
|
84
|
+
review. This doesn't scale to multi-agent, cross-organization, or regulated
|
|
85
|
+
environments. CapForge fills this gap with the **Agent Capability Manifest
|
|
86
|
+
(ACM)** — a lightweight, verifiable authorization document format.
|
|
87
|
+
|
|
88
|
+
### Design Philosophy
|
|
89
|
+
|
|
90
|
+
- **Minimal** — Defines only what existing standards (SPIFFE, OPA, RATS, OTel)
|
|
91
|
+
do not cover.
|
|
92
|
+
- **Composable** — Composes with existing infrastructure rather than replacing it.
|
|
93
|
+
- **Verifiable** — Every ACM document is cryptographically signed via Ed25519.
|
|
94
|
+
- **Scopable** — Delegation chains can only narrow scope, never expand it.
|
|
95
|
+
- **Framework-agnostic** — Works with LangGraph, CrewAI, AutoGen, or custom agents.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Documentation
|
|
100
|
+
|
|
101
|
+
| Document | Purpose |
|
|
102
|
+
|:---------|:--------|
|
|
103
|
+
| **[SPECIFICATION.md](SPECIFICATION.md)** | ACM protocol specification v1.0 (canonical) |
|
|
104
|
+
| **[SPEC.md](SPEC.md)** | Protocol specification (alias) |
|
|
105
|
+
| **[ARCHITECTURE.md](ARCHITECTURE.md)** | Module design, data flow, design principles |
|
|
106
|
+
| **[DECISIONS.md](DECISIONS.md)** | 13 Architecture Decision Records |
|
|
107
|
+
| **[ROADMAP.md](ROADMAP.md)** | Phased milestones through standardization |
|
|
108
|
+
| **[CHANGELOG.md](CHANGELOG.md)** | Version history (v0.1.0 → v0.5.0) |
|
|
109
|
+
| **[SECURITY.md](SECURITY.md)** | Security policy and vulnerability reporting |
|
|
110
|
+
| **[CONTRIBUTING.md](CONTRIBUTING.md)** | Contribution guidelines |
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Quick Start
|
|
115
|
+
|
|
116
|
+
### 1. Install
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pip install capforge
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 2. Generate a signing key
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
capforge keygen --output ./my-agent-key
|
|
126
|
+
# -> Private key: my-agent-key.pem
|
|
127
|
+
# -> Public key: my-agent-key.pub
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 3. Create and sign an ACM document
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
capforge create \
|
|
134
|
+
--spiffe-id spiffe://acme-corp.com/agent/support-bot \
|
|
135
|
+
--sponsor alice@acme-corp.com \
|
|
136
|
+
--capability knowledge_base:read \
|
|
137
|
+
--capability tickets:read \
|
|
138
|
+
--capability tickets:write \
|
|
139
|
+
--constraint max_cost_per_session=0.05 \
|
|
140
|
+
--constraint disallowed_tools=delete_user \
|
|
141
|
+
--key-file ./my-agent-key.pem \
|
|
142
|
+
--output manifest.json
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 4. Verify the signed document
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
capforge verify manifest.json --trusted-roots my-agent-key.pub
|
|
149
|
+
# -> Verification PASSED (signature valid)
|
|
150
|
+
# -> Agent: spiffe://acme-corp.com/agent/support-bot
|
|
151
|
+
# -> Sponsor: alice@acme-corp.com
|
|
152
|
+
# -> Capabilities: 3
|
|
153
|
+
# -> Expires at: 2026-07-22T12:00:00+00:00
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 5. Delegate scope to a sub-agent
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
capforge delegate \
|
|
160
|
+
--parent manifest.json \
|
|
161
|
+
--child-spiffe-id spiffe://acme-corp.com/agent/search-worker \
|
|
162
|
+
--capability knowledge_base:read \
|
|
163
|
+
--output delegated.json
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Framework Integrations
|
|
169
|
+
|
|
170
|
+
CapForge provides tools to protect agent execution across multiple AI frameworks.
|
|
171
|
+
|
|
172
|
+
### LangGraph
|
|
173
|
+
|
|
174
|
+
Wrap LangChain tools with ACM authorization checks:
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
from capforge_langgraph import ACMControlledTool, wrap_tools
|
|
178
|
+
|
|
179
|
+
wrapped = ACMControlledTool(
|
|
180
|
+
tool=search_kb,
|
|
181
|
+
acm=acm,
|
|
182
|
+
resource="knowledge_base",
|
|
183
|
+
action="read",
|
|
184
|
+
)
|
|
185
|
+
# Every call checks ACM validity + capability
|
|
186
|
+
result = wrapped.invoke({"query": "ACM protocol"})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Full example: [`examples/langgraph/`](examples/langgraph/)
|
|
190
|
+
|
|
191
|
+
### CrewAI
|
|
192
|
+
|
|
193
|
+
Wrap CrewAI tools with ACM authorization:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from capforge import ACM
|
|
197
|
+
from examples.crewai.acm_controlled_crew import ACMControlledCrewTool
|
|
198
|
+
|
|
199
|
+
safe_tool = ACMControlledCrewTool(
|
|
200
|
+
tool=SearchKnowledgeBase(),
|
|
201
|
+
acm=acm,
|
|
202
|
+
resource="knowledge_base",
|
|
203
|
+
action="read",
|
|
204
|
+
)
|
|
205
|
+
result = safe_tool(query="ACM protocol")
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Full example: [`examples/crewai/`](examples/crewai/)
|
|
209
|
+
|
|
210
|
+
### FastAPI
|
|
211
|
+
|
|
212
|
+
Protect API endpoints with ACM dependencies:
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
from fastapi import Depends
|
|
216
|
+
from typing import Annotated
|
|
217
|
+
|
|
218
|
+
@app.get("/agents/{agent_id}")
|
|
219
|
+
async def get_agent(
|
|
220
|
+
agent_id: str,
|
|
221
|
+
acm: Annotated[ACM, Depends(require_capability("agent", "read"))],
|
|
222
|
+
):
|
|
223
|
+
return {"agent_id": agent_id, "authorized_by": acm.sponsor}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Full example: [`examples/fastapi/`](examples/fastapi/)
|
|
227
|
+
|
|
228
|
+
### OpenAI Agents SDK
|
|
229
|
+
|
|
230
|
+
Wrap function tools with ACM checks:
|
|
231
|
+
|
|
232
|
+
```python
|
|
233
|
+
class ACMControlledFunctionTool:
|
|
234
|
+
def __call__(self, *args, **kwargs):
|
|
235
|
+
if not self.acm.check(self.resource, self.action).allowed:
|
|
236
|
+
raise PermissionError("ACM denied")
|
|
237
|
+
return self.fn(*args, **kwargs)
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Full example: [`examples/openai_agents/`](examples/openai_agents/)
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Python SDK
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
from capforge import ACM, Capability, Constraints
|
|
248
|
+
from datetime import UTC, datetime, timedelta
|
|
249
|
+
|
|
250
|
+
# Create a new manifest
|
|
251
|
+
manifest = ACM.create(
|
|
252
|
+
spiffe_id="spiffe://org/agent/my-bot",
|
|
253
|
+
sponsor="dev@org.com",
|
|
254
|
+
capabilities=[Capability(resource="kb", action="read")],
|
|
255
|
+
constraints=Constraints(max_cost_per_session=0.05),
|
|
256
|
+
issuer="spiffe://org/user/dev",
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
# Sign it
|
|
260
|
+
manifest.sign("my-key.pem")
|
|
261
|
+
|
|
262
|
+
# Save to file
|
|
263
|
+
manifest.save("manifest.json")
|
|
264
|
+
|
|
265
|
+
# Load and verify
|
|
266
|
+
loaded = ACM.load("manifest.json")
|
|
267
|
+
loaded.verify(trusted_keys=["my-key.pub"])
|
|
268
|
+
print(f"Valid: {loaded.is_valid()}")
|
|
269
|
+
print(f"Agent: {loaded.spiffe_id}")
|
|
270
|
+
|
|
271
|
+
# Check capabilities
|
|
272
|
+
if loaded.has_capability("kb", "read"):
|
|
273
|
+
print("Agent can read the knowledge base")
|
|
274
|
+
|
|
275
|
+
# Delegate scope
|
|
276
|
+
child = loaded.delegate(
|
|
277
|
+
child_spiffe_id="spiffe://org/agent/sub-worker",
|
|
278
|
+
capabilities=[Capability(resource="kb", action="read")],
|
|
279
|
+
key="my-key.pem",
|
|
280
|
+
)
|
|
281
|
+
child.save("delegated.json")
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### SDK Reference
|
|
285
|
+
|
|
286
|
+
| Method | Description |
|
|
287
|
+
|:-------|:------------|
|
|
288
|
+
| `ACM.create(spiffe_id, sponsor, capabilities, ...)` | Create a new manifest |
|
|
289
|
+
| `ACM.load(source)` | Load from file or dict |
|
|
290
|
+
| `manifest.save(path)` | Save to file (returns JSON string) |
|
|
291
|
+
| `manifest.sign(key)` | Sign with Ed25519 key (PEM path or key object) |
|
|
292
|
+
| `manifest.verify(trusted_keys=...)` | Verify temporal validity + optional signature |
|
|
293
|
+
| `manifest.delegate(child_id, caps, ...)` | Create delegated manifest with narrowed scope |
|
|
294
|
+
| `manifest.check(resource, action, ...)` | Runtime authorization decision |
|
|
295
|
+
| `manifest.has_capability(resource, action)` | Check if a capability exists |
|
|
296
|
+
| `manifest.get_capability(resource, action)` | Get a capability by resource and action |
|
|
297
|
+
| `manifest.is_valid()` | Check if within temporal validity window |
|
|
298
|
+
| `manifest.to_dict()` | Export as dictionary |
|
|
299
|
+
| `manifest.to_json()` | Export as JSON string |
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## CLI Reference
|
|
304
|
+
|
|
305
|
+
| Command | Description |
|
|
306
|
+
|:--------|:------------|
|
|
307
|
+
| `capforge keygen --output <prefix>` | Generate Ed25519 key pair |
|
|
308
|
+
| `capforge create --spiffe-id --sponsor --capability ...` | Create and optionally sign an ACM |
|
|
309
|
+
| `capforge verify <file> --trusted-roots <pubkey>` | Verify ACM (temporal + crypto) |
|
|
310
|
+
| `capforge validate <file>` | Validate ACM (temporal + structural only) |
|
|
311
|
+
| `capforge info <file>` | Display human-readable ACM info |
|
|
312
|
+
| `capforge delegate --parent --child-spiffe-id --capability` | Create delegated ACM |
|
|
313
|
+
| `capforge --help` | Show help |
|
|
314
|
+
| `capforge --version` | Show version |
|
|
315
|
+
|
|
316
|
+
Full CLI workflow: [`examples/cli/`](examples/cli/)
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Runtime Policy Engine
|
|
321
|
+
|
|
322
|
+
CapForge includes a runtime authorization engine that evaluates "may this
|
|
323
|
+
action execute right now?" — not just "does this capability exist?".
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
from capforge import ACM, Capability, Constraints
|
|
327
|
+
|
|
328
|
+
manifest = ACM.create(
|
|
329
|
+
spiffe_id="spiffe://org/agent/bot",
|
|
330
|
+
sponsor="user@org.com",
|
|
331
|
+
capabilities=[Capability(resource="github", action="search")],
|
|
332
|
+
constraints=Constraints(
|
|
333
|
+
max_cost_per_session=0.50,
|
|
334
|
+
max_tokens_per_session=100_000,
|
|
335
|
+
allowed_models=["gpt-5"],
|
|
336
|
+
disallowed_tools=["delete_repo"],
|
|
337
|
+
max_execution_seconds=300,
|
|
338
|
+
),
|
|
339
|
+
ttl=3600,
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
# Authorized action
|
|
343
|
+
result = manifest.check(
|
|
344
|
+
resource="github", action="search",
|
|
345
|
+
tool="search_code", cost=0.02,
|
|
346
|
+
session_cost=0.10, session_tokens=500,
|
|
347
|
+
model="gpt-5", execution_seconds=10,
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
if result.allowed:
|
|
351
|
+
print(f"Allowed. Remaining budget: {result.remaining_budget}")
|
|
352
|
+
else:
|
|
353
|
+
print(f"Denied: {result.reason} (constraint: {result.failed_constraint})")
|
|
354
|
+
|
|
355
|
+
# Unauthorized action
|
|
356
|
+
result = manifest.check(resource="github", action="delete_repo")
|
|
357
|
+
print(result.allowed) # False
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Full example: [`examples/policy/`](examples/policy/)
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## CI/CD Integration
|
|
365
|
+
|
|
366
|
+
Verify ACM documents as a deployment gate in GitHub Actions:
|
|
367
|
+
|
|
368
|
+
```yaml
|
|
369
|
+
- name: Verify ACM signature
|
|
370
|
+
run: |
|
|
371
|
+
capforge verify manifests/agent-acm.json \
|
|
372
|
+
--trusted-roots manifests/trusted-roots.pub
|
|
373
|
+
|
|
374
|
+
- name: Check required capabilities
|
|
375
|
+
run: |
|
|
376
|
+
python -c "from capforge import ACM; m = ACM.load('manifest.json'); ...
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Full workflow: [`examples/github_actions/`](examples/github_actions/)
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Benchmarks
|
|
384
|
+
|
|
385
|
+
Core operation performance at varying manifest sizes:
|
|
386
|
+
|
|
387
|
+
| Operation | n=1 | n=10 | n=100 | n=1000 |
|
|
388
|
+
|:----------|:---:|:----:|:-----:|:------:|
|
|
389
|
+
| Manifest load | ~5 us | ~10 us | ~57 us | ~837 us |
|
|
390
|
+
| Signature verify | ~147 us | ~173 us | ~307 us | ~1838 us |
|
|
391
|
+
| ACM.check() | ~3 us | ~3 us | ~3 us | ~3 us |
|
|
392
|
+
| Delegation | ~80 us | ~81 us | ~89 us | ~160 us |
|
|
393
|
+
|
|
394
|
+
Run benchmarks: `python benchmarks/acm_benchmarks.py`
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## Features
|
|
399
|
+
|
|
400
|
+
| Feature | Status |
|
|
401
|
+
|:--------|:-------|
|
|
402
|
+
| Protocol specification (ACM v1.0) | ✅ |
|
|
403
|
+
| JSON Schema (Draft 2020-12) | ✅ |
|
|
404
|
+
| Ed25519 cryptographic signing | ✅ |
|
|
405
|
+
| Canonical JSON serialization | ✅ |
|
|
406
|
+
| Temporal validation (expiry, not-before) | ✅ |
|
|
407
|
+
| Delegation with scope narrowing | ✅ |
|
|
408
|
+
| `ACM.create()` factory | ✅ |
|
|
409
|
+
| `ACM.load()` from file or dict | ✅ |
|
|
410
|
+
| `manifest.save()` to file | ✅ |
|
|
411
|
+
| `manifest.sign()` with key or PEM path | ✅ |
|
|
412
|
+
| `manifest.verify()` temporal + crypto | ✅ |
|
|
413
|
+
| `manifest.delegate()` scope narrowing | ✅ |
|
|
414
|
+
| Capability lookup (`has_capability`, `get_capability`) | ✅ |
|
|
415
|
+
| Constraint access (`constraints_obj` property) | ✅ |
|
|
416
|
+
| Click CLI (6 commands) | ✅ |
|
|
417
|
+
| Core test suite (56 tests) | ✅ |
|
|
418
|
+
| ruff + mypy --strict | ✅ |
|
|
419
|
+
| CI pipeline (GitHub Actions) | ✅ |
|
|
420
|
+
| **LangGraph adapter** (`capforge_langgraph`) | ✅ |
|
|
421
|
+
| `ACMControlledTool` — ACM-checked tool wrapper | ✅ |
|
|
422
|
+
| `wrap_tools()` — multi-tool wrapper | ✅ |
|
|
423
|
+
| Adapter tests (10 tests) | ✅ |
|
|
424
|
+
| **Runtime policy engine** (`ACM.check()`) | ✅ |
|
|
425
|
+
| `PolicyDecision` structured result | ✅ |
|
|
426
|
+
| Cost budget evaluation | ✅ |
|
|
427
|
+
| Token budget evaluation | ✅ |
|
|
428
|
+
| Model restriction checking | ✅ |
|
|
429
|
+
| Blocked tool checking | ✅ |
|
|
430
|
+
| Execution timeout checking | ✅ |
|
|
431
|
+
| Policy tests (34 tests) | ✅ |
|
|
432
|
+
| **CrewAI example** | ✅ |
|
|
433
|
+
| **FastAPI example** | ✅ |
|
|
434
|
+
| **OpenAI Agents SDK example** | ✅ |
|
|
435
|
+
| **CLI workflow example** | ✅ |
|
|
436
|
+
| **GitHub Actions CI example** | ✅ |
|
|
437
|
+
| **Performance benchmarks** | ✅ |
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
## Project Structure
|
|
442
|
+
|
|
443
|
+
```
|
|
444
|
+
capforge/
|
|
445
|
+
├── __init__.py # Public API exports
|
|
446
|
+
├── _acm.py # ACM class (create, load, sign, verify, delegate)
|
|
447
|
+
├── _model.py # Pydantic models (Capability, Constraints)
|
|
448
|
+
├── _crypto.py # Ed25519 signing/verification
|
|
449
|
+
├── _policy.py # Runtime policy engine
|
|
450
|
+
├── _validator.py # Temporal + delegation validation
|
|
451
|
+
├── _delegation.py # Delegation scope narrowing
|
|
452
|
+
├── _exceptions.py # Exception hierarchy
|
|
453
|
+
├── _version.py # Package version
|
|
454
|
+
├── py.typed # PEP 561 type marker
|
|
455
|
+
└── cli/
|
|
456
|
+
├── __init__.py
|
|
457
|
+
└── main.py # Click CLI (6 commands)
|
|
458
|
+
|
|
459
|
+
tests/ # 100 tests total
|
|
460
|
+
├── test_acm.py # 30 tests
|
|
461
|
+
├── test_crypto.py # 14 tests
|
|
462
|
+
├── test_validator.py # 5 tests
|
|
463
|
+
├── test_model.py # 7 tests
|
|
464
|
+
├── test_policy.py # 34 tests
|
|
465
|
+
└── test_langgraph_adapter.py # 10 tests
|
|
466
|
+
|
|
467
|
+
capforge_langgraph/ # LangGraph adapter (separate package)
|
|
468
|
+
├── __init__.py
|
|
469
|
+
├── _tool_wrapper.py
|
|
470
|
+
└── pyproject.toml
|
|
471
|
+
|
|
472
|
+
examples/ # Production showcase
|
|
473
|
+
├── langgraph/ # LangGraph integration
|
|
474
|
+
│ ├── basic_acm_agent.py
|
|
475
|
+
│ ├── README.md
|
|
476
|
+
│ └── requirements.txt
|
|
477
|
+
├── crewai/ # CrewAI integration
|
|
478
|
+
│ ├── acm_controlled_crew.py
|
|
479
|
+
│ ├── README.md
|
|
480
|
+
│ └── requirements.txt
|
|
481
|
+
├── fastapi/ # FastAPI + ACM dependencies
|
|
482
|
+
│ ├── acm_protected_api.py
|
|
483
|
+
│ ├── README.md
|
|
484
|
+
│ └── requirements.txt
|
|
485
|
+
├── openai_agents/ # OpenAI Agents SDK integration
|
|
486
|
+
│ ├── acm_controlled_agent.py
|
|
487
|
+
│ ├── README.md
|
|
488
|
+
│ └── requirements.txt
|
|
489
|
+
├── cli/ # CLI workflow
|
|
490
|
+
│ ├── run_cli_examples.sh
|
|
491
|
+
│ └── README.md
|
|
492
|
+
├── github_actions/ # CI/CD verification
|
|
493
|
+
│ ├── verify_acm.yml
|
|
494
|
+
│ └── README.md
|
|
495
|
+
└── policy/ # Runtime policy engine
|
|
496
|
+
├── runtime_checks.py
|
|
497
|
+
├── README.md
|
|
498
|
+
└── requirements.txt
|
|
499
|
+
|
|
500
|
+
benchmarks/
|
|
501
|
+
├── acm_benchmarks.py # Performance benchmarks
|
|
502
|
+
└── README.md
|
|
503
|
+
|
|
504
|
+
spec/
|
|
505
|
+
├── acm-schema.json # JSON Schema (Draft 2020-12)
|
|
506
|
+
└── examples/
|
|
507
|
+
├── valid-acm.json
|
|
508
|
+
├── minimal-acm.json
|
|
509
|
+
└── expired-acm.json
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## Progress
|
|
515
|
+
|
|
516
|
+
| Area | Status |
|
|
517
|
+
|:-----|:-------|
|
|
518
|
+
| Protocol specification | ✅ 100% |
|
|
519
|
+
| JSON Schema | ✅ 100% |
|
|
520
|
+
| Pydantic data models | ✅ 100% |
|
|
521
|
+
| Ed25519 cryptography | ✅ 100% |
|
|
522
|
+
| Temporal validation | ✅ 100% |
|
|
523
|
+
| Delegation chain | ✅ 100% |
|
|
524
|
+
| Public API (`ACM.create`, `.sign`, `.verify`, etc.) | ✅ 100% |
|
|
525
|
+
| Click CLI (6 commands) | ✅ 100% |
|
|
526
|
+
| Test suite (100 tests) | ✅ 100% |
|
|
527
|
+
| ruff + mypy strict | ✅ 100% |
|
|
528
|
+
| CI pipeline | ✅ 100% |
|
|
529
|
+
| LangGraph adapter | ✅ 100% |
|
|
530
|
+
| Runtime policy engine | ✅ 100% |
|
|
531
|
+
| Framework examples (CrewAI, FastAPI, OpenAI) | ✅ 100% |
|
|
532
|
+
| CLI workflow example | ✅ 100% |
|
|
533
|
+
| GitHub Actions CI example | ✅ 100% |
|
|
534
|
+
| Performance benchmarks | ✅ 100% |
|
|
535
|
+
|
|
536
|
+
---
|
|
537
|
+
|
|
538
|
+
## Roadmap
|
|
539
|
+
|
|
540
|
+
```
|
|
541
|
+
Phase 1 ─── Foundation + Specification ✓ (v0.1.0)
|
|
542
|
+
Phase 2 ─── Cryptography + CLI Enhancement ✓ (v0.2.0)
|
|
543
|
+
Phase 3a ── CapForge SDK ✓ (v0.3.0)
|
|
544
|
+
Phase 3b ── LangGraph adapter ✓
|
|
545
|
+
Phase 4 ─── Runtime Policy Engine ✓ (v0.4.0)
|
|
546
|
+
Phase 5 ─── Production Showcase ✓ (v0.5.0) ← You are here
|
|
547
|
+
Phase 6 ─── Standardization ⬜
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
## Contributing
|
|
553
|
+
|
|
554
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
555
|
+
|
|
556
|
+
- **Report bugs:** GitHub Issues
|
|
557
|
+
- **Discuss ideas:** GitHub Discussions
|
|
558
|
+
- **Security vulnerabilities:** See [SECURITY.md](SECURITY.md)
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## License
|
|
563
|
+
|
|
564
|
+
[Apache License 2.0](LICENSE)
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
*Built for the AI agent ecosystem.*
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
capforge/__init__.py,sha256=UwlM50KqgpoknYcei-bO4vvXUUetUg1pgh6HpEZFhb4,1341
|
|
2
|
+
capforge/_acm.py,sha256=Y4ASWenMv1hZKawmQmTi0iXhCYHI6sq4iID0eN02i6U,16100
|
|
3
|
+
capforge/_crypto.py,sha256=r2tV9ccj_147GA45O0B0XCuX85eRKn13LiGqBVxOnH8,4702
|
|
4
|
+
capforge/_delegation.py,sha256=pFSdZjW38tWMT1mD7CiUUQYxpJlZFpeh43BiU40_yYg,2431
|
|
5
|
+
capforge/_exceptions.py,sha256=A14bTqC-qORjoVrp9oueJONXiHW9HEj6yVWcHOCc7EI,542
|
|
6
|
+
capforge/_model.py,sha256=lPCjhlkFCZGH0b0PvJrBOs1Iff0TrIm0smumzypQNr4,6012
|
|
7
|
+
capforge/_policy.py,sha256=mEzrz0ONHhsLGPK26yuHBCWwNhl9b19r86a79Sz4e-c,12323
|
|
8
|
+
capforge/_validator.py,sha256=Y-BcUp8L4tk3DrEcYAPLk4-KwcUgps9R0Dz1qHZpXIU,2413
|
|
9
|
+
capforge/_version.py,sha256=o5TeTLBbZaApPY9HC36gIj-DF4mpnUSxjqhaiLfBbEo,75
|
|
10
|
+
capforge/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
capforge/cli/__init__.py,sha256=HhN9_iQDWSGqaZQJvVDmSxamDoX4iGbQxrJUvbpKiH4,58
|
|
12
|
+
capforge/cli/main.py,sha256=uC8aSfd7YUGCgOwnbFYI0h_Ity65q8qzXYsvaZdJrAk,12012
|
|
13
|
+
capforge-0.4.0.dist-info/licenses/LICENSE,sha256=lEo0Pfp5z0THhoCF_kvJSR-kl5ZVsfWlLLQhIw4DX4A,11350
|
|
14
|
+
capforge_langgraph/__init__.py,sha256=6ha_PmYlRiqL140AxnUzBMjvJC_p32uj7S768Siyylk,820
|
|
15
|
+
capforge_langgraph/_tool_wrapper.py,sha256=3HNGMj_YWICcg6ASVqGDt5wqfATVgLsCYNlSkKnzqqs,6068
|
|
16
|
+
capforge_langgraph/pyproject.toml,sha256=8vyAq35WuXufIV1nQmA1tjnMz9wVF1NJKesQNta8sXs,962
|
|
17
|
+
capforge-0.4.0.dist-info/METADATA,sha256=NJcU1leCmeIyqWb0zv6oTlQOGAgiz8k9dAl7L5A-LlE,17779
|
|
18
|
+
capforge-0.4.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
19
|
+
capforge-0.4.0.dist-info/entry_points.txt,sha256=JWNfppVHyNKVV8xwEv3Hoo1VJ8ukwmVb84dKzldQRhY,51
|
|
20
|
+
capforge-0.4.0.dist-info/top_level.txt,sha256=lo1CSiIrhcs6hmG6OyOhlcjf3UKzK26fNUUBGbmQsss,28
|
|
21
|
+
capforge-0.4.0.dist-info/RECORD,,
|