modelsign 1.0.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 (39) hide show
  1. modelsign-1.0.0/.github/workflows/ci.yml +51 -0
  2. modelsign-1.0.0/.gitignore +6 -0
  3. modelsign-1.0.0/CHANGELOG.md +18 -0
  4. modelsign-1.0.0/LICENSE +21 -0
  5. modelsign-1.0.0/PKG-INFO +147 -0
  6. modelsign-1.0.0/README.md +119 -0
  7. modelsign-1.0.0/pyproject.toml +42 -0
  8. modelsign-1.0.0/setup.cfg +4 -0
  9. modelsign-1.0.0/src/modelsign/__init__.py +21 -0
  10. modelsign-1.0.0/src/modelsign/cli.py +402 -0
  11. modelsign-1.0.0/src/modelsign/crypto/__init__.py +23 -0
  12. modelsign-1.0.0/src/modelsign/crypto/keys.py +111 -0
  13. modelsign-1.0.0/src/modelsign/crypto/sign.py +28 -0
  14. modelsign-1.0.0/src/modelsign/crypto/verify.py +13 -0
  15. modelsign-1.0.0/src/modelsign/formats/__init__.py +6 -0
  16. modelsign-1.0.0/src/modelsign/formats/directory.py +33 -0
  17. modelsign-1.0.0/src/modelsign/formats/single.py +26 -0
  18. modelsign-1.0.0/src/modelsign/identity/__init__.py +6 -0
  19. modelsign-1.0.0/src/modelsign/identity/canonical.py +20 -0
  20. modelsign-1.0.0/src/modelsign/identity/card.py +71 -0
  21. modelsign-1.0.0/src/modelsign/middleware/__init__.py +5 -0
  22. modelsign-1.0.0/src/modelsign/middleware/response.py +42 -0
  23. modelsign-1.0.0/src/modelsign/sig.py +118 -0
  24. modelsign-1.0.0/src/modelsign.egg-info/PKG-INFO +147 -0
  25. modelsign-1.0.0/src/modelsign.egg-info/SOURCES.txt +37 -0
  26. modelsign-1.0.0/src/modelsign.egg-info/dependency_links.txt +1 -0
  27. modelsign-1.0.0/src/modelsign.egg-info/entry_points.txt +2 -0
  28. modelsign-1.0.0/src/modelsign.egg-info/requires.txt +11 -0
  29. modelsign-1.0.0/src/modelsign.egg-info/top_level.txt +1 -0
  30. modelsign-1.0.0/tests/conftest.py +45 -0
  31. modelsign-1.0.0/tests/test_canonical.py +83 -0
  32. modelsign-1.0.0/tests/test_card.py +98 -0
  33. modelsign-1.0.0/tests/test_cli.py +194 -0
  34. modelsign-1.0.0/tests/test_formats.py +60 -0
  35. modelsign-1.0.0/tests/test_integration.py +151 -0
  36. modelsign-1.0.0/tests/test_keys.py +74 -0
  37. modelsign-1.0.0/tests/test_middleware.py +53 -0
  38. modelsign-1.0.0/tests/test_sig.py +98 -0
  39. modelsign-1.0.0/tests/test_sign_verify.py +59 -0
