diff --git a/model_signing/sign_and_verify_model.ipynb b/model_signing/sign_and_verify_model.ipynb new file mode 100644 index 00000000..a6ac5201 --- /dev/null +++ b/model_signing/sign_and_verify_model.ipynb @@ -0,0 +1,279 @@ +{ + "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": 1, + "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": "37be5231-fde9-4bd3-83f3-333db57b7561", + "metadata": {}, + "source": [ + "## Sign function" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "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": 4, + "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=Yf-lZKDeMFe6X4_nKtA4XUEmWm6Z1l4H6TQiCkZHH6U&code_challenge_method=S256&state=a4383338-8b7a-497f-94f0-5e61be615a22&nonce=5cd82e7f-4896-438a-ab91-5f6e0c7afbcf\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Enter verification code: k7ezy7u6mhhemi3dm4tpxkjcy\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": 5, + "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": 6, + "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 +}