aauth 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 (66) hide show
  1. aauth-0.1.0/LICENSE +21 -0
  2. aauth-0.1.0/PKG-INFO +584 -0
  3. aauth-0.1.0/README.md +530 -0
  4. aauth-0.1.0/aauth/__init__.py +137 -0
  5. aauth-0.1.0/aauth/agent/__init__.py +2 -0
  6. aauth-0.1.0/aauth/agent/challenge_handler.py +61 -0
  7. aauth-0.1.0/aauth/agent/signer.py +78 -0
  8. aauth-0.1.0/aauth/errors.py +51 -0
  9. aauth-0.1.0/aauth/headers/__init__.py +2 -0
  10. aauth-0.1.0/aauth/headers/agent_auth.py +146 -0
  11. aauth-0.1.0/aauth/headers/signature.py +53 -0
  12. aauth-0.1.0/aauth/headers/signature_input.py +65 -0
  13. aauth-0.1.0/aauth/headers/signature_key.py +99 -0
  14. aauth-0.1.0/aauth/http/__init__.py +2 -0
  15. aauth-0.1.0/aauth/http/request.py +140 -0
  16. aauth-0.1.0/aauth/http/response.py +106 -0
  17. aauth-0.1.0/aauth/keys/__init__.py +2 -0
  18. aauth-0.1.0/aauth/keys/jwk.py +123 -0
  19. aauth-0.1.0/aauth/keys/jwks.py +191 -0
  20. aauth-0.1.0/aauth/keys/keypair.py +16 -0
  21. aauth-0.1.0/aauth/metadata/__init__.py +2 -0
  22. aauth-0.1.0/aauth/metadata/agent.py +20 -0
  23. aauth-0.1.0/aauth/metadata/auth_server.py +114 -0
  24. aauth-0.1.0/aauth/metadata/resource.py +42 -0
  25. aauth-0.1.0/aauth/resource/__init__.py +2 -0
  26. aauth-0.1.0/aauth/resource/challenge_builder.py +87 -0
  27. aauth-0.1.0/aauth/resource/token_issuer.py +74 -0
  28. aauth-0.1.0/aauth/resource/verifier.py +170 -0
  29. aauth-0.1.0/aauth/signing/__init__.py +2 -0
  30. aauth-0.1.0/aauth/signing/algorithms.py +35 -0
  31. aauth-0.1.0/aauth/signing/signature_base.py +193 -0
  32. aauth-0.1.0/aauth/signing/signer.py +138 -0
  33. aauth-0.1.0/aauth/signing/verifier.py +323 -0
  34. aauth-0.1.0/aauth/tokens/__init__.py +2 -0
  35. aauth-0.1.0/aauth/tokens/agent_token.py +202 -0
  36. aauth-0.1.0/aauth/tokens/auth_token.py +227 -0
  37. aauth-0.1.0/aauth/tokens/resource_token.py +68 -0
  38. aauth-0.1.0/aauth.egg-info/PKG-INFO +584 -0
  39. aauth-0.1.0/aauth.egg-info/SOURCES.txt +64 -0
  40. aauth-0.1.0/aauth.egg-info/dependency_links.txt +1 -0
  41. aauth-0.1.0/aauth.egg-info/requires.txt +14 -0
  42. aauth-0.1.0/aauth.egg-info/top_level.txt +1 -0
  43. aauth-0.1.0/core/__init__.py +198 -0
  44. aauth-0.1.0/core/crypto_utils.py +116 -0
  45. aauth-0.1.0/core/httpsig.py +881 -0
  46. aauth-0.1.0/core/metadata.py +161 -0
  47. aauth-0.1.0/core/tokens.py +727 -0
  48. aauth-0.1.0/flows/__init__.py +2 -0
  49. aauth-0.1.0/flows/autonomous.py +143 -0
  50. aauth-0.1.0/flows/user_delegated.py +252 -0
  51. aauth-0.1.0/participants/__init__.py +2 -0
  52. aauth-0.1.0/participants/agent.py +1275 -0
  53. aauth-0.1.0/participants/agent_delegate.py +336 -0
  54. aauth-0.1.0/participants/auth_server.py +2240 -0
  55. aauth-0.1.0/participants/resource.py +1669 -0
  56. aauth-0.1.0/participants/user_simulator.py +239 -0
  57. aauth-0.1.0/pyproject.toml +49 -0
  58. aauth-0.1.0/setup.cfg +4 -0
  59. aauth-0.1.0/tests/__init__.py +2 -0
  60. aauth-0.1.0/tests/test_phase1.py +105 -0
  61. aauth-0.1.0/tests/test_phase2.py +545 -0
  62. aauth-0.1.0/tests/test_phase3.py +361 -0
  63. aauth-0.1.0/tests/test_phase4.py +153 -0
  64. aauth-0.1.0/tests/test_phase5.py +136 -0
  65. aauth-0.1.0/tests/test_phase6.py +213 -0
  66. aauth-0.1.0/tests/test_phase7.py +421 -0
