{"id":15290520,"url":"https://github.com/dentrax/cosigneth","last_synced_at":"2025-05-07T04:25:19.327Z","repository":{"id":64300648,"uuid":"466169697","full_name":"Dentrax/cosigneth","owner":"Dentrax","description":"Container Image Signing \u0026 Verifying on Ethereum [Testnet]","archived":false,"fork":false,"pushed_at":"2022-03-15T11:55:04.000Z","size":2016,"stargazers_count":17,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-19T18:31:06.448Z","etag":null,"topics":["container","container-image","cosign","dapp","docker","ecdsa","ethereum","signing","solidity"],"latest_commit_sha":null,"homepage":"https://cosigneth.dev","language":"TypeScript","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/Dentrax.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}},"created_at":"2022-03-04T15:14:34.000Z","updated_at":"2022-07-04T03:43:14.000Z","dependencies_parsed_at":"2023-01-15T09:31:09.407Z","dependency_job_id":null,"html_url":"https://github.com/Dentrax/cosigneth","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dentrax%2Fcosigneth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dentrax%2Fcosigneth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dentrax%2Fcosigneth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dentrax%2Fcosigneth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dentrax","download_url":"https://codeload.github.com/Dentrax/cosigneth/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252811785,"owners_count":21808012,"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":["container","container-image","cosign","dapp","docker","ecdsa","ethereum","signing","solidity"],"created_at":"2024-09-30T16:08:30.293Z","updated_at":"2025-05-07T04:25:19.305Z","avatar_url":"https://github.com/Dentrax.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003ca href=\"https://github.com/Dentrax/cosigneth\" target=\"_blank\"\u003e\u003cimg height=\"128\" src=\"https://raw.githubusercontent.com/Dentrax/cosigneth/main/.res/logo.png\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003e\u003ca href=\"https://cosigneth.dev\"\u003ecosigneth\u003c/a\u003e\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n \u003cstrong\u003e\n   An experimental decentralized application for storing and verifying container image signatures as an NFT on Ethereum\n \u003c/strong\u003e\n\u003c/div\u003e\n\n\u003cbr /\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://opensource.org/licenses/Apache-2\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-Apache-blue.svg?style=flat-square\" alt=\"MIT\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/Dentrax/cosigneth/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/release/Dentrax/cosigneth.svg?style=flat-square\" alt=\"GitHub release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/Dentrax/cosigneth/src/functions\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/Dentrax/cosigneth/src/functions?style=flat-square\" alt=\"Go Report\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://app.netlify.com/sites/cosigneth/deploys\"\u003e\u003cimg src=\"https://api.netlify.com/api/v1/badges/d843e41a-1308-472c-9feb-1e0d507234d4/deploy-status\" alt=\"Netlify\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cbr /\u003e\n\n*[cosigneth](https://cosigneth.dev)*, is a decentralized application that runs on Ethereum Rinkeby Testnet. Each signature stored as an NFT using [EIP-721](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md) standard. Sign your image digest using your public address and verify them on the blockchain by Solidity [contract](https://github.com/Dentrax/cosigneth/blob/main/src/contracts/Cosigneth.sol). Custom [serverless function](https://github.com/Dentrax/cosigneth/tree/main/src/functions) is created to interact with OCI registiries with your given [JWT token](https://docs.docker.com/registry/spec/auth/jwt).\nWe use [ethers.signMessage()](https://docs.ethers.io/v5/api/signer/#Signer-signMessage) to sign given [image digest](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests) using your injected wallet. By giving digest and corresponding signature, we can recover public wallet address by using [ECDSA-tryRecover](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol) method. See _Appendix F_ in [yellowpaper](https://ethereum.github.io/yellowpaper/paper.pdf) for more information.\n\n[![GIF](.res/preview.gif)](https://cosigneth.dev)\n\nActive contract: [0x1a0278c2402aa06d88a8d29c0cac8422e983bd55](https://rinkeby.etherscan.io/address/0x1a0278c2402aa06d88a8d29c0cac8422e983bd55#code#L1768)\n\n# How to use\n\n## Prerequisites\n\n* Injected Wallet ([Metamask](https://metamask.io), etc.)\n* An Ethereum wallet address\n* [Switch network](https://umbria.network/connect/ethereum-testnet-rinkeby) to Rinkeby\n* Request 0.1 test ETH from [Chainlink](https://faucets.chain.link) Faucet\n\n## Instructions\n\n### Signing\n\n1. Jump to https://cosigneth.dev\n2. Connect your wallet\n3. Create a registry token\n\n```bash\n$ curl -L -X POST 'https://auth.docker.io/token' \\\n-H 'Content-Type: application/x-www-form-urlencoded' \\\n--data-urlencode 'grant_type=password' \\\n--data-urlencode 'username=$USERNAME' \\\n--data-urlencode 'password=$PASSWORD' \\\n--data-urlencode 'service=registry.docker.io' \\\n--data-urlencode 'client_id=dockerengine' \\\n--data-urlencode 'access_type=offline' \\\n--data-urlencode 'scope=repository:$IMAGE:pull,push'\n```\n\n\u003e _Replace `$USERNAME`, `$PASSWORD` and `$IMAGE` with yours to [get an access token](https://docs.docker.com/registry/spec/auth/token) from Docker Registry v2 with `300`s expire duration. This is an example for Docker Registry._\n\n4. Pass your OCI _image reference_ and _token (Without Bearer)_\n5. Wait until image reference validation and signing process\n6. Done! Click the generated [Transaction Hash (Txn)](https://info.etherscan.com/what-is-a-transaction-hash-txhash) on the UI and jump to [Etherscan](https://etherscan.io/)\n\n### Verifying\n\n1. Jump to https://cosigneth.dev\n2. Connect your wallet\n3. Pass your OCI _image reference_ and _a public wallet address_\n4. Wait until fetching signature tags from registry API and verifying process on [EVM](https://ethereum.org/en/developers/docs/evm)\n5. Done! Check your verification result on the UI\n\n# How It Works?\n\n```mermaid\nsequenceDiagram\n    autonumber\n    \n\tFrontend-\u003e\u003eWeb3.js: Initialize Contract ABI\n\n    Frontend-\u003e\u003eWeb3.js: window.ethereum\n\tWeb3.js-\u003e\u003e+Wallet: Connect\n\n\tWallet--)-Frontend: Accounts\n\n\tNote over Frontend: Sign\n\n\trect rgba(0, 0, 255, .1)\n\t\t  Frontend-\u003e\u003e+Function: Image Check Prelight\n\t\t  Function--)-Frontend: Return Digest\n\t  \n\t\t  Frontend-\u003e\u003e+Web3.js: web3.eth.sign()\n\t\t  Web3.js--)-Frontend: Signature\n\t  \n\t\t  Frontend-\u003e\u003e+Ethereum: mint()\n\t\t  Ethereum--)-Frontend: Transaction Hash\n\t  \n\t\t  Frontend-\u003e\u003e+Function: Attach ETH Object to Image\n\t\t  Function--)-Frontend: Status Code\n\tend\n\n\tNote over Frontend: Verify\n\n\trect rgba(0, 255, 0, .1)\n\t\tFrontend-\u003e\u003e+Function: Get ETH Object\n\t\tFunction--)-Frontend: Signatures\n\n\t\tFrontend-\u003e\u003e+Ethereum: nft.methods.verify()\n\t\tEthereum--)-Frontend: Verify Result\n\tend\n```\n\n# Verify ETH Object\n\nYou can use [crane](https://github.com/google/go-containerregistry/tree/main/cmd/crane) to check your `.eth` tag:\n\n```bash\n$ crane ls furkanturkal/busybox\n0.2.0\nsha256-c734ddd2cee195855d0b5b1906afdf84b68940bc736fca03e2d05d2bd228ea9d.eth\n\n$ crane manifest furkanturkal/busybox:sha256-c734ddd2cee195855d0b5b1906afdf84b68940bc736fca03e2d05d2bd228ea9d.eth | jq\n```\n\nYou should expect the following output:\n\n```json\n{\n  \"schemaVersion\": 2,\n  \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n  \"config\": {\n    \"mediaType\": \"application/vnd.oci.image.config.v1+json\",\n    \"size\": 233,\n    \"digest\": \"sha256:0a151380f4116c9388e53fd6fae56e0769eaf539e6a5e67116a40f37a8e24f20\"\n  },\n  \"layers\": [\n    {\n      \"mediaType\": \"application/vnd.dev.cosign.simplesigning.v1+json\",\n      \"size\": 252,\n      \"digest\": \"sha256:4a9735466ab2e5ddf42968a8e283fc2232b04b8c3a93cb710a934d6307ea220f\",\n      \"annotations\": {\n        \"dev.cosignproject.cosign/blockchain\": \"Ethereum\",\n        \"dev.cosignproject.cosign/chainId\": \"4\",\n        \"dev.cosignproject.cosign/network\": \"rinkeby\",\n        \"dev.cosignproject.cosign/signature\": \"0x5c4d29575dbb038b12ee2cc49911a8418c243fd404b8c0dfd13e3a24de244c3d7b45e23521a880e6972df76305c662ace2b93006e09865a3e10194cb2bfb30731b\",\n        \"dev.cosignproject.cosign/signer\": \"0xd8f88dc38071f700ee5003ebfef73266cf16e5f1\",\n        \"dev.cosignproject.cosign/timestamp\": \"1647261544\",\n        \"dev.cosignproject.cosign/transaction\": \"0x3f09bbc6ada48c1233bf9f1167c427483234312f8ee907efaa9f91a618aef36f\"\n      }\n    }\n  ]\n}\n```\n\n# Motivation\n\nBecause, why not? NFTs are [trend topic](https://trends.google.com/trends/explore?q=nft) nowadays. This idea is a good opportunity to create a decentralized application from scratch. Building a website using Next.js with Material UI was a good experince. We learned to interact with the contract using Web3.js.\n\n# Running on Local\n\n## Web\n\n```bash\n$ cd src\n$ yarn install\n$ yarn dev\n```\n\n## Server\n\n```bash\n$ cd src/functions\n$ go run . -port 8080\n```\n\n# Known Issues\n\n* If transaction failed, we attach ETH object anyway. (not actually signed but it will look like that)\n* We haven't a resiliency mechanism in case we couldn't talk with Registry API. (actually signed but won't look like that)\n* Reverse proxy does not work well on localhost if you want to run local server.\n\n# Tech Stack\n\n## Frontend\n\n* [Next.js](https://github.com/vercel/next.js)\n* [Material UI](https://github.com/mui/material-ui)\n* [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)\n\n## Backend\n\n* [Ethereum](https://github.com/ethereum/go-ethereum)\n* [Solidity](https://github.com/ethereum/solidity) + [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts)\n* [Hardhat](https://github.com/NomicFoundation/hardhat)\n* [Go](https://github.com/golang/go)\n* [TypeScript](https://github.com/microsoft/TypeScript)\n* [cosign](https://github.com/sigstore/cosign)\n* [go-containerregistry](https://github.com/google/go-containerregistry)\n\n## Hosting\n\n* [Netlify](https://www.netlify.com)\n\n# License\n\nThe base project code is licensed under [Apache License 2.0](https://opensource.org/licenses/Apache-2.0) unless otherwise specified. Please see the **[LICENSE](https://github.com/Dentrax/cosigneth/blob/main/LICENSE)** file for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdentrax%2Fcosigneth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdentrax%2Fcosigneth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdentrax%2Fcosigneth/lists"}