{"id":13390432,"url":"https://github.com/controlplaneio/kubesec-webhook","last_synced_at":"2025-05-12T08:31:49.768Z","repository":{"id":54806273,"uuid":"142763343","full_name":"controlplaneio/kubesec-webhook","owner":"controlplaneio","description":"Security risk analysis for Kubernetes resources","archived":false,"fork":false,"pushed_at":"2023-11-28T12:37:01.000Z","size":3043,"stargazers_count":74,"open_issues_count":9,"forks_count":19,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-10-29T16:58:41.442Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://kubesec.io","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/controlplaneio.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}},"created_at":"2018-07-29T13:29:58.000Z","updated_at":"2024-09-27T11:43:25.000Z","dependencies_parsed_at":"2024-01-18T09:04:32.228Z","dependency_job_id":"bbec4e0a-43ff-40bb-b188-d959be191002","html_url":"https://github.com/controlplaneio/kubesec-webhook","commit_stats":{"total_commits":32,"total_committers":8,"mean_commits":4.0,"dds":0.40625,"last_synced_commit":"2ef104ce63bd0f2d0023f0f337f853d1a8e34aec"},"previous_names":["stefanprodan/kubesec-webhook"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/controlplaneio%2Fkubesec-webhook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/controlplaneio%2Fkubesec-webhook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/controlplaneio%2Fkubesec-webhook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/controlplaneio%2Fkubesec-webhook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/controlplaneio","download_url":"https://codeload.github.com/controlplaneio/kubesec-webhook/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224862940,"owners_count":17382284,"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-07-30T14:01:00.347Z","updated_at":"2024-11-18T04:47:39.677Z","avatar_url":"https://github.com/controlplaneio.png","language":"Go","funding_links":[],"categories":["Operators vs Controllers"],"sub_categories":["Admission"],"readme":"# kubesec-webhook\n\n[![Build Status](https://travis-ci.org/controlplaneio/kubesec-webhook.svg?branch=master)](https://travis-ci.org/controlplaneio/kubesec-webhook)\n\nKubesec.io admission controller for Kubernetes Pods, Deployments,\nDaemonSets and StatefulSets.\n\nFor the kubectl scan plugin see [kubectl-kubesec](https://github.com/controlplaneio/kubectl-kubesec)\n\n## Install\n\nGenerate webhook configuration files with a new TLS certificate and CA Bundle:\n\n```bash\nmake certs\n```\n\nDeploy the admission controller and webhooks in the kubesec namespace (requires Kubernetes 1.20 or newer):\n\n```bash\nmake deploy\n```\n\nEnable Kubesec validation by adding this label:\n\n```bash\nkubectl label namespaces default kubesec-validation=enabled\n```\n\n## Usage\n\nTry to apply a privileged Deployment:\n\n```bash\nkubectl apply -f ./test/deployment.yaml\n\nError from server (InternalError): error when creating \"./test/deployment.yaml\":\nInternal error occurred: admission webhook \"deployment.admission.kubesec.io\" denied the request:\ndeployment-test score is -30, deployment minimum accepted score is 0\nScan Result:\n{\n  \"error\": \"\",\n  \"score\": -30,\n  \"scoring\": {\n    \"critical\": [\n      {\n        \"selector\": \"containers[] .securityContext .privileged == true\",\n        \"reason\": \"Privileged containers can allow almost completely unrestricted host access\",\n        \"weight\": 0\n      }\n    ],\n    \"advise\": [\n      {\n        \"selector\": \"containers[] .securityContext .runAsNonRoot == true\",\n        \"reason\": \"Force the running image to run as a non-root user to ensure least privilege\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .capabilities .drop\",\n        \"reason\": \"Reducing kernel capabilities available to a container limits its attack surface\",\n        \"href\": \"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .readOnlyRootFilesystem == true\",\n        \"reason\": \"An immutable root filesystem can prevent malicious binaries being added to\nPATH and increase attack cost\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .runAsUser \\u003e 10000\",\n        \"reason\": \"Run as a high-UID user to avoid conflicts with the host's user table\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .capabilities .drop | index(\\\"ALL\\\")\",\n        \"reason\": \"Drop all capabilities and add only those required to reduce syscall attack surface\"\n      }\n    ]\n  }\n}\n```\n\nTry to apply a privileged DaemonSet:\n\n```bash\nkubectl apply -f ./test/daemonset.yaml\n\nError from server (InternalError): error when creating \"./test/daemonset.yaml\":\nInternal error occurred: admission webhook \"daemonset.admission.kubesec.io\" denied the request:\ndaemonset-test score is -30, daemonset minimum accepted score is 0\nScan Result:\n{\n  \"error\": \"\",\n  \"score\": -30,\n  \"scoring\": {\n    \"critical\": [\n      {\n        \"selector\": \"containers[] .securityContext .privileged == true\",\n        \"reason\": \"Privileged containers can allow almost completely unrestricted host access\",\n        \"weight\": 0\n      }\n    ],\n    \"advise\": [\n      {\n        \"selector\": \"containers[] .securityContext .runAsNonRoot == true\",\n        \"reason\": \"Force the running image to run as a non-root user to ensure least privilege\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .capabilities .drop\",\n        \"reason\": \"Reducing kernel capabilities available to a container limits its attack surface\",\n        \"href\": \"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .readOnlyRootFilesystem == true\",\n        \"reason\": \"An immutable root filesystem can prevent malicious binaries being added to PATH and increase attack cost\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .runAsUser \\u003e 10000\",\n        \"reason\": \"Run as a high-UID user to avoid conflicts with the host's user table\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .capabilities .drop | index(\\\"ALL\\\")\",\n        \"reason\": \"Drop all capabilities and add only those required to reduce syscall attack surface\"\n      }\n    ]\n  }\n}\n```\n\nTry to apply a privileged StatefulSet:\n\n```bash\nkubectl apply -f ./test/statefulset.yaml\n\nError from server (InternalError): error when creating \"./test/statefulset.yaml\":\nInternal error occurred: admission webhook \"statefulset.admission.kubesec.io\" denied the request:\nstatefulset-test score is -30, statefulset minimum accepted score is 0\nScan Result:\n{\n  \"error\": \"\",\n  \"score\": -30,\n  \"scoring\": {\n    \"critical\": [\n      {\n        \"selector\": \"containers[] .securityContext .privileged == true\",\n        \"reason\": \"Privileged containers can allow almost completely unrestricted host access\",\n        \"weight\": 0\n      }\n    ],\n    \"advise\": [\n      {\n        \"selector\": \".spec .volumeClaimTemplates[] .spec .accessModes | index(\\\"ReadWriteOnce\\\")\",\n        \"reason\": \"\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .runAsNonRoot == true\",\n        \"reason\": \"Force the running image to run as a non-root user to ensure least privilege\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .capabilities .drop\",\n        \"reason\": \"Reducing kernel capabilities available to a container limits its attack surface\",\n        \"href\": \"https://kubernetes.io/docs/tasks/configure-pod-container/security-context/\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .readOnlyRootFilesystem == true\",\n        \"reason\": \"An immutable root filesystem can prevent malicious binaries being added to\nPATH and increase attack cost\"\n      },\n      {\n        \"selector\": \"containers[] .securityContext .runAsUser \\u003e 10000\",\n        \"reason\": \"Run as a high-UID user to avoid conflicts with the host's user table\"\n      }\n    ]\n  }\n}\n```\n\n## Configuration\n\nYou can set the minimum Kubesec.io score in `./deploy/webhook/yaml`:\n\n```yaml\napiVersion: apps/v1beta1\nkind: Deployment\nmetadata:\n  name: kubesec-webhook\n  labels:\n    app: kubesec-webhook\nspec:\n  replicas: 1\n  template:\n    metadata:\n      labels:\n        app: kubesec-webhook\n      annotations:\n        prometheus.io/scrape: \"true\"\n        prometheus.io/port: \"8081\"\n    spec:\n      containers:\n        - name: kubesec-webhook\n          image: controlplaneio/kubesec:0.1-dev\n          imagePullPolicy: Always\n          command:\n            - ./kubesec\n          args:\n            - -tls-cert-file=/etc/webhook/certs/cert.pem\n            - -tls-key-file=/etc/webhook/certs/key.pem\n            - -min-score=0\n          ports:\n            - containerPort: 8080\n            - containerPort: 8081\n          volumeMounts:\n            - name: webhook-certs\n              mountPath: /etc/webhook/certs\n              readOnly: true\n      volumes:\n        - name: webhook-certs\n          secret:\n            secretName: kubesec-webhook-certs\n```\n\n## Monitoring\n\nThe admission controller exposes Prometheus RED metrics for each webhook a\nGrafana dashboard is available [here](https://grafana.com/dashboards/7088).\n\n### Credits\n\nKudos to [Xabier](https://github.com/slok) for the awesome [kubewebhook library](https://github.com/slok/kubewebhook).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontrolplaneio%2Fkubesec-webhook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcontrolplaneio%2Fkubesec-webhook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontrolplaneio%2Fkubesec-webhook/lists"}