{"id":22923676,"url":"https://github.com/mithril-security/aicert","last_synced_at":"2025-06-21T21:34:48.095Z","repository":{"id":183501768,"uuid":"662018709","full_name":"mithril-security/aicert","owner":"mithril-security","description":null,"archived":false,"fork":false,"pushed_at":"2024-06-25T10:21:57.000Z","size":14498,"stargazers_count":15,"open_issues_count":3,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-12T23:14:20.405Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mithril-security.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-07-04T07:24:29.000Z","updated_at":"2025-05-09T10:31:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"bb715d92-8e16-49a5-8028-97112de44a92","html_url":"https://github.com/mithril-security/aicert","commit_stats":null,"previous_names":["mithril-security/aicert"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mithril-security/aicert","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mithril-security%2Faicert","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mithril-security%2Faicert/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mithril-security%2Faicert/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mithril-security%2Faicert/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mithril-security","download_url":"https://codeload.github.com/mithril-security/aicert/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mithril-security%2Faicert/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261197395,"owners_count":23123707,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-14T08:16:18.893Z","updated_at":"2025-06-21T21:34:43.081Z","avatar_url":"https://github.com/mithril-security.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca name=\"readme-top\"\u003e\u003c/a\u003e\n\n\u003c!-- [![Contributors][contributors-shield]][contributors-url]\n[![Forks][forks-shield]][forks-url]\n[![Stargazers][stars-shield]][stars-url]\n[![Issues][issues-shield]][issues-url]\n[![Apache License][license-shield]][license-url] --\u003e\n\n\n\u003c!-- PROJECT LOGO --\u003e\n\u003cbr /\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/mithril-security/aicert\"\u003e\n    \u003cimg src=\"https://github.com/mithril-security/blindai/raw/main/docs/assets/logo.png\" alt=\"Logo\" width=\"80\" height=\"80\"\u003e\n  \u003c/a\u003e\n\n\u003ch1 align=\"center\"\u003eAICert\u003c/h1\u003e\n\n[![Website][website-shield]][website-url]\n[![Blog][blog-shield]][blog-url]\n[![Docs][docs-shield]][docs-url]\n\u003c/div\u003e\n\n \u003cp align=\"center\"\u003e\n    \u003cb\u003eMaking AI Traceable and Transparent\u003c/b\u003e\u003cbr /\u003e\u003cbr /\u003e\n   \u003c!-- \n    \u003ca href=\"https://aicert.mithrilsecurity.io/en/latest\"\u003e\u003cstrong\u003eExplore the docs »\u003c/strong\u003e\u003c/a\u003e\n    \u003cbr /\u003e\n    \u003cbr /\u003e\n    \u003ca href=\"https://aicert.mithrilsecurity.io/en/latest/docs/getting-started/quick-tour/\"\u003eGet started\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/mithril-security/aicert/issues\"\u003eReport Bug\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/mithril-security/aicert/issues\"\u003eRequest Feature\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\u003c!-- TABLE OF CONTENTS --\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eTable of Contents\u003c/summary\u003e\n  \u003col\u003e\n    \u003cli\u003e\u003ca href=\"#-about-the-project\"\u003eAbout the project\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#-getting-started\"\u003eGetting started\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#-limitations\"\u003eLimitations\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#-contact\"\u003eContact\u003c/a\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/details\u003e\n\n## 🔒 About The Project\n\n🛠️ **AICert** aims to make AI **traceable** and **transparent** by enabling **AI builders** to create certificates with **cryptographic proofs binding the weights to the training data and code**. AI builders can be foundational model providers or companies that finetune the foundational models to their needs.\n\n👩‍💻 **End users** are the final consumers of the AI builders’ models. They can then verify these AI certificates to have proof that the model they talk to comes from a specific training set and code, and therefore **alleviates copyright, security and safety issues**.\n\n\u003c/br\u003e\n\n\u003cimg align=\"left\" src=\"https://github.com/mithril-security/aicert/blob/readme/docs/assets/TPM.png?raw=true\" width=\"110\" alt=\"TPM\"\u003e We leverage **Trusted Platform Modules (TPMs)** in order to attest the whole stack used for producing the model, from the UEFI, all the way to the code and data, through the OS. \n\nMeasuring the software stack, training code and inputs and binding them to the final weights allows the derivation of certificates that contain **irrefutable proof of model provenance**.\n\n\n### ✅ Use cases\n\nAICert addresses some of the most urgent concerns related to **AI provenance**. It allows AI builders to:\n\n+ Prove their AI model was not trained on copyrighted, biased or non-consensual PII data\n+ Provide an AI Bill of Material about the data and code used, which makes it harder to poison the model by injecting backdoors in the weights\n+ Provide a strong audit trail with irrefutable proof for compliance and transparency\n\n  ⚠️ **WARNING:** AICert is still under development. Do not use it in production!\n  If you want to contribute to this project, do not hesitate to raise an issue.\n\n### 🔍 Features\n\n+ **AI model traceability:** create AI model ID cards that provide cryptographic proof binding model weights to a specific training set and code\n+ **Non-forgeable proofs:** leverage TPMs to ensure non-forgeable AI model ID cards\n+ **Flexible training:** use your preferred tooling for training\n+ **No slowdown** induced during training\n+ **Azure support**\n\n\n## Workflow:\n\u003cimg align=\"center\" src=\"https://github.com/mithril-security/aicert/blob/main/docs/assets/aicert-axolotl.png?raw=true\" alt=\"Workflow\"\u003e\n\n\n## Verification of an AIBOM:\nOn successful finetuning of a model, an AIBOM is returned to the client. \n\nIt can be verified with the ```aicert verify``` command. The command verifies and prints out each component used in the fine-tuning, such as the model, dataset, compute used, fine-tuning configuration, etc.\n\n![](verify.gif)\n\n\n## Prerequisites\nTo run this example, you will need acess to an Azure subscription with quota for VMs with GPUs.\nInstall terraform and az cli. The client code requires python 3.11 or later.\n```bash\n# qemu-utils to resize disk to conform to azure disk specifications\nsudo apt-get update \u0026\u0026 sudo apt-get install qemu-utils tpm2-tools pesign jq\n# Azure CLI\ncurl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash\n# azcopy to copy disk to azure \nhttps://aka.ms/downloadazcopy-v10-linux\n# Install python 3.11\nsudo apt-get install python3.11\n# Install terraform\nwget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg\necho \"deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main\" | sudo tee /etc/apt/sources.list.d/hashicorp.list\nsudo apt update \u0026\u0026 sudo apt install terraform\n# Install earthly\nsudo /bin/sh -c 'wget https://github.com/earthly/earthly/releases/latest/download/earthly-linux-amd64 -O /usr/local/bin/earthly \u0026\u0026 chmod +x /usr/local/bin/earthly \u0026\u0026 /usr/local/bin/earthly bootstrap --with-autocomplete'\n# Install poetry\ncurl -sSL https://install.python-poetry.org | python3 -\n```\n\n## 1 - Configuration\nWe must first configure the Azure region and resource names before we begin creating the Mithril OS image.\n\nThe resource group name, gallery name and region can be set in the [upload_config.sh](upload_config.sh)\n```bash\nAZ_RESOURCE_GROUP=\"your-resource-group\"\nAZ_REGION=\"your-region\"\nGALLERY_NAME=\"your-gallery-name\"\n```\n\nThe size of the Azure VM can be set in [variables.tf](client/aicert/cli/deployment/deploy/variables.tf)\n```console\nvariable \"instance_type\" {\n  type        = string\n  default     = \"Standard_NC24ads_A100_v4\"\n  description = \"Type/Size of VM to create.\"\n}\n```\nThe default size is Standard_NC24ads_A100_v4\n\n## 2 - Preparing the image\nAIcert finetunes models inside Mithril OS enclaves.\nThe OS image packages the server, reverse proxy and axolotl container images within it.\n\nTo make subsequent finetunes easier, the OS disk only needs to be built once and uploaded to Azure.\n\nThe \"create_MithrilOS.sh\" script creates the disk, uploads it to Azure, and converts it into an OS image. It also generates the OS measurements.\n```bash\n# log in to Azure CLI\naz login\n\n# Create OS image\nsudo ./create_MithrilOS.sh\n```\n\n## 3 - Install the client\n```bash\ncd client\n# If your default python is below python3.10\npoetry env use python3.11\npoetry shell\npoetry install\n```\n\n### 3.1 - Copy measurements\nIf the client is run on a different machine than the one on which the OS was built, copy the following measurements to the client machine:\n+ `container_measurements.json`\n+ `measurements_azure.json`\n+ `measurements_qemu.json` (only required if the OS is being run locally for testing)\n\nPlace these files in the `security_config` folder in the client.\n\n## 4 - Finetune a model\nAIcert pefroms the following functions when the finetune command is run:\n- Creates a VM with the Mithril OS image\n- Connects to the server VM using aTLS\n- Sends the axolotl configuration in the aicert.yaml\n- Waits for the finetuned model and attestation report to be returned\n```bash\ncd axolotl_yaml\n# There is a sample axolotl configuration present in this folder named aicert.yaml\n# This specifies the model, dataset, and training parameters\naicert finetune\n```\n\nWe recommend placing each axolotl config in a dedicated folder so as not to overwrite the `attestation.json` (the AIBOM) returned after the finetuning during the next finetuning run.\n\n### 4.1 - Changes to the Axolotl configuration file\nWhen Axolotl runs the fine-tuning, the container has no connection to the outside and can not pull other models that those gathered at the initialization part. \nPining the model and dataset makes it possible to verify the versionning and track exactly which dataset and model were used on the procedure. \nSome changes must be taken into account when supplying an Axolotl configuration yaml. \n\n- The model name that is specified must be pinned to a specific version :\n  ```yaml\n  # example:\n  base_model: TinyLlama/TinyLlama-1.1B-intermediate-step-1431k-3T@sha1:036fa4651240b9a1487f709833b9e4b96b4c1574\n  ``` \n- The dataset name must also be pinned to a specific version and the relative path to the data must also be specified in name (This is due to Axolotl not being able to pull a dataset locally).\n  ```yaml\n  datasets:\n  - path: mhenrichsen/alpaca_2k_test@sha1:d05c1cb585e462b16532a44314aa4859cb7450c6\n    name: /alpaca_2000.parquet\n    type: alpaca\n  ```\nThese are the only changes that differs from a normal Axolotl configuration file. \n\n## 5 - Network policy\n\nWhile the network policy is part of the OS image, it is interesting to explore it further, as it is important for security and privacy. \n\nThe network policy that will be used will be included in the measurement of the OS. For instance, we will use the following one to allow data to be loaded inside the enclave, but nothing will leave it except the output of the AI model that will be sent back to the requester.\n\nThe network policy file can be found in the annex.\n\nThe measurement file contains the PCR values of the OS. A sample measurement file is as follows:\n```json\n{\n    \"measurements\": {\n        \"0\": \"f3a7e99a5f819a034386bce753a48a73cfdaa0bea0ecfc124bedbf5a8c4799be\",\n        \"1\": \"3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969\",\n        \"2\": \"3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969\",\n        \"3\": \"3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969\",\n        \"4\": \"dd2ccfebe24db4c43ed6913d3cbd7f700395a88679d3bb3519ab6bace1d064c0\",\n        \"12\": \"0000000000000000000000000000000000000000000000000000000000000000\",\n        \"13\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n    }\n}\n```\n\nTo understand better what it means, each PCR measures different parts of the stack:\nPCRs  0, 1, 2, and 3 are firmware related measurements.\nPCR 4 measures the UKI (initrd, kernel image, and boot stub)\nPCR 12 and 13 measure the kernel command line and system extensions. We do not want any of those to be enabled, so we ensure they are 0s.\n\n\n## Annex - Information on network Policy and Isolation\nThe network policy is implemented individually for the k3s pods as well as for the host.\nThe host network is controlled by iptables rules. The exact rules are:\n```\n*filter\n# Allow localhost connections to permit communication between k3s components\n-A INPUT -p tcp -s localhost -d localhost -j ACCEPT\n-A OUTPUT -p tcp -s localhost -d localhost -j ACCEPT\n# Allow connection to Azure IMDS to get the VM Instance userdata\n-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT\n-A OUTPUT -p tcp -d 169.254.169.254 --dport 80 -j ACCEPT\n-A OUTPUT -p tcp -d 168.63.129.16 --dport 80 -j ACCEPT\n# DNS over UDP\n-A INPUT -p udp --sport 53 -j ACCEPT\n-A INPUT -p udp --dport 53 -j ACCEPT\n-A OUTPUT -p udp --sport 53 -j ACCEPT\n-A OUTPUT -p udp --dport 53 -j ACCEPT\n# DNS over TCP\n-A INPUT -p tcp --sport 53 -j ACCEPT\n-A INPUT -p tcp --dport 53 -j ACCEPT\n-A OUTPUT -p tcp --sport 53 -j ACCEPT\n-A OUTPUT -p tcp --dport 53 -j ACCEPT\n# Drop all other traffic\n-A OUTPUT -j DROP\n-A INPUT -j DROP\nCOMMIT\n```\nIn the repository they can be found in [rules.v4](mithril-os/mkosi/rootfs/mkosi.extra/etc/iptables/rules.v4) and [rules.v6](mithril-os/mkosi/rootfs/mkosi.extra/etc/iptables/rules.v6)\n\nThese rules block all incoming and outgoing traffic except for DNS queries and localhost connections. The rules are applied on boot by the iptables-persistent package. You can verify that the package is installed if you take a look at the [mkosi.conf](mithril-os/mkosi/rootfs/mkosi.conf.j2) file.\n\nWhen the client tries to connect to the server it first retrieves the attestation report which is a quote from the TPM. The client uses the measurements stored in the `security_config` to validate the quote received from the TPM. \n\nIf there are any changes in the host networking rules, it will reflect in the PCR values (PCR 4) of the OS measurement and the connection will be terminated.\n\n## ⚠️ Limitations\n\nWhile we provide traceability and ensure that a given set of weights comes from applying a specific training code on a specific dataset, there are still challenges to solve:\n\n+ The training code and data have to be inspected. AICert does not audit the code or input data for threats, such as backdoors injected into a model by the code or poisonous data. It will simply allow us to prove model provenance. It is up to the AI community or end-user to inspect or prove the trustworthiness of the code and data. \n+ AICert itself has to be inspected, all the way from the OS we choose to the HTTP server and the app we provide to run the code on the training data.\n\nWe are well aware that AICert is not a silver bullet, as to have a fully trustworthy process, it requires scrutiny of both our code and the code and data of the AI builder.\n\nHowever, by combining both, we can have a solid foundation for the AI supply chain.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n## 📇 Contact\n\n[![Contact us][contact]][contact-url]\n[![Twitter][twitter]][website-url]\n[![LinkedIn][linkedin-shield]][linkedin-url]\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- MARKDOWN LINKS \u0026 IMAGES --\u003e\n\u003c!-- https://github.com/alexandresanlim/Badges4-README.md-Profile#-blog- --\u003e\n\u003c!-- [contributors-shield]: https://img.shields.io/github/contributors/mithril-security/aicert.svg?style=for-the-badge\n[contributors-url]: https://github.com/mithril-security/aicert/graphs/contributors\n[forks-shield]: https://img.shields.io/github/forks/mithril-security/aicert.svg?style=for-the-badge\n[forks-url]: https://github.com/mithril-security/blindbox/network/members\n[stars-shield]: https://img.shields.io/github/stars/mithril-security/aicert.svg?style=for-the-badge\n[stars-url]: https://github.com/mithril-security/blindbox/stargazers\n[issues-shield]: https://img.shields.io/github/issues/mithril-security/aicert.svg?style=for-the-badge\n\u003c!-- [issues-url]: https://github.com/mithril-security/aicert/issues --\u003e\n[project-url]: https://github.com/mithril-security/aicert\n[twitter-url]: https://twitter.com/MithrilSecurity\n[contact-url]: https://www.mithrilsecurity.io/contact\n[license-shield]: https://img.shields.io/github/license/mithril-security/aicert.svg?style=for-the-badge\n[contact]: https://img.shields.io/badge/Contact_us-000000?style=for-the-badge\u0026colorB=555\n[project]: https://img.shields.io/badge/Project-000000?style=for-the-badge\u0026colorB=555\n[license-url]: https://github.com/mithril-security/aicert/blob/master/LICENSE.txt\n[linkedin-shield]: https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge\u0026logo=linkedin\u0026logoColor=white\u0026colorB=555\n[twitter]: https://img.shields.io/badge/Twitter-1DA1F2?style=for-the-badge\u0026logo=twitter\u0026logoColor=white\n[linkedin-url]: https://www.linkedin.com/company/mithril-security-company/\n[website-url]: https://www.mithrilsecurity.io\n[website-shield]: https://img.shields.io/badge/website-000000?style=for-the-badge\u0026colorB=555\n[docs-url]: https://aicert.mithrilsecurity.io/en/latest/\n[docs-shield]: https://img.shields.io/readthedocs/aicert?style=for-the-badge\n[blog-url]: https://blog.mithrilsecurity.io/\n[blog-shield]: https://img.shields.io/badge/Blog-000?style=for-the-badge\u0026logo=ghost\u0026logoColor=yellow\u0026colorB=555\n[product-screenshot]: images/screenshot.png\n[Python]: https://img.shields.io/badge/Python-FFD43B?style=for-the-badge\u0026logo=python\u0026logoColor=blue\n[Python-url]: https://www.python.org/\n[Rust]: https://img.shields.io/badge/rust-FFD43B?style=for-the-badge\u0026logo=rust\u0026logoColor=black\n[Rust-url]: https://www.rust-lang.org/fr\n[Intel-SGX]: https://img.shields.io/badge/SGX-FFD43B?style=for-the-badge\u0026logo=intel\u0026logoColor=black\n[Intel-sgx-url]: https://www.intel.fr/content/www/fr/fr/architecture-and-technology/software-guard-extensions.html\n[Tract]: https://img.shields.io/badge/Tract-FFD43B?style=for-the-badge\n\u003c!-- [tract-url]: https://github.com/mithril-security/tract/tree/6e4620659837eebeaba40ab3eeda67d33a99c7cf --\u003e\n\u003c!-- Done using https://github.com/othneildrew/Best-README-Template --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmithril-security%2Faicert","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmithril-security%2Faicert","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmithril-security%2Faicert/lists"}