{"id":26786170,"url":"https://github.com/derekahn/klint","last_synced_at":"2025-10-06T04:25:05.586Z","repository":{"id":77593171,"uuid":"454519784","full_name":"derekahn/klint","owner":"derekahn","description":"Suite of kubernetes CLI tools to lint and validate","archived":false,"fork":false,"pushed_at":"2022-02-01T20:47:50.000Z","size":5,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T11:36:00.383Z","etag":null,"topics":["helm","k8s","kube-score","kubectl","kubernetes","kubesec","kubeval","kustomize","linter","validation"],"latest_commit_sha":null,"homepage":"","language":"Dockerfile","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/derekahn.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}},"created_at":"2022-02-01T19:19:10.000Z","updated_at":"2022-02-01T22:42:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"b9ef1c7c-f14e-4233-a7fb-8cb8f1e90f02","html_url":"https://github.com/derekahn/klint","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/derekahn/klint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derekahn%2Fklint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derekahn%2Fklint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derekahn%2Fklint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derekahn%2Fklint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/derekahn","download_url":"https://codeload.github.com/derekahn/klint/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derekahn%2Fklint/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273122138,"owners_count":25049539,"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","status":"online","status_checked_at":"2025-09-01T02:00:09.058Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["helm","k8s","kube-score","kubectl","kubernetes","kubesec","kubeval","kustomize","linter","validation"],"created_at":"2025-03-29T11:35:53.743Z","updated_at":"2025-10-06T04:25:00.553Z","avatar_url":"https://github.com/derekahn.png","language":"Dockerfile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# klint 🧹\n\n[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)\n\nA consolidated suite of kubernetes tools in a single container.\n\nThis is a portable solution to validate ☸️ manifests anywhere with a container runtime; local machine, CI, etc.\n\n## Reminders 🎗\n\n- The container is set with the permissions `nobody:nobody`\n- The container's **workspace** is set to `/src`\n- The container doesn't have `curl`, but it has `wget`\n- Any vulnerabilities are not my own; see tools 🔧\n\n## Tools 🔧\n\nThis swiss army knife stands on the shoulders of giants:\n\n| Name                                                      | Version   | License                                                                        | Description                                                                           |\n| --------------------------------------------------------- | --------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- |\n| [helm](https://github.com/helm/helm)                      | `v3.7`    | [Apache 2.0](https://github.com/helm/helm/blob/main/LICENSE)                   | The Kubernetes Package Manager                                                        |\n| [kubectl](https://github.com/kubernetes/kubectl)          | `v1.23.3` | [Apache 2.0](https://github.com/kubernetes/kubectl/blob/master/LICENSE)        | The designated kubernetes CLI client                                                  |\n| [kubesec](https://github.com/controlplaneio/kubesec)      | `v2.11.4` | [Apache 2.0](https://github.com/controlplaneio/kubesec/blob/master/LICENSE)    | Security risk analysis for Kubernetes resources                                       |\n| [kubeval](https://github.com/instrumenta/kubeval)         | `v0.15.0` | [Apache 2.0](https://github.com/instrumenta/kubeval/blob/master/LICENSE)       | Validate your Kubernetes configuration files, supports multiple Kubernetes versions   |\n| [kube-score](https://github.com/zegl/kube-score)          | `v1.13.0` | [Apache 2.0](https://github.com/zegl/kube-score/blob/master/LICENSE)           | Kubernetes object analysis with recommendations for improved reliability and security |\n| [kustomize](https://github.com/kubernetes-sigs/kustomize) | `v4.4.1`  | [Apache 2.0](https://github.com/kubernetes-sigs/kustomize/blob/master/LICENSE) | Customization of kubernetes YAML configurations                                       |\n\n## Usage 🐳\n\nFor local usage... first spin up the container\n\n```BASH\n$ docker run --rm -it -v `pwd`:/src derekahn/klint\n```\n\n### Kubescore\n\n##### Example Usage\n\n```bash\n/src $ kube-score score *.yaml\n```\n\n##### Example Output\n\n```bsh\napps/v1/Deployment my-app in awesome                                    💥\n  [CRITICAL] Pod Probes\n    · Container has the same readiness and liveness probe\n        Using the same probe for liveness and readiness is very likely dangerous. Generally it's better to avoid\n        the livenessProbe than re-using the readinessProbe.\n        More information: https://github.com/zegl/kube-score/blob/master/README_PROBES.md\n  [CRITICAL] Container Resources\n    · scala-sample -\u003e CPU limit is not set\n        Resource limits are recommended to avoid resource DDOS. Set resources.limits.cpu\n    · scala-sample -\u003e Memory limit is not set\n        Resource limits are recommended to avoid resource DDOS. Set resources.limits.memory\n    · scala-sample -\u003e CPU request is not set\n        Resource requests are recommended to make sure that the application can start and run without crashing.\n        Set resources.requests.cpu\n    · scala-sample -\u003e Memory request is not set\n        Resource requests are recommended to make sure that the application can start and run without crashing.\n        Set resources.requests.memory\n  [CRITICAL] Container Image Tag\n    · scala-sample -\u003e Image with latest tag\n        Using a fixed tag is recommended to avoid accidental upgrades\n  [CRITICAL] Pod NetworkPolicy\n    · The pod does not have a matching NetworkPolicy\n        Create a NetworkPolicy that targets this pod to control who/what can communicate with this pod. Note, this\n        feature needs to be supported by the CNI implementation used in the Kubernetes cluster to have an effect.\n  [CRITICAL] Deployment has PodDisruptionBudget\n    · No matching PodDisruptionBudget was found\n        It's recommended to define a PodDisruptionBudget to avoid unexpected downtime during Kubernetes\n        maintenance operations, such as when draining a node.\n  [WARNING] Deployment has host PodAntiAffinity\n    · Deployment does not have a host podAntiAffinity set\n        It's recommended to set a podAntiAffinity that stops multiple pods from a deployment from being scheduled\n        on the same node. This increases availability in case the node becomes unavailable.\nv1/Service my-app in awesome                                        ✅\n```\n\n### Kubeval\n\n##### Example Usage\n\n```bash\n/src $ kube-score score *.yaml\n```\n\n##### Example Output\n\n```bash\nPASS - my-app-deply.yaml contains a valid Deployment (awesome.my-app)\nPASS - my-app-svc.yaml contains a valid Service (awesome.my-app-svc)\n```\n\n### Kubesec\n\n##### Example Usage\n\n```bash\n/src $ kubesec scan my-app-deploy.yaml\n```\n\n##### Example Output\n\n```bash\n[\n  {\n    \"object\": \"Deployment/my-app.awesome\",\n    \"valid\": true,\n    \"fileName\": \"my-app-deploy.yaml\",\n    \"message\": \"Passed with a score of 5 points\",\n    \"score\": 5,\n    \"scoring\": {\n      \"passed\": [\n        {\n          \"id\": \"CapDropAny\",\n          \"selector\": \"containers[] .securityContext .capabilities .drop\",\n          \"reason\": \"Reducing kernel capabilities available to a container limits its attack surface\",\n          \"points\": 1\n        },\n        {\n          \"id\": \"CapDropAll\",\n          \"selector\": \"containers[] .securityContext .capabilities .drop | index(\\\"ALL\\\")\",\n          \"reason\": \"Drop all capabilities and add only those required to reduce syscall attack surface\",\n          \"points\": 1\n        },\n        {\n          \"id\": \"ReadOnlyRootFilesystem\",\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          \"points\": 1\n        },\n        {\n          \"id\": \"RunAsNonRoot\",\n          \"selector\": \"containers[] .securityContext .runAsNonRoot == true\",\n          \"reason\": \"Force the running image to run as a non-root user to ensure least privilege\",\n          \"points\": 1\n        },\n        {\n          \"id\": \"RunAsUser\",\n          \"selector\": \"containers[] .securityContext .runAsUser -gt 10000\",\n          \"reason\": \"Run as a high-UID user to avoid conflicts with the host's user table\",\n          \"points\": 1\n        }\n      ],\n      \"advise\": [\n        {\n          \"id\": \"ApparmorAny\",\n          \"selector\": \".metadata .annotations .\\\"container.apparmor.security.beta.kubernetes.io/nginx\\\"\",\n          \"reason\": \"Well defined AppArmor policies may provide greater protection from unknown threats. WARNING: NOT PRODUCTION READY\",\n          \"points\": 3\n        },\n        {\n          \"id\": \"ServiceAccountName\",\n          \"selector\": \".spec .serviceAccountName\",\n          \"reason\": \"Service accounts restrict Kubernetes API access and should be configured with least privilege\",\n          \"points\": 3\n        },\n        {\n          \"id\": \"SeccompAny\",\n          \"selector\": \".metadata .annotations .\\\"container.seccomp.security.alpha.kubernetes.io/pod\\\"\",\n          \"reason\": \"Seccomp profiles set minimum privilege and secure against unknown threats\",\n          \"points\": 1\n        },\n      ]\n    }\n  }\n]\n```\n\n### Kustomize\n\n```\n/src $ kustomize build overlays/development/\napiVersion: v1\nkind: Namespace\nmetadata:\n  annotations:\n    kube-score/ignore: pod-networkpolicy,deployment-has-host-podantiaffinity,container-security-context,deployment-has-poddisruptionbudget\n  name: awesome\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  annotations:\n    kube-score/ignore: pod-networkpolicy,deployment-has-host-podantiaffinity,container-security-context,deployment-has-poddisruptionbudget\n  labels:\n    app: my-app\n  name: my-app\n  namespace: awesome\nspec:\n  selector:\n    matchLabels:\n      app: my-app\n  template:\n    metadata:\n      annotations:\n        kube-score/ignore: pod-networkpolicy,deployment-has-host-podantiaffinity,container-security-context,deployment-has-poddisruptionbudget\n      labels:\n        app: my-app\n    spec:\n      containers:\n      - image: k8s:5000/my-app\n        imagePullPolicy: Always\n        name: my-app\n        ports:\n        - containerPort: 5000\n        resources:\n          limits:\n            cpu: 1\n            memory: 2048Mi\n          requests:\n            cpu: 1\n            memory: 512Mi\n```\n\n## Continuous Integration\n\nThese are just simple examples of plugging this into your CI\n\n### Github Actions\n\n```yaml\njobs:\n  container:\n    runs-on: ubuntu-latest\n    container: derekahn/klint:latest\n    steps:\n      - run: |\n          kubeval *.yaml\n        name: Run in container\n```\n\n### Jenkins example using Docker agents\n\n`Jenkinsfile`\n\n```jenkinsfile\npipeline {\n  agent {\n    docker { image 'derekahn/klint:latest' }\n  }\n\n  stages {\n    stage('lint') {\n      steps {\n        sh 'kubeval *.yaml'\n      }\n    }\n    stage('validate') {\n      steps {\n        sh 'kube-score score *.yaml'\n      }\n    }\n    stage('security scan') {\n      steps {\n        sh 'kubeval *.yaml'\n      }\n    }\n  }\n}\n```\n\n### Drone\n\n`.drone.yml`\n\n```yaml\nkind: pipeline\nname: k8s validations\n\nsteps:\n  - name: lint\n    image: derekahn/klint:latest\n    commands:\n      - kubeval score *.yaml\n  - name: validate\n    image: derekahn/klint:latest\n    commands:\n      - kube-score score *.yaml\n  - name: scan\n    image: derekahn/klint:latest\n    commands:\n      - kubesec scan *.yaml\n```\n\n### Circle-CI\n\n`.circleci/config.yml`\n\n```yaml\nversion: 2.0\njobs:\n  build:\n    docker:\n      - image: derekahn/klint:latest\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fderekahn%2Fklint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fderekahn%2Fklint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fderekahn%2Fklint/lists"}