-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Jupyter Notebook to sign and verify a model
Signed-off-by: Ivan Font <ifont@redhat.com>
- Loading branch information
Showing
1 changed file
with
309 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,309 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "9ad01d5f-1703-41f5-a67c-cd4140576d63", | ||
"metadata": {}, | ||
"source": [ | ||
"# Sign and Verify Model" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "e3fb9a88-dbb5-4321-9a9d-7d96bd488eb1", | ||
"metadata": {}, | ||
"source": [ | ||
"## Install Python Dependencies for Linux" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 6, | ||
"id": "f289f36b-b90f-417e-b682-54dc13f3ca36", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"Defaulting to user installation because normal site-packages is not writeable\n", | ||
"Requirement already satisfied: annotated-types==0.6.0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 7)) (0.6.0)\n", | ||
"Requirement already satisfied: appdirs==1.4.4 in /usr/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 11)) (1.4.4)\n", | ||
"Requirement already satisfied: betterproto==2.0.0b6 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 15)) (2.0.0b6)\n", | ||
"Requirement already satisfied: certifi==2024.2.2 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 19)) (2024.2.2)\n", | ||
"Requirement already satisfied: cffi==1.16.0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 23)) (1.16.0)\n", | ||
"Requirement already satisfied: charset-normalizer==3.3.2 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 77)) (3.3.2)\n", | ||
"Requirement already satisfied: cryptography==42.0.5 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 169)) (42.0.5)\n", | ||
"Requirement already satisfied: dnspython==2.6.1 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 205)) (2.6.1)\n", | ||
"Requirement already satisfied: email-validator==2.1.1 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 209)) (2.1.1)\n", | ||
"Requirement already satisfied: grpclib==0.4.7 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 213)) (0.4.7)\n", | ||
"Requirement already satisfied: h2==4.1.0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 216)) (4.1.0)\n", | ||
"Requirement already satisfied: hpack==4.0.0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 220)) (4.0.0)\n", | ||
"Requirement already satisfied: hyperframe==6.0.1 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 224)) (6.0.1)\n", | ||
"Requirement already satisfied: id==1.4.0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 228)) (1.4.0)\n", | ||
"Requirement already satisfied: idna==3.7 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 232)) (3.7)\n", | ||
"Requirement already satisfied: markdown-it-py==3.0.0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 238)) (3.0.0)\n", | ||
"Requirement already satisfied: mdurl==0.1.2 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 242)) (0.1.2)\n", | ||
"Requirement already satisfied: multidict==6.0.5 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 246)) (6.0.5)\n", | ||
"Requirement already satisfied: psutil==5.9.8 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 338)) (5.9.8)\n", | ||
"Requirement already satisfied: pycparser==2.22 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 356)) (2.22)\n", | ||
"Requirement already satisfied: pydantic==2.7.1 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 360)) (2.7.1)\n", | ||
"Requirement already satisfied: pydantic-core==2.18.2 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 367)) (2.18.2)\n", | ||
"Requirement already satisfied: pygments==2.17.2 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 448)) (2.17.2)\n", | ||
"Requirement already satisfied: pyjwt==2.8.0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 452)) (2.8.0)\n", | ||
"Requirement already satisfied: pyopenssl==24.1.0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 456)) (24.1.0)\n", | ||
"Requirement already satisfied: python-dateutil==2.9.0.post0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 460)) (2.9.0.post0)\n", | ||
"Requirement already satisfied: requests==2.31.0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 464)) (2.31.0)\n", | ||
"Requirement already satisfied: rich==13.7.1 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 471)) (13.7.1)\n", | ||
"Requirement already satisfied: securesystemslib==0.31.0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 475)) (0.31.0)\n", | ||
"Requirement already satisfied: sigstore==2.1.5 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 481)) (2.1.5)\n", | ||
"Requirement already satisfied: sigstore-protobuf-specs==0.3.1 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 485)) (0.3.1)\n", | ||
"Requirement already satisfied: sigstore-rekor-types==0.0.11 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 489)) (0.0.11)\n", | ||
"Requirement already satisfied: six==1.16.0 in /usr/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 493)) (1.16.0)\n", | ||
"Requirement already satisfied: tuf==3.1.1 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 497)) (3.1.1)\n", | ||
"Requirement already satisfied: typing-extensions==4.11.0 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 501)) (4.11.0)\n", | ||
"Requirement already satisfied: urllib3==2.2.1 in /home/ifont/.local/lib/python3.11/site-packages (from -r install/requirements_Linux.txt (line 507)) (2.2.1)\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"!pip install --require-hashes -r install/requirements_Linux.txt" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "6a7c52c4-f338-4018-bdc6-5adf0d6c5305", | ||
"metadata": {}, | ||
"source": [ | ||
"## Confirm the model exists in the right directory" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 8, | ||
"id": "946f2097-042a-4133-ba3f-5902be4fc1e5", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"./models/:\n", | ||
"total 16K\n", | ||
"drwxr-xr-x. 1 ifont ifont 20 May 10 16:06 .\n", | ||
"drwxr-xr-x. 1 ifont ifont 278 May 10 16:24 ..\n", | ||
"-rw-r--r--. 1 ifont ifont 13K May 10 15:33 model.onnx\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"! ls -alRh ./models/" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "37be5231-fde9-4bd3-83f3-333db57b7561", | ||
"metadata": {}, | ||
"source": [ | ||
"## Sign function" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 13, | ||
"id": "ccc8d0d8-d749-40f9-92c9-6fcfa6fbc621", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from pathlib import Path\n", | ||
"import model\n", | ||
"\n", | ||
"def sign(modelfn: Path) -> model.SignatureResult:\n", | ||
" signer = model.SigstoreSigner()\n", | ||
" return signer.sign(modelfn, signature_path(modelfn),\n", | ||
" ignored_paths(modelfn))\n", | ||
"\n", | ||
"def signature_path(modelfn: Path) -> Path:\n", | ||
" if modelfn.is_file():\n", | ||
" return Path(modelfn.parent).joinpath(f\"{modelfn.name}.sig\")\n", | ||
" return modelfn.joinpath(\"model.sig\")\n", | ||
"\n", | ||
"\n", | ||
"def ignored_paths(modelfn: Path) -> [Path]:\n", | ||
" if modelfn.is_file():\n", | ||
" return []\n", | ||
" return [modelfn.joinpath(\".git\")]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "eaaafa7b-4179-4dda-8685-8398ebbb7256", | ||
"metadata": {}, | ||
"source": [ | ||
"## Sign the model" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 22, | ||
"id": "07ff3a23-9b88-45d8-ade8-fa13d7210b1f", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdin", | ||
"output_type": "stream", | ||
"text": [ | ||
"Path to model (e.g. ./models/model.onnx) ./models/model.onnx\n" | ||
] | ||
}, | ||
{ | ||
"name": "stderr", | ||
"output_type": "stream", | ||
"text": [ | ||
"Go to the following link in a browser:\n", | ||
"\n", | ||
"\thttps://oauth2.sigstore.dev/auth/auth?response_type=code&client_id=sigstore&client_secret=&scope=openid+email&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&code_challenge=dnwpMwMRjdg3LKdDWG4dgICExV_Gii05KJfj-pQFkaw&code_challenge_method=S256&state=5db93ac7-0d17-42eb-a7b5-2c0249c6d7f9&nonce=a1cfd65b-3f8a-4350-b733-3936d5d71163\n" | ||
] | ||
}, | ||
{ | ||
"name": "stdin", | ||
"output_type": "stream", | ||
"text": [ | ||
"Enter verification code: gvwo3szaoxty5ikjfg76uzaxe\n" | ||
] | ||
}, | ||
{ | ||
"name": "stderr", | ||
"output_type": "stream", | ||
"text": [ | ||
"identity-provider: https://oauth2.sigstore.dev/auth\n", | ||
"identity: ifont@redhat.com\n", | ||
"/home/ifont/.local/lib/python3.11/site-packages/sigstore/sign.py:141: CryptographyDeprecationWarning: Properties that return a naïve datetime object have been deprecated. Please switch to not_valid_after_utc.\n", | ||
" not_valid_after = self.__cached_signing_certificate.cert.not_valid_after\n" | ||
] | ||
}, | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"signature success\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"model_path = input(\"Path to model (e.g. ./models/model.onnx)\")\n", | ||
"modelfn = Path(model_path)\n", | ||
"result = sign(modelfn)\n", | ||
"if result:\n", | ||
" print(\"signature success\")\n", | ||
"else:\n", | ||
" print(f\"signature failure: {str(result)}\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "abf6b921-9376-482c-853a-e30388bf997e", | ||
"metadata": {}, | ||
"source": [ | ||
"## Verify function" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 23, | ||
"id": "51d6aba7-242d-4600-9268-f29f679fa2ab", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"def verify(modelfn: Path, issuer: str, identity: str,\n", | ||
" offline=False) -> model.VerificationResult:\n", | ||
" verifier = model.SigstoreVerifier(oidc_provider=issuer, identity=identity)\n", | ||
" return verifier.verify(modelfn, signature_path(modelfn),\n", | ||
" ignored_paths(modelfn), offline)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "67f80b2d-c716-4778-a42a-1ae2e94e09ca", | ||
"metadata": {}, | ||
"source": [ | ||
"## Verify the model" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 24, | ||
"id": "ab769b78-ee9b-4554-9bc3-ad963be72d56", | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdin", | ||
"output_type": "stream", | ||
"text": [ | ||
"Identity provider (e.g. https://accounts.google.com): https://accounts.google.com\n", | ||
"identity (e.g. mymail@gmail.com) ifont@redhat.com\n" | ||
] | ||
}, | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"verification success\n" | ||
] | ||
}, | ||
{ | ||
"name": "stderr", | ||
"output_type": "stream", | ||
"text": [ | ||
"/home/ifont/.local/lib/python3.11/site-packages/sigstore/verify/verifier.py:187: CryptographyDeprecationWarning: Properties that return a naïve datetime object have been deprecated. Please switch to not_valid_before_utc.\n", | ||
" sign_date = materials.certificate.not_valid_before\n", | ||
"/home/ifont/.local/lib/python3.11/site-packages/sigstore/verify/verifier.py:296: CryptographyDeprecationWarning: Properties that return a naïve datetime object have been deprecated. Please switch to not_valid_before_utc.\n", | ||
" materials.certificate.not_valid_before\n", | ||
"/home/ifont/.local/lib/python3.11/site-packages/sigstore/verify/verifier.py:298: CryptographyDeprecationWarning: Properties that return a naïve datetime object have been deprecated. Please switch to not_valid_after_utc.\n", | ||
" <= materials.certificate.not_valid_after\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"identity_provider = input(\"Identity provider (e.g. https://accounts.google.com):\")\n", | ||
"identity = input(\"identity (e.g. mymail@gmail.com)\")\n", | ||
"result = verify(modelfn=modelfn,\n", | ||
" issuer=identity_provider,\n", | ||
" identity=identity)\n", | ||
"if result:\n", | ||
" print(\"verification success\")\n", | ||
"else:\n", | ||
" print(f\"verification failure: {str(result)}\")\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "365ade63-9b6e-45a6-b1c9-ecf83a6fac0c", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3 (ipykernel)", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.11.8" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |