auths-python 0.1.0__cp38-abi3-win_amd64.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.
auths/__init__.py ADDED
@@ -0,0 +1,147 @@
1
+ """Auths Python SDK — decentralized identity for developers and AI agents."""
2
+
3
+ from auths._client import Auths
4
+ from auths._errors import (
5
+ AuthsError,
6
+ CryptoError,
7
+ IdentityError,
8
+ KeychainError,
9
+ NetworkError,
10
+ OrgError,
11
+ PairingError,
12
+ StorageError,
13
+ VerificationError,
14
+ )
15
+ from auths._native import (
16
+ ChainLink,
17
+ VerificationReport,
18
+ VerificationResult,
19
+ VerificationStatus,
20
+ get_token,
21
+ sign_action,
22
+ sign_bytes,
23
+ verify_action_envelope,
24
+ verify_at_time,
25
+ verify_at_time_with_capability,
26
+ verify_attestation,
27
+ verify_attestation_with_capability,
28
+ verify_chain,
29
+ verify_chain_with_capability,
30
+ verify_device_authorization,
31
+ )
32
+ from auths.agent import AgentAuth
33
+ from auths.doctor import Check, DiagnosticReport, DoctorService
34
+ from auths.audit import (
35
+ AuditReport,
36
+ AuditService,
37
+ AuditSummary,
38
+ CommitRecord,
39
+ IdentityBundleInfo,
40
+ parse_identity_bundle,
41
+ parse_identity_bundle_info,
42
+ )
43
+ from auths.org import Org, OrgMember, OrgService
44
+ from auths.pairing import PairingResponse, PairingResult, PairingService, PairingSession
45
+ from auths.trust import TrustEntry, TrustLevel, TrustService
46
+ from auths.witness import Witness, WitnessService
47
+ from auths.artifact import ArtifactPublishResult, ArtifactSigningResult
48
+ from auths.attestation_query import Attestation, AttestationService
49
+ from auths.commit import CommitSigningResult
50
+ from auths.jwt import AuthsClaims
51
+ from auths.policy import Outcome, PolicyBuilder, ReasonCode, eval_context_from_commit_result
52
+ from auths.devices import Device, DeviceExtension, DeviceService
53
+ from auths.identity import AgentIdentity, DelegatedAgent, Identity, IdentityService
54
+ from auths.rotation import IdentityRotationResult
55
+ from auths.verify import WitnessConfig, WitnessKey, verify_chain_with_witnesses
56
+ from auths.policy import compile_policy
57
+ from auths.git import (
58
+ CommitResult,
59
+ ErrorCode,
60
+ LayoutError,
61
+ LayoutInfo,
62
+ VerifyResult,
63
+ discover_layout,
64
+ generate_allowed_signers,
65
+ verify_commit_range,
66
+ )
67
+
68
+ __all__ = [
69
+ "Auths",
70
+ "AuthsError",
71
+ "VerificationError",
72
+ "CryptoError",
73
+ "KeychainError",
74
+ "StorageError",
75
+ "NetworkError",
76
+ "IdentityError",
77
+ "VerificationResult",
78
+ "VerificationStatus",
79
+ "ChainLink",
80
+ "VerificationReport",
81
+ "verify_at_time",
82
+ "verify_at_time_with_capability",
83
+ "verify_attestation",
84
+ "verify_chain",
85
+ "verify_attestation_with_capability",
86
+ "verify_chain_with_capability",
87
+ "verify_chain_with_witnesses",
88
+ "verify_device_authorization",
89
+ "sign_bytes",
90
+ "sign_action",
91
+ "verify_action_envelope",
92
+ "get_token",
93
+ "AgentAuth",
94
+ "ArtifactPublishResult",
95
+ "ArtifactSigningResult",
96
+ "Attestation",
97
+ "AttestationService",
98
+ "CommitSigningResult",
99
+ "AuthsClaims",
100
+ "Outcome",
101
+ "PolicyBuilder",
102
+ "ReasonCode",
103
+ "eval_context_from_commit_result",
104
+ "compile_policy",
105
+ "parse_identity_bundle",
106
+ "parse_identity_bundle_info",
107
+ "IdentityBundleInfo",
108
+ "TrustLevel",
109
+ "CommitResult",
110
+ "ErrorCode",
111
+ "VerifyResult",
112
+ "LayoutInfo",
113
+ "LayoutError",
114
+ "discover_layout",
115
+ "generate_allowed_signers",
116
+ "verify_commit_range",
117
+ "Identity",
118
+ "AgentIdentity",
119
+ "DelegatedAgent",
120
+ "IdentityService",
121
+ "Device",
122
+ "DeviceExtension",
123
+ "DeviceService",
124
+ "IdentityRotationResult",
125
+ "WitnessConfig",
126
+ "WitnessKey",
127
+ "Org",
128
+ "OrgMember",
129
+ "OrgService",
130
+ "OrgError",
131
+ "AuditReport",
132
+ "AuditService",
133
+ "AuditSummary",
134
+ "CommitRecord",
135
+ "TrustEntry",
136
+ "TrustService",
137
+ "Witness",
138
+ "WitnessService",
139
+ "Check",
140
+ "DiagnosticReport",
141
+ "DoctorService",
142
+ "PairingResponse",
143
+ "PairingResult",
144
+ "PairingService",
145
+ "PairingSession",
146
+ "PairingError",
147
+ ]
auths/__init__.pyi ADDED
@@ -0,0 +1,486 @@
1
+ from dataclasses import dataclass
2
+
3
+ # -- Client --
4
+
5
+ class Auths:
6
+ repo_path: str
7
+ identities: IdentityService
8
+ devices: DeviceService
9
+ attestations: AttestationService
10
+ orgs: OrgService
11
+ audit: AuditService
12
+ trust: TrustService
13
+ pairing: PairingService
14
+ witnesses: WitnessService
15
+ doctor: DoctorService
16
+ def __init__(self, repo_path: str = "~/.auths", passphrase: str | None = None) -> None: ...
17
+ def verify(self, attestation_json: str, issuer_key: str, required_capability: str | None = None, at: str | None = None) -> VerificationResult: ...
18
+ def verify_chain(self, attestations: list[str], root_key: str, required_capability: str | None = None, witnesses: WitnessConfig | None = None) -> VerificationReport: ...
19
+ def verify_device(self, identity_did: str, device_did: str, attestations: list[str], identity_key: str) -> VerificationReport: ...
20
+ def sign(self, message: bytes, private_key: str) -> str: ...
21
+ def sign_action(self, action_type: str, payload: str, identity_did: str, private_key: str) -> str: ...
22
+ def verify_action(self, envelope_json: str, public_key: str) -> VerificationResult: ...
23
+ def sign_commit(self, data: bytes, *, identity_did: str, passphrase: str | None = None) -> CommitSigningResult: ...
24
+ def sign_artifact(self, path: str, *, identity_did: str, expires_in: int | None = None, note: str | None = None) -> ArtifactSigningResult: ...
25
+ def sign_artifact_bytes(self, data: bytes, *, identity_did: str, expires_in: int | None = None, note: str | None = None) -> ArtifactSigningResult: ...
26
+ def sign_as(self, message: bytes, identity: str, passphrase: str | None = None) -> str: ...
27
+ def sign_action_as(self, action_type: str, payload: str, identity: str, passphrase: str | None = None) -> str: ...
28
+ def get_public_key(self, identity: str, passphrase: str | None = None) -> str: ...
29
+ def sign_as_agent(self, message: bytes, key_alias: str, passphrase: str | None = None) -> str: ...
30
+ def sign_action_as_agent(self, action_type: str, payload: str, key_alias: str, agent_did: str, passphrase: str | None = None) -> str: ...
31
+ def publish_artifact(self, attestation_json: str, *, registry_url: str, package_name: str | None = None) -> ArtifactPublishResult: ...
32
+ def get_token(self, bridge_url: str, chain_json: str, root_key: str, capabilities: list[str] | None = None) -> str: ...
33
+
34
+ # -- Errors --
35
+
36
+ class AuthsError(Exception):
37
+ message: str
38
+ code: str
39
+ context: dict
40
+ def __init__(self, message: str, code: str, **context: object) -> None: ...
41
+
42
+ class VerificationError(AuthsError): ...
43
+ class CryptoError(AuthsError): ...
44
+ class KeychainError(AuthsError): ...
45
+ class StorageError(AuthsError): ...
46
+
47
+ class NetworkError(AuthsError):
48
+ should_retry: bool
49
+ def __init__(self, message: str, code: str, should_retry: bool = False, **context: object) -> None: ...
50
+
51
+ class IdentityError(AuthsError): ...
52
+ class OrgError(AuthsError): ...
53
+ class PairingError(AuthsError): ...
54
+
55
+ # -- Native types --
56
+
57
+ class VerificationResult:
58
+ valid: bool
59
+ error: str | None
60
+ def __bool__(self) -> bool: ...
61
+
62
+ class VerificationStatus:
63
+ status_type: str
64
+ at: str | None
65
+ step: int | None
66
+ missing_link: str | None
67
+ required: int | None
68
+ verified: int | None
69
+ def is_valid(self) -> bool: ...
70
+
71
+ class ChainLink:
72
+ issuer: str
73
+ subject: str
74
+ valid: bool
75
+ error: str | None
76
+
77
+ class VerificationReport:
78
+ status: VerificationStatus
79
+ chain: list[ChainLink]
80
+ warnings: list[str]
81
+ def is_valid(self) -> bool: ...
82
+
83
+ # -- Verify functions --
84
+
85
+ @dataclass
86
+ class WitnessKey:
87
+ did: str
88
+ public_key_hex: str
89
+
90
+ @dataclass
91
+ class WitnessConfig:
92
+ receipts: list[str]
93
+ keys: list[WitnessKey]
94
+ threshold: int
95
+
96
+ def verify_at_time(attestation_json: str, issuer_pk_hex: str, at_rfc3339: str) -> VerificationResult: ...
97
+ def verify_at_time_with_capability(attestation_json: str, issuer_pk_hex: str, at_rfc3339: str, required_capability: str) -> VerificationResult: ...
98
+ def verify_attestation(attestation_json: str, issuer_pk_hex: str) -> VerificationResult: ...
99
+ def verify_chain(attestations_json: list[str], root_pk_hex: str) -> VerificationReport: ...
100
+ def verify_attestation_with_capability(attestation_json: str, issuer_pk_hex: str, required_capability: str) -> VerificationResult: ...
101
+ def verify_chain_with_capability(attestations_json: list[str], root_pk_hex: str, required_capability: str) -> VerificationReport: ...
102
+ def verify_device_authorization(identity_did: str, device_did: str, attestations_json: list[str], identity_pk_hex: str) -> VerificationReport: ...
103
+
104
+ # -- Sign functions --
105
+
106
+ def sign_bytes(private_key_hex: str, message: bytes) -> str: ...
107
+ def sign_action(private_key_hex: str, action_type: str, payload_json: str, identity_did: str) -> str: ...
108
+ def verify_action_envelope(envelope_json: str, public_key_hex: str) -> VerificationResult: ...
109
+
110
+ # -- Token --
111
+
112
+ def get_token(bridge_url: str, chain_json: str, root_public_key: str, capabilities: list[str]) -> str: ...
113
+
114
+ # -- Identity resources --
115
+
116
+ @dataclass
117
+ class Identity:
118
+ did: str
119
+ public_key: str
120
+ label: str
121
+ repo_path: str
122
+
123
+ @dataclass
124
+ class AgentIdentity:
125
+ did: str
126
+ attestation: str
127
+ public_key: str
128
+
129
+ @dataclass
130
+ class DelegatedAgent:
131
+ did: str
132
+ attestation: str
133
+ public_key: str
134
+
135
+ @dataclass
136
+ class IdentityRotationResult:
137
+ controller_did: str
138
+ new_key_fingerprint: str
139
+ previous_key_fingerprint: str
140
+ sequence: int
141
+
142
+ class IdentityService:
143
+ def create(self, label: str = "main", repo_path: str | None = None, passphrase: str | None = None) -> Identity: ...
144
+ def rotate(self, identity_did: str, *, passphrase: str | None = None) -> IdentityRotationResult: ...
145
+ def create_agent(self, name: str, capabilities: list[str], passphrase: str | None = None) -> AgentIdentity: ...
146
+ def delegate_agent(self, identity_did: str, name: str, capabilities: list[str], expires_in: int | None = None, passphrase: str | None = None) -> DelegatedAgent: ...
147
+
148
+ # -- Device resources --
149
+
150
+ @dataclass
151
+ class Device:
152
+ did: str
153
+ attestation_id: str
154
+
155
+ @dataclass
156
+ class DeviceExtension:
157
+ device_did: str
158
+ new_expires_at: str
159
+ previous_expires_at: str | None
160
+
161
+ @dataclass
162
+ class Attestation:
163
+ rid: str
164
+ issuer: str
165
+ subject: str
166
+ device_did: str
167
+ capabilities: list[str]
168
+ signer_type: str | None
169
+ expires_at: str | None
170
+ revoked_at: str | None
171
+ created_at: str | None
172
+ delegated_by: str | None
173
+ json: str
174
+ @property
175
+ def is_active(self) -> bool: ...
176
+ @property
177
+ def is_revoked(self) -> bool: ...
178
+
179
+ @dataclass
180
+ class CommitSigningResult:
181
+ signature_pem: str
182
+ method: str
183
+ namespace: str
184
+
185
+ @dataclass
186
+ class ArtifactSigningResult:
187
+ attestation_json: str
188
+ rid: str
189
+ digest: str
190
+ file_size: int
191
+
192
+ @dataclass
193
+ class ArtifactPublishResult:
194
+ attestation_rid: str
195
+ package_name: str | None
196
+ signer_did: str
197
+
198
+ class AttestationService:
199
+ def list(self, *, identity_did: str | None = None, device_did: str | None = None) -> list[Attestation]: ...
200
+ def latest(self, device_did: str) -> Attestation | None: ...
201
+
202
+ class DeviceService:
203
+ def link(self, identity_did: str, capabilities: list[str] | None = None, expires_in: int | None = None, passphrase: str | None = None) -> Device: ...
204
+ def extend(self, device_did: str, identity_did: str, *, days: int = 90, passphrase: str | None = None) -> DeviceExtension: ...
205
+ def revoke(self, device_did: str, identity_did: str, note: str | None = None, passphrase: str | None = None) -> None: ...
206
+
207
+ # -- Agent --
208
+
209
+ class AgentAuth:
210
+ bridge_url: str
211
+ def __init__(self, bridge_url: str, attestation_chain_path: str, root_public_key: str | None = None) -> None: ...
212
+ def get_token(self, capabilities: list[str] | None = None) -> str: ...
213
+
214
+ AuthsAgentAuth = AgentAuth
215
+
216
+ # -- Git --
217
+
218
+ class ErrorCode:
219
+ UNSIGNED: str
220
+ GPG_NOT_SUPPORTED: str
221
+ UNKNOWN_SIGNER: str
222
+ INVALID_SIGNATURE: str
223
+ NO_ATTESTATION_FOUND: str
224
+ DEVICE_REVOKED: str
225
+ DEVICE_EXPIRED: str
226
+ LAYOUT_DISCOVERY_FAILED: str
227
+
228
+ @dataclass
229
+ class CommitResult:
230
+ commit_sha: str
231
+ is_valid: bool
232
+ signer: str | None
233
+ error: str | None
234
+ error_code: str | None
235
+
236
+ @dataclass
237
+ class VerifyResult:
238
+ commits: list[CommitResult]
239
+ passed: bool
240
+ mode: str
241
+ summary: str
242
+
243
+ @dataclass
244
+ class LayoutInfo:
245
+ bundle: str | None
246
+ refs: list[str] | None
247
+ source: str
248
+
249
+ class LayoutError(Exception):
250
+ code: str
251
+ def __init__(self, code: str, message: str) -> None: ...
252
+
253
+ def sign_commit(data: bytes, identity_key_alias: str, repo_path: str, passphrase: str | None = None) -> CommitSigningResult: ...
254
+
255
+ def sign_artifact(file_path: str, identity_key_alias: str, repo_path: str, passphrase: str | None = None, expires_in: int | None = None, note: str | None = None) -> ArtifactSigningResult: ...
256
+ def sign_artifact_bytes(data: bytes, identity_key_alias: str, repo_path: str, passphrase: str | None = None, expires_in: int | None = None, note: str | None = None) -> ArtifactSigningResult: ...
257
+
258
+ def list_attestations(repo_path: str) -> list[Attestation]: ...
259
+ def list_attestations_by_device(repo_path: str, device_did: str) -> list[Attestation]: ...
260
+ def get_latest_attestation(repo_path: str, device_did: str) -> Attestation | None: ...
261
+
262
+ class CompiledPolicy:
263
+ def check(self, context: EvalContext) -> Decision: ...
264
+ def to_json(self) -> str: ...
265
+
266
+ class EvalContext:
267
+ def __init__(self, issuer: str, subject: str, *, capabilities: list[str] | None = None, role: str | None = None, revoked: bool = False, expires_at: str | None = None, repo: str | None = None, environment: str | None = None, signer_type: str | None = None, delegated_by: str | None = None, chain_depth: int | None = None) -> None: ...
268
+
269
+ @dataclass
270
+ class Decision:
271
+ outcome: str
272
+ reason: str
273
+ message: str
274
+ @property
275
+ def allowed(self) -> bool: ...
276
+ @property
277
+ def denied(self) -> bool: ...
278
+ def __bool__(self) -> bool: ...
279
+
280
+ class PolicyBuilder:
281
+ def __init__(self) -> None: ...
282
+ @classmethod
283
+ def standard(cls, capability: str) -> PolicyBuilder: ...
284
+ @classmethod
285
+ def any_of(cls, *builders: PolicyBuilder) -> PolicyBuilder: ...
286
+ def not_revoked(self) -> PolicyBuilder: ...
287
+ def not_expired(self) -> PolicyBuilder: ...
288
+ def expires_after(self, seconds: int) -> PolicyBuilder: ...
289
+ def issued_within(self, seconds: int) -> PolicyBuilder: ...
290
+ def require_capability(self, cap: str) -> PolicyBuilder: ...
291
+ def require_all_capabilities(self, caps: list[str]) -> PolicyBuilder: ...
292
+ def require_any_capability(self, caps: list[str]) -> PolicyBuilder: ...
293
+ def require_issuer(self, did: str) -> PolicyBuilder: ...
294
+ def require_issuer_in(self, dids: list[str]) -> PolicyBuilder: ...
295
+ def require_subject(self, did: str) -> PolicyBuilder: ...
296
+ def require_delegated_by(self, did: str) -> PolicyBuilder: ...
297
+ def require_agent(self) -> PolicyBuilder: ...
298
+ def require_human(self) -> PolicyBuilder: ...
299
+ def require_workload(self) -> PolicyBuilder: ...
300
+ def require_repo(self, repo: str) -> PolicyBuilder: ...
301
+ def require_env(self, env: str) -> PolicyBuilder: ...
302
+ def max_chain_depth(self, depth: int) -> PolicyBuilder: ...
303
+ def or_policy(self, other: PolicyBuilder) -> PolicyBuilder: ...
304
+ def negate(self) -> PolicyBuilder: ...
305
+ def build(self) -> CompiledPolicy: ...
306
+ def to_json(self) -> str: ...
307
+
308
+ def compile_policy(policy_json: str) -> CompiledPolicy: ...
309
+
310
+ @dataclass
311
+ class AuthsClaims:
312
+ sub: str
313
+ keri_prefix: str
314
+ capabilities: list[str]
315
+ iss: str
316
+ aud: str
317
+ exp: int
318
+ iat: int
319
+ jti: str
320
+ signer_type: str | None
321
+ delegated_by: str | None
322
+ witness_quorum: dict | None
323
+ github_actor: str | None
324
+ github_repository: str | None
325
+ def has_capability(self, cap: str) -> bool: ...
326
+ def has_any_capability(self, caps: list[str]) -> bool: ...
327
+ def has_all_capabilities(self, caps: list[str]) -> bool: ...
328
+ @property
329
+ def is_agent(self) -> bool: ...
330
+ @property
331
+ def is_human(self) -> bool: ...
332
+ @property
333
+ def is_delegated(self) -> bool: ...
334
+
335
+ class AuthsJWKSClient:
336
+ def __init__(self, jwks_url: str, *, cache_ttl: int = 300) -> None: ...
337
+ def verify_token(self, token: str, *, audience: str, issuer: str | None = None, leeway: int = 60) -> AuthsClaims: ...
338
+
339
+ def discover_layout(repo_root: str = ".") -> LayoutInfo: ...
340
+ def generate_allowed_signers(repo_path: str = "~/.auths") -> str: ...
341
+ def verify_commit_range(commit_range: str, identity_bundle: str | None = None, allowed_signers: str = ".auths/allowed_signers", mode: str = "enforce") -> VerifyResult: ...
342
+ def verify_chain_with_witnesses(attestations_json: list[str], root_pk_hex: str, witnesses: WitnessConfig) -> VerificationReport: ...
343
+ def verify_token(token: str, *, jwks_url: str, audience: str, issuer: str | None = None, leeway: int = 60) -> AuthsClaims: ...
344
+
345
+ # -- Organization --
346
+
347
+ @dataclass
348
+ class Org:
349
+ prefix: str
350
+ did: str
351
+ label: str
352
+ repo_path: str
353
+
354
+ @dataclass
355
+ class OrgMember:
356
+ member_did: str
357
+ role: str
358
+ capabilities: list[str]
359
+ issuer_did: str
360
+ attestation_rid: str
361
+ revoked: bool
362
+ expires_at: str | None
363
+
364
+ class OrgService:
365
+ def create(self, label: str, repo_path: str | None = None, passphrase: str | None = None) -> Org: ...
366
+ def add_member(self, org_did: str, member_did: str, role: str = "member", capabilities: list[str] | None = None, note: str | None = None, repo_path: str | None = None, passphrase: str | None = None, member_public_key_hex: str | None = None) -> OrgMember: ...
367
+ def revoke_member(self, org_did: str, member_did: str, note: str | None = None, repo_path: str | None = None, passphrase: str | None = None, member_public_key_hex: str | None = None) -> OrgMember: ...
368
+ def update_member(self, org_did: str, member_did: str, role: str | None = None, capabilities: list[str] | None = None, note: str | None = None, repo_path: str | None = None, passphrase: str | None = None, member_public_key_hex: str | None = None) -> OrgMember: ...
369
+ def list_members(self, org_did: str, include_revoked: bool = False, repo_path: str | None = None) -> list[OrgMember]: ...
370
+ def get_member(self, org_did: str, member_did: str, repo_path: str | None = None) -> OrgMember | None: ...
371
+
372
+ # -- Audit --
373
+
374
+ @dataclass
375
+ class AuditSummary:
376
+ total_commits: int
377
+ signed_commits: int
378
+ unsigned_commits: int
379
+ auths_signed: int
380
+ gpg_signed: int
381
+ ssh_signed: int
382
+ verification_passed: int
383
+ verification_failed: int
384
+ @property
385
+ def signing_rate(self) -> float: ...
386
+
387
+ @dataclass
388
+ class CommitRecord:
389
+ oid: str
390
+ author_name: str
391
+ author_email: str
392
+ date: str
393
+ message: str
394
+ signature_type: str | None
395
+ signer_did: str | None
396
+ verified: bool | None
397
+
398
+ @dataclass
399
+ class AuditReport:
400
+ commits: list[CommitRecord]
401
+ summary: AuditSummary
402
+
403
+ class AuditService:
404
+ def report(self, repo_path: str | None = None, since: str | None = None, until: str | None = None, author: str | None = None, limit: int = 500) -> AuditReport: ...
405
+ def is_compliant(self, repo_path: str | None = None, since: str | None = None, until: str | None = None) -> bool: ...
406
+
407
+ # -- Trust --
408
+
409
+ @dataclass
410
+ class TrustEntry:
411
+ did: str
412
+ label: str | None
413
+ trust_level: str
414
+ first_seen: str
415
+ kel_sequence: int | None
416
+ pinned_at: str
417
+
418
+ class TrustService:
419
+ def pin(self, did: str, label: str | None = None, trust_level: str = "manual", repo_path: str | None = None) -> TrustEntry: ...
420
+ def remove(self, did: str, repo_path: str | None = None) -> None: ...
421
+ def list(self, repo_path: str | None = None) -> list[TrustEntry]: ...
422
+ def get(self, did: str, repo_path: str | None = None) -> TrustEntry | None: ...
423
+ def is_trusted(self, did: str, repo_path: str | None = None) -> bool: ...
424
+
425
+ # -- Witness --
426
+
427
+ @dataclass
428
+ class Witness:
429
+ url: str
430
+ did: str | None
431
+ label: str | None
432
+
433
+ class WitnessService:
434
+ def add(self, url: str, label: str | None = None, repo_path: str | None = None) -> Witness: ...
435
+ def remove(self, url: str, repo_path: str | None = None) -> None: ...
436
+ def list(self, repo_path: str | None = None) -> list[Witness]: ...
437
+
438
+ # -- Doctor --
439
+
440
+ @dataclass
441
+ class Check:
442
+ name: str
443
+ passed: bool
444
+ message: str
445
+ fix_hint: str | None
446
+
447
+ @dataclass
448
+ class DiagnosticReport:
449
+ checks: list[Check]
450
+ all_passed: bool
451
+ version: str
452
+
453
+ class DoctorService:
454
+ def check(self, repo_path: str | None = None) -> DiagnosticReport: ...
455
+ def check_one(self, name: str, repo_path: str | None = None) -> Check: ...
456
+
457
+ # -- Pairing --
458
+
459
+ @dataclass
460
+ class PairingResponse:
461
+ device_did: str
462
+ device_name: str | None
463
+ device_public_key_hex: str
464
+ capabilities: list[str]
465
+
466
+ @dataclass
467
+ class PairingResult:
468
+ device_did: str
469
+ device_name: str | None
470
+ attestation_rid: str | None
471
+
472
+ class PairingSession:
473
+ session_id: str
474
+ short_code: str
475
+ endpoint: str
476
+ token: str
477
+ controller_did: str
478
+ def wait_for_response(self, timeout_secs: int = 300) -> PairingResponse: ...
479
+ def stop(self) -> None: ...
480
+ def __enter__(self) -> PairingSession: ...
481
+ def __exit__(self, exc_type: type | None, exc_val: BaseException | None, exc_tb: object | None) -> bool: ...
482
+
483
+ class PairingService:
484
+ def create_session(self, capabilities: list[str] | None = None, timeout_secs: int = 300, bind_address: str = "0.0.0.0", enable_mdns: bool = True, repo_path: str | None = None, passphrase: str | None = None) -> PairingSession: ...
485
+ def join(self, short_code: str, endpoint: str, token: str, device_name: str | None = None, repo_path: str | None = None, passphrase: str | None = None) -> PairingResult: ...
486
+ def complete(self, session: PairingSession, response: PairingResponse, repo_path: str | None = None, passphrase: str | None = None) -> PairingResult: ...