{"id":13521362,"url":"https://github.com/undistro/marvin","last_synced_at":"2025-10-16T10:59:45.345Z","repository":{"id":154830953,"uuid":"601633043","full_name":"undistro/marvin","owner":"undistro","description":"Marvin is a CLI tool that scans a k8s cluster by performing CEL expressions to report potential issues, misconfigurations and vulnerabilities.","archived":false,"fork":false,"pushed_at":"2024-08-08T14:35:49.000Z","size":538,"stargazers_count":163,"open_issues_count":10,"forks_count":5,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-08-08T23:04:25.263Z","etag":null,"topics":["cel","cli","golang","kubernetes","scan"],"latest_commit_sha":null,"homepage":"https://undistro.io/marvin/","language":"Go","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/undistro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2023-02-14T13:43:06.000Z","updated_at":"2024-08-08T14:35:50.000Z","dependencies_parsed_at":"2024-01-13T22:23:33.941Z","dependency_job_id":"3d454402-e9d1-4803-939b-c6fdad856339","html_url":"https://github.com/undistro/marvin","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/undistro%2Fmarvin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/undistro%2Fmarvin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/undistro%2Fmarvin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/undistro%2Fmarvin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/undistro","download_url":"https://codeload.github.com/undistro/marvin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246535878,"owners_count":20793343,"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":["cel","cli","golang","kubernetes","scan"],"created_at":"2024-08-01T06:00:33.329Z","updated_at":"2025-10-16T10:59:40.293Z","avatar_url":"https://github.com/undistro.png","language":"Go","funding_links":[],"categories":["Kubernetes cluster security","Go","Configuration Management"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"assets/banner-dark.png\"\u003e\n  \u003cimg alt=\"Marvin logo\" src=\"assets/banner-light.png\"\u003e\n\u003c/picture\u003e\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/undistro/marvin.svg)](https://pkg.go.dev/github.com/undistro/marvin)\n[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/marvin)](https://artifacthub.io/packages/krew/krew-index/marvin)\n[![Test](https://github.com/undistro/marvin/actions/workflows/test.yml/badge.svg?branch=main\u0026event=push)](https://github.com/undistro/marvin/actions/workflows/test.yml)\n![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/undistro/marvin?sort=semver\u0026color=brightgreen)\n![GitHub](https://img.shields.io/github/license/undistro/marvin?color=brightgreen)\n[![Go Report Card](https://goreportcard.com/badge/github.com/undistro/marvin)](https://goreportcard.com/report/github.com/undistro/marvin)\n![GitHub all releases](https://img.shields.io/github/downloads/undistro/marvin/total)\n\n\u003c/div\u003e\n\nMarvin is a CLI tool designed to help Kubernetes cluster administrators \nensure the security and reliability of their environments. \n\nUsing a comprehensive set of [CEL (Common Expression Language)](https://github.com/google/cel-spec) expressions, \nMarvin performs extensive checks on cluster resources, \nidentifying potential issues, misconfigurations, and vulnerabilities that could pose a risk to the system. \nIt helps ensure that your Kubernetes clusters are always in compliance with best practices and industry standards.\n\nMarvin is also used as a plugin in [Zora](https://zora-docs.undistro.io/latest/).\n\n\u003c!-- TOC --\u003e\n* [Installation](#installation)\n  * [Manually](#manually)\n  * [Install via script](#install-via-script)\n  * [Install via Krew](#install-via-krew)\n  * [Install from source](#install-from-source)\n* [Usage](#usage)\n  * [Built-in checks](#built-in-checks)\n  * [Custom checks](#custom-checks)\n  * [Skipping resources](#skipping-resources)\n  * [RBAC](#rbac)\n* [Contributing](#contributing)\n* [License](#license)\n\u003c!-- TOC --\u003e\n\n_Please [star :star:](https://github.com/undistro/marvin/stargazers) the repo if you want us to continue developing and improving Marvin!_ :grin:\n\n# Installation\n\nThe pre-compiled binaries are available in [GitHub releases page](https://github.com/undistro/marvin/releases) \nand can be installed manually, via script or as a `kubectl` plugin with [Krew](https://krew.sigs.k8s.io).\n\n## Manually\n\n1. Download the file for your system/architecture from the [GitHub releases page](https://github.com/undistro/marvin/releases)\n2. Unpack the downloaded archive (e.g `tar -xzf marvin_Linux_x86_64.tar.gz`)\n3. Make sure the binary has execution bit turned on (`chmod +x ./marvin`)\n4. Move the binary somewhere in your `$PATH` (e.g `sudo mv ./marvin /usr/local/bin/`)\n\n## Install via script\n\nThe process above can be automated by the following script:\n\n```shell\ncurl -sSfL https://raw.githubusercontent.com/undistro/marvin/main/install.sh | sh -s -- -b $HOME/.local/bin\n```\n\n## Install via [Krew](https://krew.sigs.k8s.io)\n\nYou can install Marvin as a `kubectl` plugin via [Krew](https://krew.sigs.k8s.io):\n```shell\nkubectl krew install marvin\n```\n\nThen you can use Marvin with `kubectl` prefix:\n```shell\nkubectl marvin version\n```\n\n## Install from source\n\n```shell\ngo install github.com/undistro/marvin@latest\n```\n\n# Usage\n\n## Built-in checks\n\nScan the current-context Kubernetes cluster performing the [built-in checks](internal/builtins):\n```shell\nmarvin scan\n```\n```\nSEVERITY   ID      CHECK                                                   STATUS   FAILED   PASSED   SKIPPED \nHigh       M-101   Host namespaces                                         Failed   8        25       0         \nHigh       M-104   HostPath volume                                         Failed   8        25       0         \nHigh       M-201   Application credentials stored in configuration files   Failed   2        45       0         \nHigh       M-102   Privileged container                                    Failed   2        31       0         \nHigh       M-103   Insecure capabilities                                   Failed   2        31       0         \nHigh       M-100   Privileged access to the Windows node                   Passed   0        33       0         \nHigh       M-105   Not allowed hostPort                                    Passed   0        33       0         \nMedium     M-113   Container could be running as root user                 Failed   33       0        0         \nMedium     M-407   CPU not limited                                         Failed   31       2        0         \nMedium     M-406   Memory not limited                                      Failed   27       6        0         \nMedium     M-404   Memory requests not specified                           Failed   26       7        0         \nMedium     M-402   Readiness and startup probe not configured              Failed   25       8        0         \nMedium     M-403   Liveness probe not configured                           Failed   25       8        0         \nMedium     M-405   CPU requests not specified                              Failed   23       10       0         \nMedium     M-106   Forbidden AppArmor profile                              Passed   0        33       0         \nMedium     M-107   Forbidden SELinux options                               Passed   0        33       0         \nMedium     M-108   Forbidden proc mount type                               Passed   0        33       0         \nMedium     M-109   Forbidden seccomp profile                               Passed   0        33       0         \nMedium     M-110   Unsafe sysctls                                          Passed   0        33       0         \nMedium     M-112   Allowed privilege escalation                            Passed   0        33       0         \nMedium     M-114   Container running as root UID                           Passed   0        33       0         \nMedium     M-200   Image registry not allowed                              Passed   0        33       0         \nMedium     M-400   Image tagged latest                                     Passed   0        33       0         \nMedium     M-408   Sudo in container entrypoint                            Passed   0        33       0         \nMedium     M-409   Deprecated image registry                               Passed   0        33       0         \nMedium     M-500   Workload in default namespace                           Passed   0        33       0         \nMedium     M-410   Not allowed restartPolicy                               Passed   0        18       0         \nLow        M-116   Not allowed added/dropped capabilities                  Failed   33       0        0         \nLow        M-202   Automounted service account token                       Failed   33       0        0         \nLow        M-115   Not allowed seccomp profile                             Failed   29       4        0         \nLow        M-300   Root filesystem write allowed                           Failed   29       4        0         \nLow        M-111   Not allowed volume type                                 Failed   8        25       0         \nLow        M-203   SSH server running inside container                     Passed   0        39       0         \nLow        M-401   Unmanaged Pod                                           Passed   0        15       0         \n```\n\nThe default output format is `table` which represents a summary of checks result. \nYou can provide `json` or `yaml` in the `-o/--output` flag to get more details.\n\nRun `marvin scan --help` to see all available options.\n\n## Custom checks\n\nMarvin allows you to write your own checks by using [CEL expressions](https://github.com/google/cel-spec) in a YAML file like the example below.\n\n```yaml\nid: CUSTOM-001\nseverity: Medium\nmessage: \"Replicas limit\"\nmatch:\n  resources:\n    - group: apps\n      version: v1\n      resource: deployments\nvalidations:\n  - expression: \u003e\n      object.spec.replicas \u003c= 5\n    message: \"Deployment with more than 5 replicas\"\n```\n\nIf an expression evaluates to `false`, the check fails.\n\nThis is how built-in Marvin checks are defined as well.\nYou can see all the built-in checks in the [`internal/builtins` folder](internal/builtins) for examples.\n\nIf you want to quickly test CEL expressions from your browser, check out the [CEL Playground](https://playcel.undistro.io/).\n\nThen provide the directory path with your custom check files in the `-f/--checks` flag:\n\n```shell\nmarvin scan --disable-builtin --checks ./examples/\n```\n```\nSEVERITY   ID           CHECK            STATUS   FAILED   PASSED   SKIPPED \nMedium     CUSTOM-001   Replicas limit   Passed   0        2        0         \n```\n\nThe flag `--disable-builtin` disables the built-in Marvin checks.\n\nIf the check matches a PodSpec (`Pod`, `ReplicationController`, `ReplicaSet`, `Deployment`, `StatefulSet`, `DaemonSet`, `Job` or `CronJob`)\nthe `podSpec` and `allContainers` inputs are available for expressions.\n\nThe `allContainers` input is a list of all containers including `initContainers` and `ephemeralContainers`.\n\n## Skipping resources\n\nYou can use annotations to skip certain checks for specific resources in your cluster.\nBy adding the `marvin.undistro.io/skip` annotation to a resource, \nyou can specify a comma-separated list of check IDs to skip.\n\nExample:\n```shell\nkubectl annotate deployment nginx marvin.undistro.io/skip='M-202, M-111'\n```\n\nBy default, Marvin will respect the `marvin.undistro.io/skip` annotation when performing checks. \nHowever, you can disable this behavior by using the `--disable-annotation-skip` flag.\nThis flag will cause Marvin to perform all checks on all resources.\n\nIf you prefer to use a different annotation to skip checks, \nyou can use the `--skip-annotation` flag to specify the annotation name. \nExample: `--skip-annotation='my-company.com/skip-checks'`\n\n## RBAC\n\nCurrently, the built-in checks look for the below resources\nand Marvin needs view (`get` and `list`) permission to verify them.\n\n- `v1/pods`\n- `v1/configmaps`\n- `v1/services`\n- `apps/v1/deployments`\n- `apps/v1/daemonsets`\n- `apps/v1/statefulsets`\n- `apps/v1/replicasets`\n- `batch/v1/cronjobs`\n- `batch/v1/jobs`\n\n\u003cdetails\u003e\n\n\u003csummary\u003e Here is a sample `ClusterRole` for Marvin: \u003c/summary\u003e\n\n```yaml\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: marvin\nrules:\n  - apiGroups: [ \"\" ]\n    resources:\n      - configmaps\n      - pods\n      - services\n    verbs: [ \"get\", \"list\" ]\n  - apiGroups: [ \"apps\" ]\n    resources:\n      - daemonsets\n      - deployments\n      - statefulsets\n      - replicasets\n    verbs: [ \"get\", \"list\" ]\n  - apiGroups: [ batch ]\n    resources:\n      - jobs\n      - cronjobs\n    verbs: [ \"get\", \"list\" ]\n```\n\n\u003c/details\u003e\n\n\u003e **Note**\n\u003e You can write a custom check to look at any resource. \n\u003e But Marvin needs view permission. \n\u003e Remember to update RBAC for new resources you want to check.\n\n# Contributing\n\nWe appreciate your contribution.\nPlease refer to our [contributing guideline](https://github.com/undistro/marvin/blob/main/CONTRIBUTING.md) for further information.\nThis project adheres to the Contributor Covenant [code of conduct](https://github.com/undistro/marvin/blob/main/CODE_OF_CONDUCT.md).\n\n# License\n\nMarvin is available under the Apache 2.0 license. See the [LICENSE](LICENSE) file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fundistro%2Fmarvin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fundistro%2Fmarvin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fundistro%2Fmarvin/lists"}