@@ -0,0 +1,51 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.9", "3.11", "3.12", "3.13"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python ${{ matrix.python-version }}
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+
24
+ - name: Install dependencies
25
+ run: pip install -e ".[dev]"
26
+
27
+ - name: Run tests
28
+ run: pytest tests/ -v --tb=short
29
+
30
+ publish:
31
+ needs: test
32
+ runs-on: ubuntu-latest
33
+ if: startsWith(github.ref, 'refs/tags/v')
34
+ permissions:
35
+ id-token: write
36
+ steps:
37
+ - uses: actions/checkout@v4
38
+
39
+ - name: Set up Python
40
+ uses: actions/setup-python@v5
41
+ with:
42
+ python-version: "3.12"
43
+
44
+ - name: Install build tools
45
+ run: pip install build
46
+
47
+ - name: Build package
48
+ run: python -m build
49
+
50
+ - name: Publish to PyPI
51
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,6 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ dist/
4
+ build/
5
+ .mypy_cache/
6
+ *.pyc
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ ## v1.0.0 (2026-03-25)
4
+
5
+ Initial release.
6
+
7
+ ### Features
8
+
9
+ - **Ed25519 model signing** with domain-prefixed messages (`modelsign-v1:`)
10
+ - **Model Identity Card** — structured, signed metadata (architecture, base model, training, eval metrics, provenance)
11
+ - **RFC 8785 canonical JSON** for deterministic, cross-platform signature verification
12
+ - **Streaming SHA-256** for large model files (1MB chunks, no full-file memory load)
13
+ - **Directory support** — sign multi-file models with recursive manifests
14
+ - **TOFU keyring** — trust-on-first-use with persistent trusted key store
15
+ - **CLI commands**: `sign`, `verify`, `inspect`, `keygen`, `keyring`, `version`
16
+ - **Python SDK** — all modules independently importable
17
+ - **Response signing middleware** (optional) for API endpoint authenticity
18
+ - **Version migration policy** — forward-compatible .sig format with semver checks
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 QJ / ConstantOne (CIP1 LLC)
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,147 @@
1
+ Metadata-Version: 2.4
2
+ Name: modelsign
3
+ Version: 1.0.0
4
+ Summary: Sign AI models with identity. Verify anywhere.
5
+ Author-email: QJ <qj@constantone.ai>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/ConstantQJ/modelsign
8
+ Project-URL: Issues, https://github.com/ConstantQJ/modelsign/issues
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Security :: Cryptography
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Requires-Python: >=3.9
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: cryptography>=41.0
19
+ Requires-Dist: click>=8.0
20
+ Requires-Dist: rfc8785>=0.1.2
21
+ Provides-Extra: middleware
22
+ Requires-Dist: fastapi>=0.100; extra == "middleware"
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=7.0; extra == "dev"
25
+ Requires-Dist: pytest-cov; extra == "dev"
26
+ Requires-Dist: mypy; extra == "dev"
27
+ Dynamic: license-file
28
+
29
+ # modelsign
30
+
31
+ [![CI](https://github.com/QuantQJ/modelsign/actions/workflows/ci.yml/badge.svg)](https://github.com/QuantQJ/modelsign/actions/workflows/ci.yml)
32
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
33
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
34
+
35
+ Sign AI models with identity. Verify anywhere.
36
+
37
+ `modelsign` cryptographically binds model files to a signed identity card -- who made this model, what it's based on, what it claims to be. Ed25519 signatures, zero ML dependencies, works with any model format.
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ pip install modelsign
43
+ ```
44
+
45
+ ## Quick Start
46
+
47
+ ```bash
48
+ # Generate your signing key
49
+ modelsign keygen
50
+
51
+ # Sign a model with a name
52
+ modelsign sign model.safetensors --name "My-Llama-8B-v1"
53
+
54
+ # Verify it
55
+ modelsign verify model.safetensors
56
+
57
+ # Inspect the identity card
58
+ modelsign inspect model.safetensors.sig
59
+ ```
60
+
61
+ ## Rich Identity Cards
62
+
63
+ Sign with full provenance:
64
+
65
+ ```bash
66
+ # Create an identity card
67
+ cat > card.json << 'EOF'
68
+ {
69
+ "name": "Llama-3.1-8B-Chat-QJ",
70
+ "architecture": "LlamaForCausalLM",
71
+ "base_model": "meta-llama/Llama-3.1-8B-Instruct",
72
+ "version": "1.0.0",
73
+ "creator": "ConstantQJ",
74
+ "license": "Llama 3.1 Community",
75
+ "intended_use": "Chat assistant",
76
+ "training": {
77
+ "dataset": "custom-chat-v2",
78
+ "epochs": 3,
79
+ "hardware": "DGX Spark GB10"
80
+ },
81
+ "eval_metrics": {
82
+ "mmlu": 0.68,
83
+ "humaneval": 0.53
84
+ }
85
+ }
86
+ EOF
87
+
88
+ modelsign sign model.safetensors --identity card.json
89
+ ```
90
+
91
+ ## Python SDK
92
+
93
+ ```python
94
+ from modelsign import (
95
+ ModelCard, validate_card, canonical_json,
96
+ generate_keypair, load_private_key, load_public_key,
97
+ sign_bytes, build_file_message, verify_bytes,
98
+ hash_file, SigFile, write_sig, read_sig,
99
+ )
100
+ ```
101
+
102
+ ## What It Protects Against
103
+
104
+ - Post-signing **tampering** of model weights
105
+ - **Substitution** of one model for another
106
+ - **Metadata swap** (changing identity claims invalidates signature)
107
+
108
+ ## What It Does NOT Cover
109
+
110
+ - Key compromise (your key, your responsibility)
111
+ - Model safety, fairness, or legal compliance
112
+ - Cryptographic timestamping (timestamps are metadata, not proofs)
113
+
114
+ ## How It Compares
115
+
116
+ | | modelsign | OpenSSF Model Signing (OMS) |
117
+ |---|---|---|
118
+ | **Focus** | Simple signing + rich identity | Supply-chain integrity via Sigstore |
119
+ | **Identity card** | Embedded (architecture, training, eval metrics) | Minimal (being expanded) |
120
+ | **Setup** | `pip install modelsign` | Sigstore toolchain + transparency log |
121
+ | **Signing** | Offline, Ed25519, one command | Keyless via OIDC + Rekor transparency |
122
+ | **Best for** | Individual fine-tunes, HF uploads, quick sharing | Enterprise supply-chain, NGC publishing |
123
+ | **Network required** | No | Yes (Sigstore/Rekor) |
124
+
125
+ modelsign and OMS are **complementary**. Use modelsign for fast, offline, identity-rich signing. Use OMS when you need transparency logs and keyless verification at enterprise scale.
126
+
127
+ ## Identity Card Schema
128
+
129
+ | Field | Required | Description |
130
+ |---|---|---|
131
+ | `name` | Yes | Model name |
132
+ | `architecture` | No | Model class (e.g., `LlamaForCausalLM`) |
133
+ | `base_model` | No | Parent model name/path |
134
+ | `parent_signature` | No | Hash of parent's `.sig` (provenance chain) |
135
+ | `version` | No | Semantic version |
136
+ | `creator` | No | Person or organization |
137
+ | `license` | No | SPDX identifier or name |
138
+ | `intended_use` | No | What the model is for |
139
+ | `restrictions` | No | What it should NOT be used for |
140
+ | `training` | No | `{dataset, dataset_hash, epochs, hardware}` |
141
+ | `quantization` | No | Method (e.g., `GPTQ-4bit`) |
142
+ | `eval_metrics` | No | Benchmark results (`{mmlu: 0.68}`) |
143
+ | `extra` | No | Any additional metadata |
144
+
145
+ ## License
146
+
147
+ MIT — QJ / ConstantOne (CIP1 LLC)
@@ -0,0 +1,119 @@
1
+ # modelsign
2
+
3
+ [![CI](https://github.com/QuantQJ/modelsign/actions/workflows/ci.yml/badge.svg)](https://github.com/QuantQJ/modelsign/actions/workflows/ci.yml)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
6
+
7
+ Sign AI models with identity. Verify anywhere.
8
+
9
+ `modelsign` cryptographically binds model files to a signed identity card -- who made this model, what it's based on, what it claims to be. Ed25519 signatures, zero ML dependencies, works with any model format.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pip install modelsign
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # Generate your signing key
21
+ modelsign keygen
22
+
23
+ # Sign a model with a name
24
+ modelsign sign model.safetensors --name "My-Llama-8B-v1"
25
+
26
+ # Verify it
27
+ modelsign verify model.safetensors
28
+
29
+ # Inspect the identity card
30
+ modelsign inspect model.safetensors.sig
31
+ ```
32
+
33
+ ## Rich Identity Cards
34
+
35
+ Sign with full provenance:
36
+
37
+ ```bash
38
+ # Create an identity card
39
+ cat > card.json << 'EOF'
40
+ {
41
+ "name": "Llama-3.1-8B-Chat-QJ",
42
+ "architecture": "LlamaForCausalLM",
43
+ "base_model": "meta-llama/Llama-3.1-8B-Instruct",
44
+ "version": "1.0.0",
45
+ "creator": "ConstantQJ",
46
+ "license": "Llama 3.1 Community",
47
+ "intended_use": "Chat assistant",
48
+ "training": {
49
+ "dataset": "custom-chat-v2",
50
+ "epochs": 3,
51
+ "hardware": "DGX Spark GB10"
52
+ },
53
+ "eval_metrics": {
54
+ "mmlu": 0.68,
55
+ "humaneval": 0.53
56
+ }
57
+ }
58
+ EOF
59
+
60
+ modelsign sign model.safetensors --identity card.json
61
+ ```
62
+
63
+ ## Python SDK
64
+
65
+ ```python
66
+ from modelsign import (
67
+ ModelCard, validate_card, canonical_json,
68
+ generate_keypair, load_private_key, load_public_key,
69
+ sign_bytes, build_file_message, verify_bytes,
70
+ hash_file, SigFile, write_sig, read_sig,
71
+ )
72
+ ```
73
+
74
+ ## What It Protects Against
75
+
76
+ - Post-signing **tampering** of model weights
77
+ - **Substitution** of one model for another
78
+ - **Metadata swap** (changing identity claims invalidates signature)
79
+
80
+ ## What It Does NOT Cover
81
+
82
+ - Key compromise (your key, your responsibility)
83
+ - Model safety, fairness, or legal compliance
84
+ - Cryptographic timestamping (timestamps are metadata, not proofs)
85
+
86
+ ## How It Compares
87
+
88
+ | | modelsign | OpenSSF Model Signing (OMS) |
89
+ |---|---|---|
90
+ | **Focus** | Simple signing + rich identity | Supply-chain integrity via Sigstore |
91
+ | **Identity card** | Embedded (architecture, training, eval metrics) | Minimal (being expanded) |
92
+ | **Setup** | `pip install modelsign` | Sigstore toolchain + transparency log |
93
+ | **Signing** | Offline, Ed25519, one command | Keyless via OIDC + Rekor transparency |
94
+ | **Best for** | Individual fine-tunes, HF uploads, quick sharing | Enterprise supply-chain, NGC publishing |
95
+ | **Network required** | No | Yes (Sigstore/Rekor) |
96
+
97
+ modelsign and OMS are **complementary**. Use modelsign for fast, offline, identity-rich signing. Use OMS when you need transparency logs and keyless verification at enterprise scale.
98
+
99
+ ## Identity Card Schema
100
+
101
+ | Field | Required | Description |
102
+ |---|---|---|
103
+ | `name` | Yes | Model name |
104
+ | `architecture` | No | Model class (e.g., `LlamaForCausalLM`) |
105
+ | `base_model` | No | Parent model name/path |
106
+ | `parent_signature` | No | Hash of parent's `.sig` (provenance chain) |
107
+ | `version` | No | Semantic version |
108
+ | `creator` | No | Person or organization |
109
+ | `license` | No | SPDX identifier or name |
110
+ | `intended_use` | No | What the model is for |
111
+ | `restrictions` | No | What it should NOT be used for |
112
+ | `training` | No | `{dataset, dataset_hash, epochs, hardware}` |
113
+ | `quantization` | No | Method (e.g., `GPTQ-4bit`) |
114
+ | `eval_metrics` | No | Benchmark results (`{mmlu: 0.68}`) |
115
+ | `extra` | No | Any additional metadata |
116
+
117
+ ## License
118
+
119
+ MIT — QJ / ConstantOne (CIP1 LLC)
@@ -0,0 +1,42 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "setuptools-scm"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "modelsign"
7
+ version = "1.0.0"
8
+ description = "Sign AI models with identity. Verify anywhere."
9
+ authors = [{name = "QJ", email = "qj@constantone.ai"}]
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.9"
12
+ readme = "README.md"
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Programming Language :: Python :: 3",
18
+ "Topic :: Security :: Cryptography",
19
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
20
+ ]
21
+ dependencies = [
22
+ "cryptography>=41.0",
23
+ "click>=8.0",
24
+ "rfc8785>=0.1.2",
25
+ ]
26
+
27
+ [project.optional-dependencies]
28
+ middleware = ["fastapi>=0.100"]
29
+ dev = ["pytest>=7.0", "pytest-cov", "mypy"]
30
+
31
+ [project.scripts]
32
+ modelsign = "modelsign.cli:main"
33
+
34
+ [project.urls]
35
+ Homepage = "https://github.com/ConstantQJ/modelsign"
36
+ Issues = "https://github.com/ConstantQJ/modelsign/issues"
37
+
38
+ [tool.setuptools.packages.find]
39
+ where = ["src"]
40
+
41
+ [tool.pytest.ini_options]
42
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,21 @@
1
+ """modelsign — Sign AI models with identity. Verify anywhere."""
2
+
3
+ __version__ = "1.0.0"
4
+
5
+ from modelsign.identity.card import ModelCard, validate_card
6
+ from modelsign.identity.canonical import canonical_json
7
+ from modelsign.crypto.keys import generate_keypair, load_private_key, load_public_key, compute_fingerprint
8
+ from modelsign.crypto.sign import sign_bytes, build_file_message, build_dir_message
9
+ from modelsign.crypto.verify import verify_bytes
10
+ from modelsign.formats.single import hash_file
11
+ from modelsign.formats.directory import hash_directory
12
+ from modelsign.sig import SigFile, write_sig, read_sig
13
+
14
+ __all__ = [
15
+ "__version__",
16
+ "ModelCard", "validate_card", "canonical_json",
17
+ "generate_keypair", "load_private_key", "load_public_key", "compute_fingerprint",
18
+ "sign_bytes", "build_file_message", "build_dir_message", "verify_bytes",
19
+ "hash_file", "hash_directory",
20
+ "SigFile", "write_sig", "read_sig",
21
+ ]