ciris-verify 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,152 @@
1
+ Metadata-Version: 2.4
2
+ Name: ciris-verify
3
+ Version: 0.1.0
4
+ Summary: Python bindings for CIRISVerify hardware-rooted license verification
5
+ Author-email: CIRIS Engineering <engineering@ciris.ai>
6
+ License-Expression: AGPL-3.0-or-later
7
+ Project-URL: Homepage, https://github.com/CIRISAI/CIRISVerify
8
+ Project-URL: Repository, https://github.com/CIRISAI/CIRISVerify
9
+ Project-URL: Documentation, https://github.com/CIRISAI/CIRISVerify/tree/main/bindings/python
10
+ Project-URL: Issues, https://github.com/CIRISAI/CIRISVerify/issues
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Rust
22
+ Classifier: Topic :: Security :: Cryptography
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
29
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
30
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
31
+
32
+ # CIRISVerify Python Bindings
33
+
34
+ Python bindings for CIRISVerify, the hardware-rooted license verification module for the CIRIS ecosystem.
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install ciris-verify
40
+ ```
41
+
42
+ **Note:** The CIRISVerify binary must be installed separately. See the [CIRISVerify documentation](https://github.com/CIRISAI/CIRISVerify) for installation instructions.
43
+
44
+ ## Quick Start
45
+
46
+ ```python
47
+ import os
48
+ from ciris_verify import CIRISVerify, LicenseStatus
49
+
50
+ # Initialize the verifier
51
+ verifier = CIRISVerify()
52
+
53
+ # Get license status with a fresh nonce
54
+ status = await verifier.get_license_status(
55
+ challenge_nonce=os.urandom(32)
56
+ )
57
+
58
+ # Check if professional capabilities are available
59
+ if status.allows_licensed_operation():
60
+ print("Professional license verified!")
61
+ print(f"Tier: {status.license.tier}")
62
+ print(f"Capabilities: {status.license.capabilities}")
63
+ else:
64
+ print("Running in community mode")
65
+
66
+ # IMPORTANT: Always display the mandatory disclosure
67
+ print(status.mandatory_disclosure.text)
68
+ ```
69
+
70
+ ## Mandatory Disclosure
71
+
72
+ Per the CIRIS ecosystem rules, agents **MUST** display the `mandatory_disclosure.text` to users. This ensures transparency about the agent's capabilities and licensing status.
73
+
74
+ ```python
75
+ # The disclosure MUST be shown to users
76
+ disclosure = status.mandatory_disclosure
77
+ print(f"[{disclosure.severity.upper()}] {disclosure.text}")
78
+ ```
79
+
80
+ ## Capability Checking
81
+
82
+ For frequent capability checks, use the fast path:
83
+
84
+ ```python
85
+ result = await verifier.check_capability("medical:diagnosis")
86
+ if result.allowed:
87
+ # Capability is available
88
+ pass
89
+ else:
90
+ print(f"Capability denied: {result.reason}")
91
+ ```
92
+
93
+ ## Testing
94
+
95
+ For testing without the actual binary, use `MockCIRISVerify`:
96
+
97
+ ```python
98
+ from ciris_verify import MockCIRISVerify, LicenseStatus
99
+
100
+ # Create a mock that returns community mode
101
+ verifier = MockCIRISVerify(
102
+ mock_status=LicenseStatus.UNLICENSED_COMMUNITY
103
+ )
104
+
105
+ # Use exactly like the real client
106
+ status = await verifier.get_license_status(os.urandom(32))
107
+ assert status.status == LicenseStatus.UNLICENSED_COMMUNITY
108
+ ```
109
+
110
+ ## Error Handling
111
+
112
+ ```python
113
+ from ciris_verify import (
114
+ CIRISVerifyError,
115
+ BinaryNotFoundError,
116
+ BinaryTamperedError,
117
+ VerificationFailedError,
118
+ )
119
+
120
+ try:
121
+ verifier = CIRISVerify()
122
+ status = await verifier.get_license_status(os.urandom(32))
123
+ except BinaryNotFoundError as e:
124
+ # Binary not installed
125
+ print(f"CIRISVerify not found: {e.path}")
126
+ except BinaryTamperedError:
127
+ # CRITICAL: Binary has been modified
128
+ # Halt all operations immediately
129
+ raise SystemExit("SECURITY ALERT: Binary integrity compromised")
130
+ except VerificationFailedError as e:
131
+ # Verification failed - operate in restricted mode
132
+ print(f"Verification failed: {e}")
133
+ ```
134
+
135
+ ## License Status Codes
136
+
137
+ | Status | Code | Description |
138
+ |--------|------|-------------|
139
+ | `LICENSED_PROFESSIONAL` | 100 | Full professional license active |
140
+ | `LICENSED_PROFESSIONAL_GRACE` | 101 | License valid, in offline grace period |
141
+ | `UNLICENSED_COMMUNITY` | 200 | Community mode, no professional capabilities |
142
+ | `RESTRICTED_*` | 300-399 | Restricted mode due to verification issues |
143
+ | `ERROR_*` | 400-499 | Error states (revoked, expired, etc.) |
144
+ | `LOCKDOWN_*` | 500+ | Critical security failure, halt operations |
145
+
146
+ ## Thread Safety
147
+
148
+ The client is thread-safe and can be used from multiple threads or async tasks concurrently.
149
+
150
+ ## License
151
+
152
+ AGPL-3.0-or-later - See LICENSE file in the CIRISVerify repository.
@@ -0,0 +1,121 @@
1
+ # CIRISVerify Python Bindings
2
+
3
+ Python bindings for CIRISVerify, the hardware-rooted license verification module for the CIRIS ecosystem.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install ciris-verify
9
+ ```
10
+
11
+ **Note:** The CIRISVerify binary must be installed separately. See the [CIRISVerify documentation](https://github.com/CIRISAI/CIRISVerify) for installation instructions.
12
+
13
+ ## Quick Start
14
+
15
+ ```python
16
+ import os
17
+ from ciris_verify import CIRISVerify, LicenseStatus
18
+
19
+ # Initialize the verifier
20
+ verifier = CIRISVerify()
21
+
22
+ # Get license status with a fresh nonce
23
+ status = await verifier.get_license_status(
24
+ challenge_nonce=os.urandom(32)
25
+ )
26
+
27
+ # Check if professional capabilities are available
28
+ if status.allows_licensed_operation():
29
+ print("Professional license verified!")
30
+ print(f"Tier: {status.license.tier}")
31
+ print(f"Capabilities: {status.license.capabilities}")
32
+ else:
33
+ print("Running in community mode")
34
+
35
+ # IMPORTANT: Always display the mandatory disclosure
36
+ print(status.mandatory_disclosure.text)
37
+ ```
38
+
39
+ ## Mandatory Disclosure
40
+
41
+ Per the CIRIS ecosystem rules, agents **MUST** display the `mandatory_disclosure.text` to users. This ensures transparency about the agent's capabilities and licensing status.
42
+
43
+ ```python
44
+ # The disclosure MUST be shown to users
45
+ disclosure = status.mandatory_disclosure
46
+ print(f"[{disclosure.severity.upper()}] {disclosure.text}")
47
+ ```
48
+
49
+ ## Capability Checking
50
+
51
+ For frequent capability checks, use the fast path:
52
+
53
+ ```python
54
+ result = await verifier.check_capability("medical:diagnosis")
55
+ if result.allowed:
56
+ # Capability is available
57
+ pass
58
+ else:
59
+ print(f"Capability denied: {result.reason}")
60
+ ```
61
+
62
+ ## Testing
63
+
64
+ For testing without the actual binary, use `MockCIRISVerify`:
65
+
66
+ ```python
67
+ from ciris_verify import MockCIRISVerify, LicenseStatus
68
+
69
+ # Create a mock that returns community mode
70
+ verifier = MockCIRISVerify(
71
+ mock_status=LicenseStatus.UNLICENSED_COMMUNITY
72
+ )
73
+
74
+ # Use exactly like the real client
75
+ status = await verifier.get_license_status(os.urandom(32))
76
+ assert status.status == LicenseStatus.UNLICENSED_COMMUNITY
77
+ ```
78
+
79
+ ## Error Handling
80
+
81
+ ```python
82
+ from ciris_verify import (
83
+ CIRISVerifyError,
84
+ BinaryNotFoundError,
85
+ BinaryTamperedError,
86
+ VerificationFailedError,
87
+ )
88
+
89
+ try:
90
+ verifier = CIRISVerify()
91
+ status = await verifier.get_license_status(os.urandom(32))
92
+ except BinaryNotFoundError as e:
93
+ # Binary not installed
94
+ print(f"CIRISVerify not found: {e.path}")
95
+ except BinaryTamperedError:
96
+ # CRITICAL: Binary has been modified
97
+ # Halt all operations immediately
98
+ raise SystemExit("SECURITY ALERT: Binary integrity compromised")
99
+ except VerificationFailedError as e:
100
+ # Verification failed - operate in restricted mode
101
+ print(f"Verification failed: {e}")
102
+ ```
103
+
104
+ ## License Status Codes
105
+
106
+ | Status | Code | Description |
107
+ |--------|------|-------------|
108
+ | `LICENSED_PROFESSIONAL` | 100 | Full professional license active |
109
+ | `LICENSED_PROFESSIONAL_GRACE` | 101 | License valid, in offline grace period |
110
+ | `UNLICENSED_COMMUNITY` | 200 | Community mode, no professional capabilities |
111
+ | `RESTRICTED_*` | 300-399 | Restricted mode due to verification issues |
112
+ | `ERROR_*` | 400-499 | Error states (revoked, expired, etc.) |
113
+ | `LOCKDOWN_*` | 500+ | Critical security failure, halt operations |
114
+
115
+ ## Thread Safety
116
+
117
+ The client is thread-safe and can be used from multiple threads or async tasks concurrently.
118
+
119
+ ## License
120
+
121
+ AGPL-3.0-or-later - See LICENSE file in the CIRISVerify repository.
@@ -0,0 +1,63 @@
1
+ """CIRISVerify Python bindings.
2
+
3
+ Hardware-rooted license verification for the CIRIS ecosystem.
4
+ Provides cryptographic proof of license status to prevent capability spoofing.
5
+
6
+ Usage:
7
+ from ciris_verify import CIRISVerify, LicenseStatus
8
+
9
+ verifier = CIRISVerify()
10
+ status = verifier.get_license_status(challenge_nonce=os.urandom(32))
11
+
12
+ if status.allows_licensed_operation():
13
+ # Professional capabilities available
14
+ pass
15
+ else:
16
+ # Community mode only
17
+ disclosure = status.mandatory_disclosure
18
+ print(disclosure.text)
19
+ """
20
+
21
+ from .client import CIRISVerify, MockCIRISVerify
22
+ from .types import (
23
+ LicenseStatus,
24
+ LicenseTier,
25
+ LicenseDetails,
26
+ MandatoryDisclosure,
27
+ DisclosureSeverity,
28
+ LicenseStatusResponse,
29
+ CapabilityCheckResult,
30
+ FileIntegrityResult,
31
+ HardwareType,
32
+ ValidationStatus,
33
+ )
34
+ from .exceptions import (
35
+ CIRISVerifyError,
36
+ BinaryNotFoundError,
37
+ BinaryTamperedError,
38
+ VerificationFailedError,
39
+ TimeoutError,
40
+ CommunicationError,
41
+ )
42
+
43
+ __version__ = "0.1.0"
44
+ __all__ = [
45
+ "CIRISVerify",
46
+ "MockCIRISVerify",
47
+ "LicenseStatus",
48
+ "LicenseTier",
49
+ "LicenseDetails",
50
+ "MandatoryDisclosure",
51
+ "DisclosureSeverity",
52
+ "LicenseStatusResponse",
53
+ "CapabilityCheckResult",
54
+ "FileIntegrityResult",
55
+ "HardwareType",
56
+ "ValidationStatus",
57
+ "CIRISVerifyError",
58
+ "BinaryNotFoundError",
59
+ "BinaryTamperedError",
60
+ "VerificationFailedError",
61
+ "TimeoutError",
62
+ "CommunicationError",
63
+ ]