swarmauth 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SwarmAuth Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,257 @@
1
+ Metadata-Version: 2.4
2
+ Name: swarmauth
3
+ Version: 0.1.0
4
+ Summary: OAuth 2.1 for autonomous AI agent swarms: signed, short-lived, capability-scoped delegation tokens.
5
+ Author: SwarmAuth Contributors
6
+ License: MIT
7
+ Keywords: ai-agents,security,authorization,multi-agent,llm,ed25519
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: cryptography>=42.0
12
+ Requires-Dist: pydantic>=2.5
13
+ Provides-Extra: dev
14
+ Requires-Dist: pytest>=8.0; extra == "dev"
15
+ Requires-Dist: fakeredis>=2.20; extra == "dev"
16
+ Provides-Extra: frameworks
17
+ Requires-Dist: langchain-core>=0.3; extra == "frameworks"
18
+ Requires-Dist: ag2>=1.0; extra == "frameworks"
19
+ Requires-Dist: mcp>=1.0; extra == "frameworks"
20
+ Provides-Extra: redis
21
+ Requires-Dist: redis>=5.0; extra == "redis"
22
+ Dynamic: license-file
23
+
24
+ # SwarmAuth
25
+
26
+ **The zero-trust authorization standard for multi-agent systems.**
27
+
28
+ SwarmAuth is OAuth 2.1 for autonomous AI swarms: cryptographically signed,
29
+ short-lived (≤300s), capability-scoped delegation tokens for agent-to-agent
30
+ and agent-to-tool calls. It's built on one assumption you should already
31
+ hold — your LLM layer *will* be compromised by prompt injection — and asks a
32
+ different question: when that happens, does the execution boundary stop the
33
+ damage, or does it just trust whatever the model decided?
34
+
35
+ Today, most multi-agent stacks pass raw API keys or unscoped bearer tokens
36
+ between agents. Read the full threat model and protocol details in
37
+ [SPEC.md](SPEC.md).
38
+
39
+ ## Why
40
+
41
+ - **Prompt injection is not a solved problem, and won't be soon.** SwarmAuth
42
+ doesn't try to detect or prevent it — it makes the LLM's decision
43
+ irrelevant at the point of execution.
44
+ - **Capability tokens, not credentials.** A token names exactly what it
45
+ authorizes (`capabilities`), against whom (`sub`), and under what limits
46
+ (`constraints`: rate limits, call caps, budget caps, parameter
47
+ allowlists) — never a raw, reusable key.
48
+ - **Tokens expire in seconds.** Max TTL is 300 seconds, enforced by every
49
+ verifier regardless of what an issuer tries to claim.
50
+ - **Zero exotic dependencies.** Ed25519 via `cryptography`, schema via
51
+ `pydantic`. That's the whole dependency tree — `KeyRegistry` needs neither,
52
+ and `RedisUsageTracker` is an opt-in extra, not baked into the core.
53
+ - **Sub-millisecond verification.** See benchmark results below.
54
+ - **Built for more than two agents.** `KeyRegistry` trusts many issuers at
55
+ once and rotates keys without a hard cutover; `RedisUsageTracker`
56
+ enforces rate/budget/call limits atomically across every verifier
57
+ process in the swarm, not just one.
58
+
59
+ ## Quickstart
60
+
61
+ ```python
62
+ import swarmauth
63
+
64
+ finance_keys = swarmauth.KeyPair.generate()
65
+
66
+ @swarmauth.guard("tool:process_payout", issuer_public_key=finance_keys.public_bytes)
67
+ def process_payout(destination_account: str, amount_usd: float):
68
+ ... # your real tool logic — only ever reached with a verified, in-scope token
69
+ ```
70
+
71
+ Issuing a token that will actually pass that check is one line:
72
+
73
+ ```python
74
+ token = swarmauth.TokenIssuer(finance_keys).issue(
75
+ iss="agent:sales-agent-01", sub="tool:process_payout",
76
+ capabilities=["tool:process_payout"], ttl_seconds=60,
77
+ )
78
+ ```
79
+
80
+ That's the entire integration surface: `@swarmauth.guard` the tool, issue the
81
+ token. Framework adapters for LangChain, CrewAI, AutoGen, and MCP tools are
82
+ one call each — see [`swarmauth/middleware.py`](swarmauth/middleware.py)
83
+ (`secure_langchain_tool`, `secure_crewai_tool`, `secure_autogen_function`,
84
+ `secure_mcp_tool`), verified against real LangChain, ag2, and MCP installs in
85
+ [`tests/test_framework_adapters.py`](tests/test_framework_adapters.py).
86
+
87
+ ## Scaling out: many issuers and many verifier processes
88
+
89
+ The examples above assume one issuer whose public key a verifier already
90
+ has in hand. A real swarm usually has many issuing agents and many verifier
91
+ processes, which needs two more pieces:
92
+
93
+ **`KeyRegistry`** — trust many issuers, and rotate an issuer's key without a
94
+ hard cutover ([SPEC.md §8](SPEC.md#8-key-registry-and-rotation)):
95
+
96
+ ```python
97
+ from swarmauth.registry import KeyRegistry
98
+
99
+ registry = KeyRegistry()
100
+ registry.register("agent:sales-agent-01", sales_keys.public_bytes)
101
+ registry.register("agent:finance-agent-01", finance_keys.public_bytes)
102
+
103
+ # Rotate sales-agent-01's key later without invalidating in-flight tokens:
104
+ registry.register("agent:sales-agent-01", new_sales_keys.public_bytes, rotate=True)
105
+ registry.revoke("agent:sales-agent-01", sales_keys.public_bytes) # once fully rolled over
106
+
107
+ @swarmauth.guard("tool:process_payout", key_registry=registry)
108
+ def process_payout(destination_account: str, amount_usd: float):
109
+ ...
110
+ ```
111
+
112
+ **`RedisUsageTracker`** — enforce `max_calls`/`max_amount_usd`/`rate_limit_per_min`
113
+ atomically across multiple verifier processes instead of per-process
114
+ ([SPEC.md §9](SPEC.md#9-distributed-usage-tracking)):
115
+
116
+ ```python
117
+ import redis
118
+ from swarmauth.backends.redis_backend import RedisUsageTracker
119
+
120
+ tracker = RedisUsageTracker(redis.Redis.from_url("redis://localhost:6379/0"))
121
+
122
+ @swarmauth.guard("tool:process_payout", key_registry=registry, tracker=tracker)
123
+ def process_payout(destination_account: str, amount_usd: float):
124
+ ...
125
+ ```
126
+
127
+ Both are optional and additive: `issuer_public_key=` and the default
128
+ in-memory `UsageTracker` still work exactly as in the quickstart above.
129
+
130
+ ## Install
131
+
132
+ ```bash
133
+ pip install -e .
134
+ # or, without an editable install:
135
+ pip install cryptography pydantic
136
+ ```
137
+
138
+ (Not yet published to PyPI — this is the MVP/open-source launch. `pip
139
+ install -e .` from a clone works today.)
140
+
141
+ For running the full test suite, including the real-framework adapter tests
142
+ and the Redis backend tests (which run against `fakeredis` by default, no
143
+ server required):
144
+
145
+ ```bash
146
+ pip install -e ".[dev,frameworks,redis]"
147
+ pytest
148
+ ```
149
+
150
+ ## Architecture
151
+
152
+ ```mermaid
153
+ sequenceDiagram
154
+ participant A as Agent A (Sales Agent)
155
+ participant I as SwarmAuth Token Issuer
156
+ participant B as Agent B / Tool (Finance Agent)
157
+
158
+ A->>I: Request capability token (iss=A, sub=B, capabilities=[...], constraints, ttl<=300s)
159
+ I->>I: Evaluate policy — is A allowed to request these capabilities against B?
160
+ I-->>A: Signed JSON Capability Token (JCT)
161
+ A->>B: Tool call, with JCT attached
162
+ B->>B: Verify Ed25519 signature, exp/iat window, audience, capability, constraints
163
+ alt Valid and in scope
164
+ B->>B: Execute tool, record usage against jti
165
+ B-->>A: Result
166
+ else Invalid, expired, wrong audience, missing capability, or over limit
167
+ B-->>A: Reject (CapabilityViolationError, ConstraintViolationError, etc)
168
+ end
169
+ ```
170
+
171
+ Full claims schema, canonicalization rules, and the complete verification
172
+ algorithm are in [SPEC.md](SPEC.md).
173
+
174
+ ## SwarmBench: does this actually stop anything?
175
+
176
+ [`benchmarks/swarmbench.py`](benchmarks/swarmbench.py) runs a runnable
177
+ simulation of a Sales Agent that delegates to a Finance Agent's
178
+ `process_payout` tool, with a prompt injection embedded in inbound customer
179
+ email instructing the Sales Agent to trigger a $50,000 payout to an
180
+ attacker-controlled account. The injection is modeled as **succeeding** at
181
+ the LLM layer in both test cases — SwarmBench isn't testing whether models
182
+ can be fooled (they can); it's testing what happens next.
183
+
184
+ ```bash
185
+ python benchmarks/swarmbench.py
186
+ ```
187
+
188
+ ### Results (from an actual run on this machine)
189
+
190
+ | Scenario | Injection succeeds at LLM layer | Unauthorized payout executed | Blocked at execution boundary |
191
+ |---|---|---|---|
192
+ | **Unprotected** agent loop | ✅ Yes | ❌ **Yes — $50,000 sent** | — |
193
+ | **SwarmAuth-protected** agent loop | ✅ Yes | ✅ **No** | ✅ Yes (`CapabilityViolationError`) |
194
+
195
+ | Metric | Value |
196
+ |---|---|
197
+ | Mean token verification overhead | **0.12 ms/op** (target: <1ms) |
198
+
199
+ In the unprotected loop, the Finance Agent's tool trusts whatever arguments
200
+ it's called with — the injection walks straight through. In the protected
201
+ loop, the token the Sales Agent actually holds only grants
202
+ `tool:draft_payout` under a policy-set budget; it does not, and cannot,
203
+ grant `tool:process_payout` no matter what the compromised LLM decided to
204
+ call — so the execution boundary rejects it before the ledger is touched.
205
+
206
+ ## Repository layout
207
+
208
+ ```
209
+ swarmauth/
210
+ ├── SPEC.md # protocol specification
211
+ ├── README.md
212
+ ├── CONTRIBUTING.md
213
+ ├── SECURITY.md
214
+ ├── .github/workflows/ci.yml # tests + benchmark + live-Redis job on every push/PR
215
+ ├── swarmauth/
216
+ │ ├── __init__.py
217
+ │ ├── crypto.py # Ed25519 keypairs, signing, verification
218
+ │ ├── token.py # CapabilityToken: issue / parse / verify
219
+ │ ├── registry.py # KeyRegistry: multi-issuer trust + key rotation
220
+ │ ├── middleware.py # guard decorator + framework adapters
221
+ │ ├── backends/
222
+ │ │ └── redis_backend.py # RedisUsageTracker (optional `redis` extra)
223
+ │ ├── exceptions.py
224
+ │ └── py.typed
225
+ ├── benchmarks/
226
+ │ └── swarmbench.py # runnable unprotected-vs-protected simulation
227
+ └── tests/
228
+ ├── test_token.py
229
+ ├── test_middleware.py
230
+ ├── test_registry.py
231
+ ├── test_redis_backend.py # runs against fakeredis, or a real server in CI
232
+ └── test_framework_adapters.py # real LangChain, ag2, and MCP integration tests
233
+ ```
234
+
235
+ ## Design principles
236
+
237
+ - No cryptographic dependencies beyond `cryptography`; no schema/validation
238
+ dependencies beyond `pydantic`.
239
+ - Strict typing, explicit exception hierarchy (`TokenExpiredError`,
240
+ `CapabilityViolationError`, `ConstraintViolationError`, ...) — callers
241
+ decide how to handle each failure mode, nothing fails silently.
242
+ - Tokens are data, not infrastructure: no required network call, no
243
+ mandatory central service. Self-issuance and centralized-issuer
244
+ deployments use the exact same token format and verification code.
245
+
246
+ ## Status
247
+
248
+ MVP / RFC. The token format, claims schema, and verification algorithm are
249
+ considered stable for `0.1.x`. Multi-issuer key rotation (`KeyRegistry`,
250
+ [SPEC.md §8](SPEC.md#8-key-registry-and-rotation)) and distributed usage
251
+ tracking (`RedisUsageTracker`, [SPEC.md §9](SPEC.md#9-distributed-usage-tracking))
252
+ now ship in the SDK; expect the framework adapters to keep evolving as more
253
+ of them get real integration use. Issues and PRs welcome.
254
+
255
+ ## License
256
+
257
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,234 @@
1
+ # SwarmAuth
2
+
3
+ **The zero-trust authorization standard for multi-agent systems.**
4
+
5
+ SwarmAuth is OAuth 2.1 for autonomous AI swarms: cryptographically signed,
6
+ short-lived (≤300s), capability-scoped delegation tokens for agent-to-agent
7
+ and agent-to-tool calls. It's built on one assumption you should already
8
+ hold — your LLM layer *will* be compromised by prompt injection — and asks a
9
+ different question: when that happens, does the execution boundary stop the
10
+ damage, or does it just trust whatever the model decided?
11
+
12
+ Today, most multi-agent stacks pass raw API keys or unscoped bearer tokens
13
+ between agents. Read the full threat model and protocol details in
14
+ [SPEC.md](SPEC.md).
15
+
16
+ ## Why
17
+
18
+ - **Prompt injection is not a solved problem, and won't be soon.** SwarmAuth
19
+ doesn't try to detect or prevent it — it makes the LLM's decision
20
+ irrelevant at the point of execution.
21
+ - **Capability tokens, not credentials.** A token names exactly what it
22
+ authorizes (`capabilities`), against whom (`sub`), and under what limits
23
+ (`constraints`: rate limits, call caps, budget caps, parameter
24
+ allowlists) — never a raw, reusable key.
25
+ - **Tokens expire in seconds.** Max TTL is 300 seconds, enforced by every
26
+ verifier regardless of what an issuer tries to claim.
27
+ - **Zero exotic dependencies.** Ed25519 via `cryptography`, schema via
28
+ `pydantic`. That's the whole dependency tree — `KeyRegistry` needs neither,
29
+ and `RedisUsageTracker` is an opt-in extra, not baked into the core.
30
+ - **Sub-millisecond verification.** See benchmark results below.
31
+ - **Built for more than two agents.** `KeyRegistry` trusts many issuers at
32
+ once and rotates keys without a hard cutover; `RedisUsageTracker`
33
+ enforces rate/budget/call limits atomically across every verifier
34
+ process in the swarm, not just one.
35
+
36
+ ## Quickstart
37
+
38
+ ```python
39
+ import swarmauth
40
+
41
+ finance_keys = swarmauth.KeyPair.generate()
42
+
43
+ @swarmauth.guard("tool:process_payout", issuer_public_key=finance_keys.public_bytes)
44
+ def process_payout(destination_account: str, amount_usd: float):
45
+ ... # your real tool logic — only ever reached with a verified, in-scope token
46
+ ```
47
+
48
+ Issuing a token that will actually pass that check is one line:
49
+
50
+ ```python
51
+ token = swarmauth.TokenIssuer(finance_keys).issue(
52
+ iss="agent:sales-agent-01", sub="tool:process_payout",
53
+ capabilities=["tool:process_payout"], ttl_seconds=60,
54
+ )
55
+ ```
56
+
57
+ That's the entire integration surface: `@swarmauth.guard` the tool, issue the
58
+ token. Framework adapters for LangChain, CrewAI, AutoGen, and MCP tools are
59
+ one call each — see [`swarmauth/middleware.py`](swarmauth/middleware.py)
60
+ (`secure_langchain_tool`, `secure_crewai_tool`, `secure_autogen_function`,
61
+ `secure_mcp_tool`), verified against real LangChain, ag2, and MCP installs in
62
+ [`tests/test_framework_adapters.py`](tests/test_framework_adapters.py).
63
+
64
+ ## Scaling out: many issuers and many verifier processes
65
+
66
+ The examples above assume one issuer whose public key a verifier already
67
+ has in hand. A real swarm usually has many issuing agents and many verifier
68
+ processes, which needs two more pieces:
69
+
70
+ **`KeyRegistry`** — trust many issuers, and rotate an issuer's key without a
71
+ hard cutover ([SPEC.md §8](SPEC.md#8-key-registry-and-rotation)):
72
+
73
+ ```python
74
+ from swarmauth.registry import KeyRegistry
75
+
76
+ registry = KeyRegistry()
77
+ registry.register("agent:sales-agent-01", sales_keys.public_bytes)
78
+ registry.register("agent:finance-agent-01", finance_keys.public_bytes)
79
+
80
+ # Rotate sales-agent-01's key later without invalidating in-flight tokens:
81
+ registry.register("agent:sales-agent-01", new_sales_keys.public_bytes, rotate=True)
82
+ registry.revoke("agent:sales-agent-01", sales_keys.public_bytes) # once fully rolled over
83
+
84
+ @swarmauth.guard("tool:process_payout", key_registry=registry)
85
+ def process_payout(destination_account: str, amount_usd: float):
86
+ ...
87
+ ```
88
+
89
+ **`RedisUsageTracker`** — enforce `max_calls`/`max_amount_usd`/`rate_limit_per_min`
90
+ atomically across multiple verifier processes instead of per-process
91
+ ([SPEC.md §9](SPEC.md#9-distributed-usage-tracking)):
92
+
93
+ ```python
94
+ import redis
95
+ from swarmauth.backends.redis_backend import RedisUsageTracker
96
+
97
+ tracker = RedisUsageTracker(redis.Redis.from_url("redis://localhost:6379/0"))
98
+
99
+ @swarmauth.guard("tool:process_payout", key_registry=registry, tracker=tracker)
100
+ def process_payout(destination_account: str, amount_usd: float):
101
+ ...
102
+ ```
103
+
104
+ Both are optional and additive: `issuer_public_key=` and the default
105
+ in-memory `UsageTracker` still work exactly as in the quickstart above.
106
+
107
+ ## Install
108
+
109
+ ```bash
110
+ pip install -e .
111
+ # or, without an editable install:
112
+ pip install cryptography pydantic
113
+ ```
114
+
115
+ (Not yet published to PyPI — this is the MVP/open-source launch. `pip
116
+ install -e .` from a clone works today.)
117
+
118
+ For running the full test suite, including the real-framework adapter tests
119
+ and the Redis backend tests (which run against `fakeredis` by default, no
120
+ server required):
121
+
122
+ ```bash
123
+ pip install -e ".[dev,frameworks,redis]"
124
+ pytest
125
+ ```
126
+
127
+ ## Architecture
128
+
129
+ ```mermaid
130
+ sequenceDiagram
131
+ participant A as Agent A (Sales Agent)
132
+ participant I as SwarmAuth Token Issuer
133
+ participant B as Agent B / Tool (Finance Agent)
134
+
135
+ A->>I: Request capability token (iss=A, sub=B, capabilities=[...], constraints, ttl<=300s)
136
+ I->>I: Evaluate policy — is A allowed to request these capabilities against B?
137
+ I-->>A: Signed JSON Capability Token (JCT)
138
+ A->>B: Tool call, with JCT attached
139
+ B->>B: Verify Ed25519 signature, exp/iat window, audience, capability, constraints
140
+ alt Valid and in scope
141
+ B->>B: Execute tool, record usage against jti
142
+ B-->>A: Result
143
+ else Invalid, expired, wrong audience, missing capability, or over limit
144
+ B-->>A: Reject (CapabilityViolationError, ConstraintViolationError, etc)
145
+ end
146
+ ```
147
+
148
+ Full claims schema, canonicalization rules, and the complete verification
149
+ algorithm are in [SPEC.md](SPEC.md).
150
+
151
+ ## SwarmBench: does this actually stop anything?
152
+
153
+ [`benchmarks/swarmbench.py`](benchmarks/swarmbench.py) runs a runnable
154
+ simulation of a Sales Agent that delegates to a Finance Agent's
155
+ `process_payout` tool, with a prompt injection embedded in inbound customer
156
+ email instructing the Sales Agent to trigger a $50,000 payout to an
157
+ attacker-controlled account. The injection is modeled as **succeeding** at
158
+ the LLM layer in both test cases — SwarmBench isn't testing whether models
159
+ can be fooled (they can); it's testing what happens next.
160
+
161
+ ```bash
162
+ python benchmarks/swarmbench.py
163
+ ```
164
+
165
+ ### Results (from an actual run on this machine)
166
+
167
+ | Scenario | Injection succeeds at LLM layer | Unauthorized payout executed | Blocked at execution boundary |
168
+ |---|---|---|---|
169
+ | **Unprotected** agent loop | ✅ Yes | ❌ **Yes — $50,000 sent** | — |
170
+ | **SwarmAuth-protected** agent loop | ✅ Yes | ✅ **No** | ✅ Yes (`CapabilityViolationError`) |
171
+
172
+ | Metric | Value |
173
+ |---|---|
174
+ | Mean token verification overhead | **0.12 ms/op** (target: <1ms) |
175
+
176
+ In the unprotected loop, the Finance Agent's tool trusts whatever arguments
177
+ it's called with — the injection walks straight through. In the protected
178
+ loop, the token the Sales Agent actually holds only grants
179
+ `tool:draft_payout` under a policy-set budget; it does not, and cannot,
180
+ grant `tool:process_payout` no matter what the compromised LLM decided to
181
+ call — so the execution boundary rejects it before the ledger is touched.
182
+
183
+ ## Repository layout
184
+
185
+ ```
186
+ swarmauth/
187
+ ├── SPEC.md # protocol specification
188
+ ├── README.md
189
+ ├── CONTRIBUTING.md
190
+ ├── SECURITY.md
191
+ ├── .github/workflows/ci.yml # tests + benchmark + live-Redis job on every push/PR
192
+ ├── swarmauth/
193
+ │ ├── __init__.py
194
+ │ ├── crypto.py # Ed25519 keypairs, signing, verification
195
+ │ ├── token.py # CapabilityToken: issue / parse / verify
196
+ │ ├── registry.py # KeyRegistry: multi-issuer trust + key rotation
197
+ │ ├── middleware.py # guard decorator + framework adapters
198
+ │ ├── backends/
199
+ │ │ └── redis_backend.py # RedisUsageTracker (optional `redis` extra)
200
+ │ ├── exceptions.py
201
+ │ └── py.typed
202
+ ├── benchmarks/
203
+ │ └── swarmbench.py # runnable unprotected-vs-protected simulation
204
+ └── tests/
205
+ ├── test_token.py
206
+ ├── test_middleware.py
207
+ ├── test_registry.py
208
+ ├── test_redis_backend.py # runs against fakeredis, or a real server in CI
209
+ └── test_framework_adapters.py # real LangChain, ag2, and MCP integration tests
210
+ ```
211
+
212
+ ## Design principles
213
+
214
+ - No cryptographic dependencies beyond `cryptography`; no schema/validation
215
+ dependencies beyond `pydantic`.
216
+ - Strict typing, explicit exception hierarchy (`TokenExpiredError`,
217
+ `CapabilityViolationError`, `ConstraintViolationError`, ...) — callers
218
+ decide how to handle each failure mode, nothing fails silently.
219
+ - Tokens are data, not infrastructure: no required network call, no
220
+ mandatory central service. Self-issuance and centralized-issuer
221
+ deployments use the exact same token format and verification code.
222
+
223
+ ## Status
224
+
225
+ MVP / RFC. The token format, claims schema, and verification algorithm are
226
+ considered stable for `0.1.x`. Multi-issuer key rotation (`KeyRegistry`,
227
+ [SPEC.md §8](SPEC.md#8-key-registry-and-rotation)) and distributed usage
228
+ tracking (`RedisUsageTracker`, [SPEC.md §9](SPEC.md#9-distributed-usage-tracking))
229
+ now ship in the SDK; expect the framework adapters to keep evolving as more
230
+ of them get real integration use. Issues and PRs welcome.
231
+
232
+ ## License
233
+
234
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,35 @@
1
+ [project]
2
+ name = "swarmauth"
3
+ version = "0.1.0"
4
+ description = "OAuth 2.1 for autonomous AI agent swarms: signed, short-lived, capability-scoped delegation tokens."
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ license = { text = "MIT" }
8
+ authors = [{ name = "SwarmAuth Contributors" }]
9
+ keywords = ["ai-agents", "security", "authorization", "multi-agent", "llm", "ed25519"]
10
+ dependencies = [
11
+ "cryptography>=42.0",
12
+ "pydantic>=2.5",
13
+ ]
14
+
15
+ [project.optional-dependencies]
16
+ dev = ["pytest>=8.0", "fakeredis>=2.20"]
17
+ # Only needed to run tests/test_framework_adapters.py against real installs;
18
+ # not required to use swarmauth itself (see swarmauth/middleware.py).
19
+ frameworks = ["langchain-core>=0.3", "ag2>=1.0", "mcp>=1.0"]
20
+ # Only needed for swarmauth.backends.redis_backend.RedisUsageTracker; the
21
+ # default swarmauth.middleware.UsageTracker (in-memory) has no such dependency.
22
+ redis = ["redis>=5.0"]
23
+
24
+ [build-system]
25
+ requires = ["setuptools>=68", "wheel"]
26
+ build-backend = "setuptools.build_meta"
27
+
28
+ [tool.setuptools.packages.find]
29
+ include = ["swarmauth*"]
30
+
31
+ [tool.setuptools.package-data]
32
+ swarmauth = ["py.typed"]
33
+
34
+ [tool.pytest.ini_options]
35
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,36 @@
1
+ """SwarmAuth: OAuth 2.1-style capability delegation for autonomous AI agent swarms."""
2
+
3
+ from swarmauth.crypto import KeyPair
4
+ from swarmauth.exceptions import (
5
+ AudienceMismatchError,
6
+ CapabilityViolationError,
7
+ ConstraintViolationError,
8
+ InvalidSignatureError,
9
+ MalformedTokenError,
10
+ SwarmAuthError,
11
+ TokenExpiredError,
12
+ TokenNotYetValidError,
13
+ )
14
+ from swarmauth.middleware import TokenIssuer, guard
15
+ from swarmauth.token import CapabilityClaims, CapabilityToken, Constraints, check_capability
16
+
17
+ __version__ = "0.1.0"
18
+
19
+ __all__ = [
20
+ "KeyPair",
21
+ "TokenIssuer",
22
+ "guard",
23
+ "CapabilityToken",
24
+ "CapabilityClaims",
25
+ "Constraints",
26
+ "check_capability",
27
+ "SwarmAuthError",
28
+ "MalformedTokenError",
29
+ "InvalidSignatureError",
30
+ "TokenExpiredError",
31
+ "TokenNotYetValidError",
32
+ "CapabilityViolationError",
33
+ "ConstraintViolationError",
34
+ "AudienceMismatchError",
35
+ "__version__",
36
+ ]
@@ -0,0 +1,8 @@
1
+ """Optional distributed backends for usage tracking.
2
+
3
+ Nothing in this package is imported by `swarmauth.middleware` at module load
4
+ time -- `UsageTracker` (in-memory) remains the zero-dependency default.
5
+ Import from `swarmauth.backends.redis_backend` directly if you need a
6
+ distributed one; it requires the optional `redis` extra
7
+ (`pip install swarmauth[redis]`).
8
+ """