aauth-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Christian Posta
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.
aauth-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,584 @@
1
+ Metadata-Version: 2.4
2
+ Name: aauth
3
+ Version: 0.1.0
4
+ Summary: AAuth protocol implementation for Python
5
+ License: MIT License
6
+
7
+ Copyright (c) 2025 Christian Posta
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Classifier: Development Status :: 4 - Beta
28
+ Classifier: Intended Audience :: Developers
29
+ Classifier: License :: OSI Approved :: MIT License
30
+ Classifier: Programming Language :: Python :: 3
31
+ Classifier: Programming Language :: Python :: 3.9
32
+ Classifier: Programming Language :: Python :: 3.10
33
+ Classifier: Programming Language :: Python :: 3.11
34
+ Classifier: Programming Language :: Python :: 3.12
35
+ Classifier: Programming Language :: Python :: Implementation :: CPython
36
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
37
+ Requires-Python: >=3.9
38
+ Description-Content-Type: text/markdown
39
+ License-File: LICENSE
40
+ Requires-Dist: cryptography>=41.0.0
41
+ Requires-Dist: PyJWT>=2.8.0
42
+ Requires-Dist: httpx>=0.25.0
43
+ Requires-Dist: http-message-signatures>=1.0.0
44
+ Requires-Dist: http-sfv>=0.9.8
45
+ Provides-Extra: dev
46
+ Requires-Dist: pytest>=7.4.0; extra == "dev"
47
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
48
+ Requires-Dist: fastapi>=0.104.0; extra == "dev"
49
+ Requires-Dist: uvicorn>=0.24.0; extra == "dev"
50
+ Requires-Dist: pydantic>=2.0.0; extra == "dev"
51
+ Requires-Dist: python-dateutil>=2.8.0; extra == "dev"
52
+ Requires-Dist: python-multipart>=0.0.6; extra == "dev"
53
+ Dynamic: license-file
54
+
55
+ # AAuth Protocol Implementation
56
+
57
+ A Python implementation of the AAuth protocol for learning and understanding the protocol through hands-on coding.
58
+
59
+ ## Library Installation
60
+
61
+ This project includes a reusable `aauth` Python library that can be installed and used in other projects.
62
+
63
+ ### Installing in the Current Project
64
+
65
+ If you're working within this project:
66
+
67
+ ```bash
68
+ # Install in editable mode (recommended for development)
69
+ pip install -e .
70
+
71
+ # Or install normally
72
+ pip install .
73
+ ```
74
+
75
+ ### Installing in Other Projects on the Same Computer
76
+
77
+ To use this library in other projects on the same computer:
78
+
79
+ 1. **Navigate to your other project directory:**
80
+ ```bash
81
+ cd /path/to/your/other/project
82
+ ```
83
+
84
+ 2. **Activate your project's virtual environment:**
85
+ ```bash
86
+ # If using venv
87
+ source .venv/bin/activate # or venv/bin/activate
88
+
89
+ # If using conda
90
+ conda activate your-env-name
91
+ ```
92
+
93
+ 3. **Install the library in editable mode using the absolute path:**
94
+ ```bash
95
+ pip install -e /Users/christian.posta/dev/code/aauth
96
+ ```
97
+
98
+ Or if you're in a different location, use the full path to this project:
99
+ ```bash
100
+ pip install -e /full/path/to/aauth/project
101
+ ```
102
+
103
+ 4. **Verify the installation:**
104
+ ```bash
105
+ pip list | grep aauth
106
+ python -c "import aauth; print(aauth.__file__)"
107
+ ```
108
+
109
+ The `__file__` should point to the source directory, confirming editable mode.
110
+
111
+ 5. **Use the library in your code:**
112
+ ```python
113
+ import aauth
114
+
115
+ # Now you can use all the library functions
116
+ private_key, public_key = aauth.generate_ed25519_keypair()
117
+ ```
118
+
119
+ **Note:** Editable mode (`-e`) means changes to the library source code will be immediately available in your other projects without reinstalling. This is ideal for development.
120
+
121
+ Once installed, you can import and use the library:
122
+
123
+ ```python
124
+ import aauth
125
+
126
+ # Generate a key pair
127
+ private_key, public_key = aauth.generate_ed25519_keypair()
128
+
129
+ # Sign a request
130
+ signed_headers = aauth.sign_request(
131
+ method="GET",
132
+ target_uri="https://resource.example/api/data",
133
+ headers={},
134
+ body=None,
135
+ private_key=private_key
136
+ )
137
+
138
+ # Verify a signature
139
+ is_valid = aauth.verify_signature(
140
+ method="GET",
141
+ target_uri="https://resource.example/api/data",
142
+ headers=signed_headers,
143
+ body=None,
144
+ signature_input_header=signed_headers["Signature-Input"],
145
+ signature_header=signed_headers["Signature"],
146
+ signature_key_header=signed_headers["Signature-Key"]
147
+ )
148
+ ```
149
+
150
+ See the [Library Usage](#library-usage) section below for more examples.
151
+
152
+ ## Overview
153
+
154
+ This project implements the AAuth protocol incrementally, phase by phase:
155
+ - **Phase 1**: Pseudonymous flow (proof-of-possession without identity)
156
+ - **Phase 2**: Agent identity (JWKS-based identity verification)
157
+ - **Phase 3**: Autonomous authorization (full token flow)
158
+ - **Phase 4**: User delegation (OAuth-like authorization code flow)
159
+ - **Phase 5**: Agent is Resource (SSO and unified token flow)
160
+ - **Phase 6**: Agent Delegation (agent tokens for distributed instances)
161
+ - **Phase 7**: Token Exchange (multi-hop resource access with delegation chain)
162
+
163
+ ## Quick Start
164
+
165
+ ### Setup
166
+
167
+ 1. Install dependencies:
168
+ ```bash
169
+ # (Recommended) Use virtual environment
170
+ python3 -m venv .venv
171
+ source .venv/bin/activate
172
+
173
+
174
+ pip install -r requirements.txt
175
+
176
+ ```
177
+
178
+ ### Running Demos
179
+
180
+ #### Phase 1: Pseudonymous Flow
181
+
182
+ Demonstrates basic proof-of-possession without identity using `sig=hwk` scheme:
183
+
184
+ ```bash
185
+ python demo_phase1.py
186
+ ```
187
+
188
+ #### Phase 2: Agent Identity via JWKS
189
+
190
+ Demonstrates agent identity verification using `sig=jwks` scheme:
191
+
192
+ ```bash
193
+ python demo_phase2.py
194
+ ```
195
+
196
+ #### Phase 3: Autonomous Authorization
197
+
198
+ Demonstrates complete token flow without user interaction:
199
+
200
+ ```bash
201
+ python demo_phase3.py
202
+ ```
203
+
204
+ #### Phase 4: User Delegation
205
+
206
+ Demonstrates OAuth-like authorization code flow with user consent:
207
+
208
+ **Automated mode** (uses user simulator):
209
+ ```bash
210
+ python demo_phase4.py
211
+ ```
212
+
213
+ **Manual mode** (browser-based testing):
214
+ ```bash
215
+ python demo_phase4.py --manual
216
+ ```
217
+
218
+ #### Phase 5: Agent is Resource
219
+
220
+ Demonstrates agent authenticating users to itself for SSO and API access:
221
+
222
+ **Automated mode** (uses user simulator):
223
+ ```bash
224
+ python demo_phase5.py
225
+ ```
226
+
227
+ **Manual mode** (browser-based testing):
228
+ ```bash
229
+ python demo_phase5.py --manual
230
+ ```
231
+
232
+ #### Phase 6: Agent Delegation
233
+
234
+ Demonstrates agent delegation where agent servers issue agent tokens to delegates:
235
+
236
+ **Automated mode**:
237
+ ```bash
238
+ python demo_phase6.py
239
+ ```
240
+
241
+ #### Phase 7: Token Exchange
242
+
243
+ Demonstrates multi-hop resource access where a resource exchanges an upstream auth token to access a downstream resource:
244
+
245
+ **Automated mode**:
246
+ ```bash
247
+ python demo_phase7.py
248
+ ```
249
+
250
+ ## Testing
251
+
252
+ Run all tests:
253
+ ```bash
254
+ pytest tests/ -v
255
+ ```
256
+
257
+ Run tests for a specific phase:
258
+ ```bash
259
+ pytest tests/test_phase1.py -v
260
+ pytest tests/test_phase2.py -v
261
+ pytest tests/test_phase3.py -v
262
+ pytest tests/test_phase4.py -v
263
+ pytest tests/test_phase5.py -v
264
+ pytest tests/test_phase6.py -v
265
+ pytest tests/test_phase7.py -v
266
+ ```
267
+
268
+ ## Phase Overview
269
+
270
+ ### Phase 1: Pseudonymous Flow
271
+ - Agent signs requests with `sig=hwk` (public key in header)
272
+ - Resource validates signatures
273
+ - No tokens, no identity - just signature verification
274
+
275
+ See [PHASE1.md](PHASE1.md) for detailed documentation.
276
+
277
+ ### Phase 2: Agent Identity via JWKS
278
+ - Agent publishes metadata at `/.well-known/aauth-agent`
279
+ - Agent publishes JWKS at `/jwks.json`
280
+ - Resource can verify agent identity using `sig=jwks` scheme
281
+ - Separate endpoints (`/data-hwk`, `/data-jwks`) for both schemes
282
+
283
+ See [PHASE2.md](PHASE2.md) for detailed documentation.
284
+
285
+ ### Phase 3: Autonomous Authorization
286
+ - Resources issue resource tokens when agents request access
287
+ - Agents present resource tokens to auth servers
288
+ - Auth servers validate resource tokens and issue auth tokens
289
+ - Agents use auth tokens to access protected resources
290
+ - Complete token flow without user interaction
291
+
292
+ See [PHASE3.md](PHASE3.md) for detailed documentation.
293
+
294
+ ### Phase 4: User Delegation
295
+ - Auth servers issue `request_token` when user consent is required
296
+ - Agents redirect users to auth server's authorization endpoint
297
+ - Users authenticate and grant consent
298
+ - Auth server redirects back with authorization code
299
+ - Agents exchange code for auth tokens with `sub` claim
300
+
301
+ See [PHASE4.md](PHASE4.md) for detailed documentation.
302
+
303
+ ### Phase 5: Agent is Resource
304
+ - Agent requests authorization directly with `scope` (no `resource_token`)
305
+ - Agent identifier matches resource identifier (agent authenticates users to itself)
306
+ - Auth token has `aud` = agent identifier and `agent` claim omitted
307
+ - Unified token serves both SSO (user identity) and API access purposes
308
+ - Solves OIDC limitation where ID tokens and access tokens are separate
309
+
310
+ See [PHASE5.md](PHASE5.md) for detailed documentation.
311
+
312
+ ### Phase 6: Agent Delegation
313
+ - Agent servers issue agent tokens (`agent+jwt`) to agent delegates
314
+ - Delegates use `scheme=jwt` with agent tokens to sign requests
315
+ - Resources and auth servers validate agent tokens per SPEC.md Section 5.7
316
+ - Delegates share agent server's identity but use ephemeral keys
317
+ - Delegate identifier (`sub`) persists across key rotations
318
+ - Auth tokens include `agent_delegate` claim when issued to delegates
319
+
320
+ See [PHASE6.md](PHASE6.md) for detailed documentation.
321
+
322
+ ### Phase 7: Token Exchange
323
+ - Resources can act as agents to access downstream resources
324
+ - Upstream auth tokens are exchanged for downstream auth tokens
325
+ - Downstream auth server validates upstream token and federation trust
326
+ - Exchanged tokens include `act` claim showing the delegation chain
327
+ - User context (`sub`) is preserved through the chain
328
+ - Enables autonomous multi-hop resource access
329
+
330
+ See [PHASE7.md](PHASE7.md) for detailed documentation.
331
+
332
+ ## Running Individual Participants
333
+
334
+ ### Run Resource Server:
335
+ ```bash
336
+ python -m participants.resource
337
+ ```
338
+
339
+ ### Run Agent:
340
+ ```bash
341
+ python -m participants.agent
342
+ ```
343
+
344
+ ### Run Auth Server:
345
+ ```bash
346
+ python -m participants.auth_server
347
+ ```
348
+
349
+ ## Library Usage
350
+
351
+ The `aauth` library provides a framework-agnostic implementation of the AAuth protocol. Here are some common usage patterns:
352
+
353
+ ### Key Generation
354
+
355
+ ```python
356
+ import aauth
357
+
358
+ # Generate Ed25519 key pair
359
+ private_key, public_key = aauth.generate_ed25519_keypair()
360
+
361
+ # Convert to JWK format
362
+ jwk = aauth.public_key_to_jwk(public_key, kid="key-1")
363
+
364
+ # Calculate JWK thumbprint
365
+ thumbprint = aauth.calculate_jwk_thumbprint(jwk)
366
+ ```
367
+
368
+ ### HTTP Message Signing
369
+
370
+ ```python
371
+ import aauth
372
+
373
+ # Sign a request with hwk scheme (pseudonymous)
374
+ signed_headers = aauth.sign_request(
375
+ method="GET",
376
+ target_uri="https://resource.example/api/data",
377
+ headers={"Host": "resource.example"},
378
+ body=None,
379
+ private_key=private_key,
380
+ sig_scheme="hwk"
381
+ )
382
+
383
+ # Sign with jwks scheme (agent identity)
384
+ signed_headers = aauth.sign_request(
385
+ method="POST",
386
+ target_uri="https://resource.example/api/data",
387
+ headers={"Content-Type": "application/json"},
388
+ body=b'{"key": "value"}',
389
+ private_key=private_key,
390
+ sig_scheme="jwks",
391
+ id="https://agent.example",
392
+ kid="key-1"
393
+ )
394
+
395
+ # Sign with jwt scheme (using auth token)
396
+ signed_headers = aauth.sign_request(
397
+ method="GET",
398
+ target_uri="https://resource.example/api/data",
399
+ headers={},
400
+ body=None,
401
+ private_key=private_key,
402
+ sig_scheme="jwt",
403
+ jwt=auth_token
404
+ )
405
+ ```
406
+
407
+ ### Signature Verification
408
+
409
+ ```python
410
+ import aauth
411
+
412
+ # Verify a signature
413
+ is_valid = aauth.verify_signature(
414
+ method=request.method,
415
+ target_uri=str(request.url),
416
+ headers=dict(request.headers),
417
+ body=request_body,
418
+ signature_input_header=request.headers.get("Signature-Input"),
419
+ signature_header=request.headers.get("Signature"),
420
+ signature_key_header=request.headers.get("Signature-Key"),
421
+ jwks_fetcher=my_jwks_fetcher # Required for jwks/jwt schemes
422
+ )
423
+ ```
424
+
425
+ ### Token Creation and Validation
426
+
427
+ ```python
428
+ import aauth
429
+
430
+ # Create a resource token
431
+ resource_token = aauth.create_resource_token(
432
+ iss="https://resource.example",
433
+ aud="https://auth.example",
434
+ agent="https://agent.example",
435
+ agent_jkt=agent_thumbprint,
436
+ scope="data.read data.write",
437
+ private_key=resource_private_key,
438
+ kid="resource-key-1"
439
+ )
440
+
441
+ # Create an auth token
442
+ auth_token = aauth.create_auth_token(
443
+ iss="https://auth.example",
444
+ aud="https://resource.example",
445
+ agent="https://agent.example",
446
+ cnf_jwk=agent_jwk,
447
+ scope="data.read",
448
+ private_key=auth_private_key,
449
+ kid="auth-key-1"
450
+ )
451
+
452
+ # Verify an agent token
453
+ claims = aauth.verify_agent_token(
454
+ token=agent_token,
455
+ jwks_fetcher=my_jwks_fetcher,
456
+ expected_aud="https://resource.example"
457
+ )
458
+
459
+ # Parse token claims (without verification)
460
+ claims = aauth.parse_token_claims(token)
461
+ ```
462
+
463
+ ### Agent-Auth Header Parsing
464
+
465
+ ```python
466
+ import aauth
467
+
468
+ # Parse Agent-Auth challenge header
469
+ challenge = aauth.parse_agent_auth_header(
470
+ "httpsig; identity=?1; auth-token; resource_token=\"...\"; auth_server=\"https://auth.example\""
471
+ )
472
+
473
+ # Build Agent-Auth challenge
474
+ challenge_header = aauth.build_agent_auth_challenge(
475
+ require_signature=True,
476
+ require_identity=True,
477
+ require_auth_token=True,
478
+ resource_token=resource_token,
479
+ auth_server="https://auth.example"
480
+ )
481
+ ```
482
+
483
+ ### High-Level Agent and Resource APIs
484
+
485
+ ```python
486
+ import aauth
487
+
488
+ # Agent request signer
489
+ signer = aauth.AgentRequestSigner(
490
+ private_key=private_key,
491
+ agent_id="https://agent.example",
492
+ agent_token=agent_token
493
+ )
494
+
495
+ signed_headers = signer.sign_request(
496
+ method="GET",
497
+ target_uri="https://resource.example/api/data",
498
+ headers={},
499
+ body=None,
500
+ sig_scheme="jwt"
501
+ )
502
+
503
+ # Resource request verifier
504
+ verifier = aauth.RequestVerifier(
505
+ canonical_authorities=["resource.example:443"],
506
+ jwks_fetcher=my_jwks_fetcher
507
+ )
508
+
509
+ result = verifier.verify_request(
510
+ method="GET",
511
+ target_uri="https://resource.example/api/data",
512
+ headers=request_headers,
513
+ body=request_body,
514
+ require_identity=True,
515
+ require_auth_token=True
516
+ )
517
+
518
+ if result["valid"]:
519
+ print(f"Agent ID: {result['agent_id']}")
520
+ print(f"Scopes: {result['scopes']}")
521
+ ```
522
+
523
+ ### Framework Integration
524
+
525
+ The library is framework-agnostic. Here's an example for FastAPI:
526
+
527
+ ```python
528
+ from fastapi import FastAPI, Request
529
+ from aauth import RequestVerifier, AAuthRequest
530
+
531
+ app = FastAPI()
532
+ verifier = RequestVerifier(canonical_authorities=["api.example.com"])
533
+
534
+ @app.get("/protected")
535
+ async def protected_endpoint(request: Request):
536
+ # Convert FastAPI request to AAuthRequest
537
+ aauth_req = AAuthRequest.from_fastapi_request(request)
538
+
539
+ # Verify signature
540
+ result = verifier.verify_request(
541
+ method=aauth_req.method,
542
+ target_uri=str(request.url),
543
+ headers=dict(request.headers),
544
+ body=await request.body()
545
+ )
546
+
547
+ if not result["valid"]:
548
+ return {"error": result["error"]}, 401
549
+
550
+ return {"data": "protected resource", "agent": result["agent_id"]}
551
+ ```
552
+
553
+ ## Project Structure
554
+
555
+ ```
556
+ aauth/
557
+ ├── aauth/ # Main library package (installable)
558
+ │ ├── signing/ # HTTP Message Signing (RFC 9421)
559
+ │ ├── keys/ # Key management and JWK operations
560
+ │ ├── tokens/ # JWT token handling
561
+ │ ├── headers/ # HTTP header parsing/building
562
+ │ ├── metadata/ # Metadata discovery
563
+ │ ├── http/ # HTTP abstraction layer
564
+ │ ├── agent/ # Agent role implementation
565
+ │ └── resource/ # Resource role implementation
566
+ ├── core/ # Legacy core utilities (deprecated, use aauth.*)
567
+ ├── participants/ # Protocol participants (demo implementations)
568
+ ├── flows/ # Flow implementations
569
+ └── tests/ # Test suite
570
+ ```
571
+
572
+ ## Documentation
573
+
574
+ - [PHASE1.md](PHASE1.md) - Phase 1 implementation details
575
+ - [PHASE2.md](PHASE2.md) - Phase 2 implementation details
576
+ - [PHASE3.md](PHASE3.md) - Phase 3 implementation details
577
+ - [PHASE4.md](PHASE4.md) - Phase 4 implementation details
578
+ - [PHASE5.md](PHASE5.md) - Phase 5 implementation details
579
+ - [PHASE6.md](PHASE6.md) - Phase 6 implementation details
580
+ - [PHASE7.md](PHASE7.md) - Phase 7 implementation details
581
+ - [SPEC.md](SPEC.md) - AAuth protocol specification
582
+ - [PLAN.md](PLAN.md) - Overall implementation plan
583
+
584
+