{"id":17272226,"url":"https://github.com/eumel8/cosignwebhook","last_synced_at":"2025-03-22T18:34:31.952Z","repository":{"id":72083359,"uuid":"583720399","full_name":"eumel8/cosignwebhook","owner":"eumel8","description":"Kubernetes Validation Admission Controller to verify Cosign signatures","archived":false,"fork":false,"pushed_at":"2025-03-12T23:18:58.000Z","size":19133,"stargazers_count":10,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-18T23:44:33.050Z","etag":null,"topics":["admission-webhook","cosign","kubernetes","signing","verify"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"giantswarm/grumpy","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eumel8.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2022-12-30T17:29:19.000Z","updated_at":"2025-03-12T23:17:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"baabc415-0854-4b7c-bd17-6745600b6f8c","html_url":"https://github.com/eumel8/cosignwebhook","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eumel8%2Fcosignwebhook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eumel8%2Fcosignwebhook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eumel8%2Fcosignwebhook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eumel8%2Fcosignwebhook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eumel8","download_url":"https://codeload.github.com/eumel8/cosignwebhook/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245003667,"owners_count":20545643,"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":["admission-webhook","cosign","kubernetes","signing","verify"],"created_at":"2024-10-15T08:48:09.449Z","updated_at":"2025-03-22T18:34:31.569Z","avatar_url":"https://github.com/eumel8.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Project Status: Active](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)\n[![Go Report Card](https://goreportcard.com/badge/github.com/eumel8/cosignwebhook)](https://goreportcard.com/report/github.com/eumel8/cosignwebhook)\n[![Release](https://img.shields.io/github/v/release/eumel8/cosignwebhook?display_name=tag)](https://github.com/eumel8/cosignwebhook/releases)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/78288de2f8eb403fa8249293b2155dca)](https://app.codacy.com/gh/eumel8/cosignwebhook/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_grade)\n\n[![Pipeline](https://github.com/eumel8/cosignwebhook/actions/workflows/gotest.yaml/badge.svg)](https://github.com/eumel8/cosignwebhook/actions/workflows/gotest.yaml)\n[![Pipeline](https://github.com/eumel8/cosignwebhook/actions/workflows/end2end.yaml/badge.svg)](https://github.com/eumel8/cosignwebhook/actions/workflows/end2end.yaml)\n[![Pipeline](https://github.com/eumel8/cosignwebhook/actions/workflows/build.yaml/badge.svg)]([https://github.com/eumel8/cosignwebhook/actions/workflows/build.yaml)\n[![Pipeline](https://github.com/eumel8/cosignwebhook/actions/workflows/trivy.yaml/badge.svg)]([https://github.com/eumel8/cosignwebhook/actions/workflows/trivy.yaml)\n\n# Cosign Webhook\n\nKubernetes Validation Admission Controller to verify Cosign Image signatures.\n\n\u003cimg src=\"cosignwebhook.png\" alt=\"cosignwebhook\" width=\"680\"/\u003e\n\nThis webhook watches for pod creation in deployments and verifies all container image it finds with an existing\nRSA public key (if present).\n\n# Installation with Helm\n\n```bash\nhelm -n cosignwebhook upgrade -i cosignwebhook oci://ghcr.io/eumel8/charts/cosignwebhook --versi\non 3.0.0 --create-namespace\n```\n\nthis installation has some advantages:\n\n* automatic generation of TLS key pair\n* automatic setup of ServiceMonitor and Grafana dashboards\n\nIf you use your own image, you'll have to sign it first. Don't forget to change the `cosign.scwebhook.key` value to your\npublic key, used to sign the image.\n\n# Installation with manifest\n\nAs cluster admin, create a namespace and install the admission controller:\n\n```bash\nkubectl create namespace cosignwebhook\nkubectl -n cosignwebhook apply -f manifests/rbac.yaml\nkubectl -n cosignwebhook apply -f manifests/manifest.yaml\n```\n\nThe manifest contains a self-signed example ca, TLS certificate, and key. This is only to see how it looks like, you\nshould generate your own certificate, see below:\n\n## Cert generation\n\nRun the generate-certs script in the `hack` folder to generate the TLS key pair and the CA certificate for the webhook:\n\n```bash\ngenerate-certs.sh --service cosignwebhook --webhook cosignwebhook --namespace cosignwebhook --secret cosignwebhook\n```\n\n## Validating your container images\n\nTo use the webhook, you need to first sign your images with `cosign`, and then use **one** of the following validation\npossibilities.\n\n- [Public key as environment variable](#public-key-as-environment-variable)\n- [Public key as secret reference](#public-key-as-secret-reference)\n- [Public key as default secret for namespace](#public-key-as-default-secret-for-namespace)\n\nAdditionally, if the signature of the image you're trying to validate **is not** in the same repository as the image,\nyou need to add the `COSIGN_REPOSITORY` environment variable to the environment of the container:\n\n```yaml\n# in the container spec of the workload\nenv:\n  - name: COSIGN_REPOSITORY\n    value: myregistry.io/signatures\n```\n\nThis option is similar to the `COSIGN_REPOSITORY` environment variable used with `cosign verify` and `cosign sign`\ncommand line tool and is used to specify the repository where the signature of the image is located, if it's not in the\nsame repository as the image.\n\n### Public key as environment variable\n\nAdd your Cosign public key as env var in container spec of the first container:\n\n```yaml\nenv:\n  - name: COSIGNPUBKEY\n    value: |\n      -----BEGIN PUBLIC KEY-----\n      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGOrnlJ1lFxAFTY2LF1vCuVHNZr9H\n      QryRDinn+JhPrDYR2wqCP+BUkeWja+RWrRdmskA0AffxBzaQrN/SwZI6fA==\n      -----END PUBLIC KEY-----\n```\n\n### Public key as secret reference\n\nInstead of hardcoding the public key in the deployment, you can also use a secret reference. The key and the secret may\nbe named freely, as long as the secret contains a valid public key.\n\n```yaml\napiVersion: v1\nkind: Secret\ndata:\n  COSIGNPUBKEY: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFS1BhWUhnZEVEQ3ltcGx5emlIdkJ5UjNxRkhZdgppaWxlMCtFMEtzVzFqWkhJa1p4UWN3aGsySjNqSm5VdTdmcjcrd05DeENkVEdYQmhBSTJveE1LbWx3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0t\nmetadata:\n  name: cosign_secret # Can be choosen freely\ntype: Opaque\n```\n\n```yaml\n        env:\n          - name: COSIGNPUBKEY\n            valueFrom:\n              secretKeyRef:\n                name: cosign_secret # Must be equal to metadata.name of the secrect\n                key: COSIGNPUBKEY\n```\n\n### Public key as default secret for namespace\n\nCreate a default secret for all your images in a namespace, which the webhook will always search for, when validating\nimages in this namespace:\n\n```yaml\napiVersion: v1\nkind: Secret\ndata:\n  COSIGNPUBKEY: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFS1BhWUhnZEVEQ3ltcGx5emlIdkJ5UjNxRkhZdgppaWxlMCtFMEtzVzFqWkhJa1p4UWN3aGsySjNqSm5VdTdmcjcrd05DeENkVEdYQmhBSTJveE1LbWx3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0t\nmetadata:\n  name: cosignwebhook\ntype: Opaque\n```\n\nThe name of the secret must be `cosignwebhook` and the key `COSIGNPUBKEY`. The value of `COSIGNPUBKEY` must match the\npublic key used to sign the image you're deploying.\n\n##     \n\n## Test\n\nTo test the webhook, you may run the following command(s):\n\n```bash\n# unit tests\nmake test-unit\n\n# E2E tests\nmake e2e-prep\nmake test-e2e\n```\n\n### E2E tests\n\nThe E2E tests require a running kubernetes cluster. Currently, the namespace and webhook are deployed via helper make\ntargets. To only run the tests, the following is required:\n\n* docker\n* cosign (v2)\n\nTo run the whole E2E tests, the following steps are required (in order):\n\n* create a k3d local cluster for the tests and a local iamge registry (`make e2e-cluster`)\n* signing keys are generated (`make e2e-keys`)\n* a new `cosignwebhook` image is build and signed with a temp key (`make e2e-images`)\n* the image is pushed to a local registry \u0026 deployed to the test cluster (`make e2e-deploy`)\n\nTo do all of the above, simply run `make e2e-prep`. Each step should also be able to be executed individually. To clean\nup the E2E setup, run `make e2e-cleanup`.\nThis will delete everything created by the E2E preparation. If you've already created the cluster and the keys, and\nyou're actively testing new code, you may run `make e2e-images e2e-deploy test-e2e` to test your changes.\n\nIn case you're running the tests on Apple devices, you may need to use deactivate the k3s dns fix (already implemented in the makefile). If your containers in the cluster don't start by skipping the fix, you may set `K3S_FIX_DNS` back to `1` in the `e2e-cluster` target.\n\n## Local build\n\n```bash\nCGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags \"-static\"' -o cosignwebhook\n```\n\n## Credits\n\n* Bruno Bressi \u003cbruno.bressi@telekom.de\u003e\n* Frank Kloeker \u003cf.kloeker@telekom.de\u003e\n\nLife is for sharing. If you have an issue with the code or want to improve it, feel free to open an issue or an pull\nrequest.\n\nThe Operator is inspired by [@pipo02mix](https://github.com/pipo02mix/grumpy), a good place\nto learn fundamental things about Admission Controllert\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feumel8%2Fcosignwebhook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feumel8%2Fcosignwebhook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feumel8%2Fcosignwebhook/lists"}