agentcert 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) 2025 Shaleen Chauhan
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,334 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentcert
3
+ Version: 0.1.0
4
+ Summary: Bitcoin-anchored identity certificates for AI agents
5
+ Author: Shaleen Chauhan
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/shaleenchauhan/agentcert
8
+ Project-URL: Documentation, https://github.com/shaleenchauhan/agentcert#readme
9
+ Project-URL: Repository, https://github.com/shaleenchauhan/agentcert
10
+ Project-URL: Issues, https://github.com/shaleenchauhan/agentcert/issues
11
+ Keywords: bitcoin,ai,identity,certificates,agents
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Security :: Cryptography
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: cryptography>=42.0
24
+ Requires-Dist: requests>=2.31
25
+ Requires-Dist: click>=8.1
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=7.4; extra == "dev"
28
+ Requires-Dist: pytest-cov>=4.1; extra == "dev"
29
+ Requires-Dist: responses>=0.24; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ # AgentCert
33
+
34
+ Bitcoin-anchored identity certificates for AI agents.
35
+
36
+ AgentCert is the open-source Python implementation of **AIT-1** (Agent Identity Certificates) from the Agent Internet Trust protocol. It lets developers create cryptographically signed, Bitcoin-anchored identity certificates that bind a **creator** (human or company) to an **agent** (autonomous software) — with verifiable metadata, capabilities, constraints, and a risk tier.
37
+
38
+ Every certificate is signed with ECDSA/secp256k1, hashed with SHA-256, and optionally anchored to Bitcoin via OP_RETURN. Any third party can verify the certificate using only math and the blockchain.
39
+
40
+ **Proven on Bitcoin testnet:** [`6b3b8cd6...`](https://blockstream.info/testnet/tx/6b3b8cd6624d833e98add57823a7a8ba72134a9de4aae6b7eb7617ebd7cb771c)
41
+
42
+ ## Install
43
+
44
+ ```bash
45
+ pip install agentcert
46
+ ```
47
+
48
+ Or from source:
49
+
50
+ ```bash
51
+ git clone https://github.com/shaleenchauhan/agentcert.git
52
+ cd agentcert
53
+ pip install -e ".[dev]"
54
+ ```
55
+
56
+ Requires Python 3.11+. Dependencies: `cryptography`, `requests`, `click`.
57
+
58
+ ## Quickstart
59
+
60
+ ```python
61
+ import agentcert
62
+
63
+ # Generate key pairs
64
+ creator_keys = agentcert.generate_keys()
65
+ agent_keys = agentcert.generate_keys()
66
+
67
+ # Create a signed certificate
68
+ cert = agentcert.create_certificate(
69
+ creator_keys=creator_keys,
70
+ agent_keys=agent_keys,
71
+ name="procurement-agent-v1",
72
+ platform="langchain",
73
+ model_hash="sha256:a1b2c3d4e5f6",
74
+ capabilities=["procurement", "negotiation"],
75
+ constraints=["max-transaction-50000-usd"],
76
+ risk_tier=3,
77
+ expires_days=90,
78
+ )
79
+
80
+ # Verify it
81
+ result = agentcert.verify(cert)
82
+ assert result.valid
83
+ print(result.status) # "VALID"
84
+
85
+ # Save to disk
86
+ agentcert.save_certificate(cert, "agent.cert.json")
87
+ agentcert.save_keys(creator_keys, "creator.keys.json")
88
+ ```
89
+
90
+ ## CLI
91
+
92
+ AgentCert ships a full command-line interface:
93
+
94
+ ```bash
95
+ # Generate keys
96
+ agentcert keygen -o creator.keys.json
97
+ agentcert keygen -o agent.keys.json
98
+
99
+ # Create a certificate
100
+ agentcert create \
101
+ --creator-keys creator.keys.json \
102
+ --agent-keys agent.keys.json \
103
+ --name "my-agent" \
104
+ --platform "langchain" \
105
+ --capabilities "procurement,negotiation" \
106
+ --constraints "max-50k-usd" \
107
+ --risk-tier 3 \
108
+ --expires 90d \
109
+ -o cert.json
110
+
111
+ # Inspect it
112
+ agentcert inspect cert.json
113
+
114
+ # Verify it
115
+ agentcert verify cert.json
116
+
117
+ # Update (add capabilities, new version in the chain)
118
+ agentcert update cert.json \
119
+ --creator-keys creator.keys.json \
120
+ --add-capability "invoicing" \
121
+ -o cert-v2.json
122
+
123
+ # Revoke
124
+ agentcert revoke cert-v2.json \
125
+ --creator-keys creator.keys.json \
126
+ --reason "Decommissioned" \
127
+ -o revoke.json
128
+
129
+ # Verify the full chain
130
+ agentcert verify-chain cert.json cert-v2.json revoke.json
131
+ ```
132
+
133
+ ## SDK API
134
+
135
+ All functions are available at the top level — no submodule imports needed.
136
+
137
+ ### Keys
138
+
139
+ ```python
140
+ creator_keys = agentcert.generate_keys()
141
+ agentcert.save_keys(creator_keys, "creator.keys.json")
142
+ creator_keys = agentcert.load_keys("creator.keys.json")
143
+
144
+ # Derive Bitcoin address (for funding anchor transactions)
145
+ address = agentcert.derive_bitcoin_address(creator_keys, network="testnet")
146
+ ```
147
+
148
+ ### Certificates
149
+
150
+ ```python
151
+ cert = agentcert.create_certificate(
152
+ creator_keys=creator_keys,
153
+ agent_keys=agent_keys,
154
+ name="my-agent",
155
+ platform="langchain",
156
+ model_hash="sha256:...",
157
+ capabilities=["task-a", "task-b"],
158
+ constraints=["spending-limit-1000"],
159
+ risk_tier=2,
160
+ expires_days=90,
161
+ )
162
+
163
+ agentcert.save_certificate(cert, "agent.cert.json")
164
+ cert = agentcert.load_certificate("agent.cert.json")
165
+ ```
166
+
167
+ ### Verification
168
+
169
+ The verifier runs 6 checks (all must pass for `VALID`):
170
+
171
+ 1. **cert_id integrity** — SHA-256(body) matches cert_id
172
+ 2. **creator_id derivation** — SHA-256(creator_public_key) matches creator_id
173
+ 3. **agent_id derivation** — SHA-256(agent_public_key) matches agent_id
174
+ 4. **Creator signature** — ECDSA verification against creator_public_key
175
+ 5. **Anchor integrity** — certificate hash matches the anchored hash (if receipt provided)
176
+ 6. **Expiration** — current time < expires
177
+
178
+ ```python
179
+ result = agentcert.verify(cert) # without anchor
180
+ result = agentcert.verify(cert, receipt) # with anchor receipt
181
+
182
+ print(result.status) # "VALID" or "INVALID"
183
+ print(result.valid) # True / False
184
+
185
+ for check in result.checks:
186
+ print(f"[{'PASS' if check.passed else 'FAIL'}] {check.name}: {check.detail}")
187
+ ```
188
+
189
+ ### Chain Operations
190
+
191
+ Certificates form a linked chain: create &rarr; update &rarr; ... &rarr; revoke.
192
+
193
+ ```python
194
+ # Update (carries over unchanged fields)
195
+ updated = agentcert.update_certificate(
196
+ previous_cert=cert,
197
+ creator_keys=creator_keys,
198
+ capabilities=["procurement", "negotiation", "invoicing"],
199
+ )
200
+
201
+ # Revoke (terminates the chain)
202
+ revocation = agentcert.revoke_certificate(
203
+ previous_cert=updated,
204
+ creator_keys=creator_keys,
205
+ reason="Decommissioned",
206
+ )
207
+
208
+ # Verify the full chain
209
+ chain_result = agentcert.verify_chain([cert, updated, revocation])
210
+ print(chain_result.status) # "REVOKED"
211
+ print(chain_result.valid) # True (REVOKED is a valid terminal state)
212
+ ```
213
+
214
+ ### Bitcoin Anchoring
215
+
216
+ Anchor a certificate to Bitcoin via an OP_RETURN transaction:
217
+
218
+ ```python
219
+ # The creator's Bitcoin address must be funded first
220
+ address = agentcert.derive_bitcoin_address(creator_keys, network="testnet")
221
+ print(f"Fund this address: {address}")
222
+
223
+ # Anchor (builds, signs, and broadcasts a Bitcoin transaction)
224
+ receipt = agentcert.anchor(cert, creator_keys=creator_keys, network="testnet")
225
+ print(receipt.txid)
226
+
227
+ # Save the receipt for later verification
228
+ agentcert.save_receipt(receipt, "receipt.json")
229
+ receipt = agentcert.load_receipt("receipt.json")
230
+ ```
231
+
232
+ The OP_RETURN payload is 38 bytes:
233
+
234
+ ```
235
+ [AIT\0] protocol tag (4 bytes)
236
+ [0x01] version (1 byte)
237
+ [0x02] IDENTITY_CERT (1 byte)
238
+ [...] SHA-256 hash (32 bytes)
239
+ ```
240
+
241
+ ## Certificate Structure
242
+
243
+ ```json
244
+ {
245
+ "ait_version": 1,
246
+ "cert_type": 1,
247
+ "cert_id": "<SHA-256 of body>",
248
+ "timestamp": 1739750000,
249
+ "expires": 1747526000,
250
+ "agent_public_key": "<33-byte compressed public key, hex>",
251
+ "agent_id": "<SHA-256 of agent_public_key>",
252
+ "creator_public_key": "<33-byte compressed public key, hex>",
253
+ "creator_id": "<SHA-256 of creator_public_key>",
254
+ "agent_metadata": {
255
+ "name": "my-agent",
256
+ "model_hash": "sha256:...",
257
+ "platform": "langchain",
258
+ "capabilities": ["procurement", "negotiation"],
259
+ "constraints": ["max-transaction-50000-usd"],
260
+ "risk_tier": 3
261
+ },
262
+ "previous_cert_id": null,
263
+ "creator_signature": "<ECDSA DER signature, hex>"
264
+ }
265
+ ```
266
+
267
+ | Field | Description |
268
+ |-------|-------------|
269
+ | `cert_type` | 1 = CREATION, 2 = UPDATE, 3 = REVOCATION |
270
+ | `cert_id` | SHA-256 of the certificate body (all fields except `cert_id` and `creator_signature`) |
271
+ | `creator_signature` | ECDSA/secp256k1 signature over the same body |
272
+ | `previous_cert_id` | Links to the prior certificate in the chain (null for the first) |
273
+
274
+ ## How It Works
275
+
276
+ **Signing:** The cert_id and creator_signature are computed over the same canonical JSON body. The cert_id verifies integrity (any tampering changes the hash). The signature verifies authenticity (only the creator's private key can produce it). Both are independently checkable by any third party.
277
+
278
+ **Anchoring:** The anchor hash is SHA-256 of the *complete* certificate (including cert_id and signature). This goes into a Bitcoin OP_RETURN output. If anything is modified after anchoring, the anchor check fails.
279
+
280
+ **Chain verification** checks: each cert's `previous_cert_id` links to the prior cert's `cert_id`, the same creator throughout, valid signatures on every cert, and the final cert's type determines the chain status (ACTIVE or REVOKED).
281
+
282
+ ## Development
283
+
284
+ ```bash
285
+ git clone https://github.com/shaleenchauhan/agentcert.git
286
+ cd agentcert
287
+ python3 -m venv .venv && source .venv/bin/activate
288
+ pip install -e ".[dev]"
289
+
290
+ # Run tests
291
+ pytest
292
+
293
+ # Run tests with coverage
294
+ pytest --cov=agentcert --cov-report=term-missing
295
+
296
+ # Run examples
297
+ python examples/quickstart.py
298
+ python examples/full_lifecycle.py
299
+ ```
300
+
301
+ ## Project Structure
302
+
303
+ ```
304
+ agentcert/
305
+ src/agentcert/
306
+ __init__.py # Public API (33 exports, no submodule imports needed)
307
+ keys.py # Key generation, save, load (secp256k1)
308
+ certificate.py # Certificate creation, signing, serialization
309
+ chain.py # Update, revoke, chain verification
310
+ anchor.py # Bitcoin OP_RETURN + Blockstream API
311
+ verify.py # 6-check verification with structured results
312
+ types.py # KeyPair, Certificate, AgentMetadata, etc.
313
+ exceptions.py # Custom exception hierarchy
314
+ cli.py # Click-based CLI (8 commands)
315
+ tests/ # 118 tests, 93% coverage
316
+ examples/ # quickstart.py, full_lifecycle.py
317
+ ```
318
+
319
+ ## Technical Decisions
320
+
321
+ | Component | Choice | Rationale |
322
+ |-----------|--------|-----------|
323
+ | Language | Python 3.11+ | AI/ML ecosystem standard |
324
+ | Curve | secp256k1 | Bitcoin-native, same keys for signing and anchoring |
325
+ | Signatures | ECDSA | Proven; Schnorr migration path later |
326
+ | Hashing | SHA-256 | Bitcoin-native |
327
+ | Serialization | JSON (deterministic) | `sort_keys=True, separators=(',',':')` |
328
+ | CLI | Click | Mature, clean subcommand support |
329
+ | Bitcoin API | Blockstream | No auth, free, reliable |
330
+ | Dependencies | 3 runtime | `cryptography`, `requests`, `click` |
331
+
332
+ ## License
333
+
334
+ MIT
@@ -0,0 +1,303 @@
1
+ # AgentCert
2
+
3
+ Bitcoin-anchored identity certificates for AI agents.
4
+
5
+ AgentCert is the open-source Python implementation of **AIT-1** (Agent Identity Certificates) from the Agent Internet Trust protocol. It lets developers create cryptographically signed, Bitcoin-anchored identity certificates that bind a **creator** (human or company) to an **agent** (autonomous software) — with verifiable metadata, capabilities, constraints, and a risk tier.
6
+
7
+ Every certificate is signed with ECDSA/secp256k1, hashed with SHA-256, and optionally anchored to Bitcoin via OP_RETURN. Any third party can verify the certificate using only math and the blockchain.
8
+
9
+ **Proven on Bitcoin testnet:** [`6b3b8cd6...`](https://blockstream.info/testnet/tx/6b3b8cd6624d833e98add57823a7a8ba72134a9de4aae6b7eb7617ebd7cb771c)
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pip install agentcert
15
+ ```
16
+
17
+ Or from source:
18
+
19
+ ```bash
20
+ git clone https://github.com/shaleenchauhan/agentcert.git
21
+ cd agentcert
22
+ pip install -e ".[dev]"
23
+ ```
24
+
25
+ Requires Python 3.11+. Dependencies: `cryptography`, `requests`, `click`.
26
+
27
+ ## Quickstart
28
+
29
+ ```python
30
+ import agentcert
31
+
32
+ # Generate key pairs
33
+ creator_keys = agentcert.generate_keys()
34
+ agent_keys = agentcert.generate_keys()
35
+
36
+ # Create a signed certificate
37
+ cert = agentcert.create_certificate(
38
+ creator_keys=creator_keys,
39
+ agent_keys=agent_keys,
40
+ name="procurement-agent-v1",
41
+ platform="langchain",
42
+ model_hash="sha256:a1b2c3d4e5f6",
43
+ capabilities=["procurement", "negotiation"],
44
+ constraints=["max-transaction-50000-usd"],
45
+ risk_tier=3,
46
+ expires_days=90,
47
+ )
48
+
49
+ # Verify it
50
+ result = agentcert.verify(cert)
51
+ assert result.valid
52
+ print(result.status) # "VALID"
53
+
54
+ # Save to disk
55
+ agentcert.save_certificate(cert, "agent.cert.json")
56
+ agentcert.save_keys(creator_keys, "creator.keys.json")
57
+ ```
58
+
59
+ ## CLI
60
+
61
+ AgentCert ships a full command-line interface:
62
+
63
+ ```bash
64
+ # Generate keys
65
+ agentcert keygen -o creator.keys.json
66
+ agentcert keygen -o agent.keys.json
67
+
68
+ # Create a certificate
69
+ agentcert create \
70
+ --creator-keys creator.keys.json \
71
+ --agent-keys agent.keys.json \
72
+ --name "my-agent" \
73
+ --platform "langchain" \
74
+ --capabilities "procurement,negotiation" \
75
+ --constraints "max-50k-usd" \
76
+ --risk-tier 3 \
77
+ --expires 90d \
78
+ -o cert.json
79
+
80
+ # Inspect it
81
+ agentcert inspect cert.json
82
+
83
+ # Verify it
84
+ agentcert verify cert.json
85
+
86
+ # Update (add capabilities, new version in the chain)
87
+ agentcert update cert.json \
88
+ --creator-keys creator.keys.json \
89
+ --add-capability "invoicing" \
90
+ -o cert-v2.json
91
+
92
+ # Revoke
93
+ agentcert revoke cert-v2.json \
94
+ --creator-keys creator.keys.json \
95
+ --reason "Decommissioned" \
96
+ -o revoke.json
97
+
98
+ # Verify the full chain
99
+ agentcert verify-chain cert.json cert-v2.json revoke.json
100
+ ```
101
+
102
+ ## SDK API
103
+
104
+ All functions are available at the top level — no submodule imports needed.
105
+
106
+ ### Keys
107
+
108
+ ```python
109
+ creator_keys = agentcert.generate_keys()
110
+ agentcert.save_keys(creator_keys, "creator.keys.json")
111
+ creator_keys = agentcert.load_keys("creator.keys.json")
112
+
113
+ # Derive Bitcoin address (for funding anchor transactions)
114
+ address = agentcert.derive_bitcoin_address(creator_keys, network="testnet")
115
+ ```
116
+
117
+ ### Certificates
118
+
119
+ ```python
120
+ cert = agentcert.create_certificate(
121
+ creator_keys=creator_keys,
122
+ agent_keys=agent_keys,
123
+ name="my-agent",
124
+ platform="langchain",
125
+ model_hash="sha256:...",
126
+ capabilities=["task-a", "task-b"],
127
+ constraints=["spending-limit-1000"],
128
+ risk_tier=2,
129
+ expires_days=90,
130
+ )
131
+
132
+ agentcert.save_certificate(cert, "agent.cert.json")
133
+ cert = agentcert.load_certificate("agent.cert.json")
134
+ ```
135
+
136
+ ### Verification
137
+
138
+ The verifier runs 6 checks (all must pass for `VALID`):
139
+
140
+ 1. **cert_id integrity** — SHA-256(body) matches cert_id
141
+ 2. **creator_id derivation** — SHA-256(creator_public_key) matches creator_id
142
+ 3. **agent_id derivation** — SHA-256(agent_public_key) matches agent_id
143
+ 4. **Creator signature** — ECDSA verification against creator_public_key
144
+ 5. **Anchor integrity** — certificate hash matches the anchored hash (if receipt provided)
145
+ 6. **Expiration** — current time < expires
146
+
147
+ ```python
148
+ result = agentcert.verify(cert) # without anchor
149
+ result = agentcert.verify(cert, receipt) # with anchor receipt
150
+
151
+ print(result.status) # "VALID" or "INVALID"
152
+ print(result.valid) # True / False
153
+
154
+ for check in result.checks:
155
+ print(f"[{'PASS' if check.passed else 'FAIL'}] {check.name}: {check.detail}")
156
+ ```
157
+
158
+ ### Chain Operations
159
+
160
+ Certificates form a linked chain: create &rarr; update &rarr; ... &rarr; revoke.
161
+
162
+ ```python
163
+ # Update (carries over unchanged fields)
164
+ updated = agentcert.update_certificate(
165
+ previous_cert=cert,
166
+ creator_keys=creator_keys,
167
+ capabilities=["procurement", "negotiation", "invoicing"],
168
+ )
169
+
170
+ # Revoke (terminates the chain)
171
+ revocation = agentcert.revoke_certificate(
172
+ previous_cert=updated,
173
+ creator_keys=creator_keys,
174
+ reason="Decommissioned",
175
+ )
176
+
177
+ # Verify the full chain
178
+ chain_result = agentcert.verify_chain([cert, updated, revocation])
179
+ print(chain_result.status) # "REVOKED"
180
+ print(chain_result.valid) # True (REVOKED is a valid terminal state)
181
+ ```
182
+
183
+ ### Bitcoin Anchoring
184
+
185
+ Anchor a certificate to Bitcoin via an OP_RETURN transaction:
186
+
187
+ ```python
188
+ # The creator's Bitcoin address must be funded first
189
+ address = agentcert.derive_bitcoin_address(creator_keys, network="testnet")
190
+ print(f"Fund this address: {address}")
191
+
192
+ # Anchor (builds, signs, and broadcasts a Bitcoin transaction)
193
+ receipt = agentcert.anchor(cert, creator_keys=creator_keys, network="testnet")
194
+ print(receipt.txid)
195
+
196
+ # Save the receipt for later verification
197
+ agentcert.save_receipt(receipt, "receipt.json")
198
+ receipt = agentcert.load_receipt("receipt.json")
199
+ ```
200
+
201
+ The OP_RETURN payload is 38 bytes:
202
+
203
+ ```
204
+ [AIT\0] protocol tag (4 bytes)
205
+ [0x01] version (1 byte)
206
+ [0x02] IDENTITY_CERT (1 byte)
207
+ [...] SHA-256 hash (32 bytes)
208
+ ```
209
+
210
+ ## Certificate Structure
211
+
212
+ ```json
213
+ {
214
+ "ait_version": 1,
215
+ "cert_type": 1,
216
+ "cert_id": "<SHA-256 of body>",
217
+ "timestamp": 1739750000,
218
+ "expires": 1747526000,
219
+ "agent_public_key": "<33-byte compressed public key, hex>",
220
+ "agent_id": "<SHA-256 of agent_public_key>",
221
+ "creator_public_key": "<33-byte compressed public key, hex>",
222
+ "creator_id": "<SHA-256 of creator_public_key>",
223
+ "agent_metadata": {
224
+ "name": "my-agent",
225
+ "model_hash": "sha256:...",
226
+ "platform": "langchain",
227
+ "capabilities": ["procurement", "negotiation"],
228
+ "constraints": ["max-transaction-50000-usd"],
229
+ "risk_tier": 3
230
+ },
231
+ "previous_cert_id": null,
232
+ "creator_signature": "<ECDSA DER signature, hex>"
233
+ }
234
+ ```
235
+
236
+ | Field | Description |
237
+ |-------|-------------|
238
+ | `cert_type` | 1 = CREATION, 2 = UPDATE, 3 = REVOCATION |
239
+ | `cert_id` | SHA-256 of the certificate body (all fields except `cert_id` and `creator_signature`) |
240
+ | `creator_signature` | ECDSA/secp256k1 signature over the same body |
241
+ | `previous_cert_id` | Links to the prior certificate in the chain (null for the first) |
242
+
243
+ ## How It Works
244
+
245
+ **Signing:** The cert_id and creator_signature are computed over the same canonical JSON body. The cert_id verifies integrity (any tampering changes the hash). The signature verifies authenticity (only the creator's private key can produce it). Both are independently checkable by any third party.
246
+
247
+ **Anchoring:** The anchor hash is SHA-256 of the *complete* certificate (including cert_id and signature). This goes into a Bitcoin OP_RETURN output. If anything is modified after anchoring, the anchor check fails.
248
+
249
+ **Chain verification** checks: each cert's `previous_cert_id` links to the prior cert's `cert_id`, the same creator throughout, valid signatures on every cert, and the final cert's type determines the chain status (ACTIVE or REVOKED).
250
+
251
+ ## Development
252
+
253
+ ```bash
254
+ git clone https://github.com/shaleenchauhan/agentcert.git
255
+ cd agentcert
256
+ python3 -m venv .venv && source .venv/bin/activate
257
+ pip install -e ".[dev]"
258
+
259
+ # Run tests
260
+ pytest
261
+
262
+ # Run tests with coverage
263
+ pytest --cov=agentcert --cov-report=term-missing
264
+
265
+ # Run examples
266
+ python examples/quickstart.py
267
+ python examples/full_lifecycle.py
268
+ ```
269
+
270
+ ## Project Structure
271
+
272
+ ```
273
+ agentcert/
274
+ src/agentcert/
275
+ __init__.py # Public API (33 exports, no submodule imports needed)
276
+ keys.py # Key generation, save, load (secp256k1)
277
+ certificate.py # Certificate creation, signing, serialization
278
+ chain.py # Update, revoke, chain verification
279
+ anchor.py # Bitcoin OP_RETURN + Blockstream API
280
+ verify.py # 6-check verification with structured results
281
+ types.py # KeyPair, Certificate, AgentMetadata, etc.
282
+ exceptions.py # Custom exception hierarchy
283
+ cli.py # Click-based CLI (8 commands)
284
+ tests/ # 118 tests, 93% coverage
285
+ examples/ # quickstart.py, full_lifecycle.py
286
+ ```
287
+
288
+ ## Technical Decisions
289
+
290
+ | Component | Choice | Rationale |
291
+ |-----------|--------|-----------|
292
+ | Language | Python 3.11+ | AI/ML ecosystem standard |
293
+ | Curve | secp256k1 | Bitcoin-native, same keys for signing and anchoring |
294
+ | Signatures | ECDSA | Proven; Schnorr migration path later |
295
+ | Hashing | SHA-256 | Bitcoin-native |
296
+ | Serialization | JSON (deterministic) | `sort_keys=True, separators=(',',':')` |
297
+ | CLI | Click | Mature, clean subcommand support |
298
+ | Bitcoin API | Blockstream | No auth, free, reliable |
299
+ | Dependencies | 3 runtime | `cryptography`, `requests`, `click` |
300
+
301
+ ## License
302
+
303
+ MIT