{"id":13522909,"url":"https://github.com/mattfenwick/kubectl-cyclonus","last_synced_at":"2025-08-22T03:13:41.870Z","repository":{"id":40428121,"uuid":"338314173","full_name":"mattfenwick/kubectl-cyclonus","owner":"mattfenwick","description":"kubectl/krew plugin for working with network policies","archived":false,"fork":false,"pushed_at":"2024-07-11T10:22:22.000Z","size":109,"stargazers_count":33,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-09T16:20:47.471Z","etag":null,"topics":["krew","kubectl","kubectl-plugin","kubernetes","network-policies"],"latest_commit_sha":null,"homepage":"","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/mattfenwick.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":"2021-02-12T12:33:16.000Z","updated_at":"2025-03-15T20:14:01.000Z","dependencies_parsed_at":"2024-01-13T22:23:40.347Z","dependency_job_id":"e0d758a7-f2b5-4a96-a8d6-274c4e98fb4c","html_url":"https://github.com/mattfenwick/kubectl-cyclonus","commit_stats":{"total_commits":31,"total_committers":3,"mean_commits":"10.333333333333334","dds":"0.16129032258064513","last_synced_commit":"2aa5324fd3471d6f0a6295af49466d99d2f2dc2e"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/mattfenwick/kubectl-cyclonus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattfenwick%2Fkubectl-cyclonus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattfenwick%2Fkubectl-cyclonus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattfenwick%2Fkubectl-cyclonus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattfenwick%2Fkubectl-cyclonus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mattfenwick","download_url":"https://codeload.github.com/mattfenwick/kubectl-cyclonus/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattfenwick%2Fkubectl-cyclonus/sbom","scorecard":{"id":626402,"data":{"date":"2025-08-11","repo":{"name":"github.com/mattfenwick/kubectl-cyclonus","commit":"b8994cc49d5edcb458533e720eea6fc665cfbdd3"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/25 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/mattfenwick/kubectl-cyclonus/release.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/mattfenwick/kubectl-cyclonus/release.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/mattfenwick/kubectl-cyclonus/release.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/mattfenwick/kubectl-cyclonus/release.yaml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yaml:7"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.2.1 not signed: https://api.github.com/repos/mattfenwick/kubectl-cyclonus/releases/164969738","Warn: release artifact v0.2.0 not signed: https://api.github.com/repos/mattfenwick/kubectl-cyclonus/releases/124806364","Warn: release artifact v0.1.9 not signed: https://api.github.com/repos/mattfenwick/kubectl-cyclonus/releases/120116134","Warn: release artifact v0.1.8 not signed: https://api.github.com/repos/mattfenwick/kubectl-cyclonus/releases/98578541","Warn: release artifact v0.1.7 not signed: https://api.github.com/repos/mattfenwick/kubectl-cyclonus/releases/83878098","Warn: release artifact v0.2.1 does not have provenance: https://api.github.com/repos/mattfenwick/kubectl-cyclonus/releases/164969738","Warn: release artifact v0.2.0 does not have provenance: https://api.github.com/repos/mattfenwick/kubectl-cyclonus/releases/124806364","Warn: release artifact v0.1.9 does not have provenance: https://api.github.com/repos/mattfenwick/kubectl-cyclonus/releases/120116134","Warn: release artifact v0.1.8 does not have provenance: https://api.github.com/repos/mattfenwick/kubectl-cyclonus/releases/98578541","Warn: release artifact v0.1.7 does not have provenance: https://api.github.com/repos/mattfenwick/kubectl-cyclonus/releases/83878098"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 8 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":6,"reason":"4 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2024-3333","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw","Warn: Project is vulnerable to: GO-2025-3488 / GHSA-6v2p-p543-phr9"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T06:36:42.124Z","repository_id":40428121,"created_at":"2025-08-21T06:36:42.124Z","updated_at":"2025-08-21T06:36:42.124Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271578520,"owners_count":24784052,"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-08-22T02:00:08.480Z","response_time":65,"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":["krew","kubectl","kubectl-plugin","kubernetes","network-policies"],"created_at":"2024-08-01T06:00:53.606Z","updated_at":"2025-08-22T03:13:41.838Z","avatar_url":"https://github.com/mattfenwick.png","language":"Go","funding_links":[],"categories":["kubectl Plugins"],"sub_categories":["Installing plugins via awesome-kubectl-plugins"],"readme":"# kubectl cyclonus\n\nA `kubectl` plugin to work with network policies.  This plugin is based on [the cyclonus tool](https://github.com/mattfenwick/cyclonus), which provides the underlying functionality.\n\n\n## Quick Start\n\nMake sure you have krew installed; then:\n\n```\nkubectl krew install cyclonus\n\nkubectl cyclonus -h\n```\n\n## Install a few network policies in your cluster\n\nIf you don't have any network policies installed on your cluster, here's a few examples to get started:\n\n```shell\n$ kubectl create -f networkpolicies/simple-example\n\n$ kubectl get netpol -A\n  NAMESPACE   NAME                        POD-SELECTOR   AGE\n  y           allow-all-egress-by-label   pod in (a,b)   96s\n  y           allow-all-for-label         pod=b          96s\n  y           allow-by-ip                 pod=c          96s\n  y           allow-label-to-label        pod=a          96s\n  y           deny-all                    \u003cnone\u003e         96s\n  y           deny-all-egress             \u003cnone\u003e         96s\n  y           deny-all-for-label          pod=a          96s\n```\n\n## Explain policies\n\nGroups policies by target, divides rules into egress and ingress, and gives a basic explanation of the combined\npolicies.  This clarifies the interactions between \"denies\" and \"allows\" from multiple policies.\n\n```\n$ kubectl cyclonus --mode explain -A\n\n+---------+---------------+------------------------+---------------------+--------------------------+\n|  TYPE   |    TARGET     |      SOURCE RULES      |        PEER         |      PORT/PROTOCOL       |\n+---------+---------------+------------------------+---------------------+--------------------------+\n| Ingress | namespace: y  | y/allow-label-to-label | no ips              | no ports, no protocols   |\n|         | Match labels: | y/deny-all-for-label   |                     |                          |\n|         |   pod: a      |                        |                     |                          |\n+         +               +                        +---------------------+--------------------------+\n|         |               |                        | namespace: y        | all ports, all protocols |\n|         |               |                        | pods: Match labels: |                          |\n|         |               |                        |   pod: c            |                          |\n+         +---------------+------------------------+---------------------+                          +\n|         | namespace: y  | y/allow-all-for-label  | all pods, all ips   |                          |\n|         | Match labels: |                        |                     |                          |\n|         |   pod: b      |                        |                     |                          |\n+         +---------------+------------------------+---------------------+--------------------------+\n|         | namespace: y  | y/allow-by-ip          | ports for all IPs   | no ports, no protocols   |\n|         | Match labels: |                        |                     |                          |\n|         |   pod: c      |                        |                     |                          |\n+         +               +                        +---------------------+--------------------------+\n|         |               |                        | 0.0.0.0/24          | all ports, all protocols |\n|         |               |                        | except []           |                          |\n|         |               |                        |                     |                          |\n+         +               +                        +---------------------+--------------------------+\n|         |               |                        | no pods             | no ports, no protocols   |\n|         |               |                        |                     |                          |\n|         |               |                        |                     |                          |\n+         +---------------+------------------------+---------------------+                          +\n|         | namespace: y  | y/deny-all             | no pods, no ips     |                          |\n|         | all pods      |                        |                     |                          |\n+---------+---------------+------------------------+---------------------+--------------------------+\n```\n\n## Which policy rules apply to a pod?\n\nThis takes the previous command a step further: it combines the rules from all the targets that apply\nto a pod. \n\n```\n$ kubectl cyclonus \\\n  --mode query-target \\\n  --target-pod-path ./examples/targets.json\n\nCombined rules for pod {Namespace:y Labels:map[pod:a]}:\n+---------+---------------+-----------------------------+---------------------+--------------------------+\n|  TYPE   |    TARGET     |        SOURCE RULES         |        PEER         |      PORT/PROTOCOL       |\n+---------+---------------+-----------------------------+---------------------+--------------------------+\n| Ingress | namespace: y  | y/allow-label-to-label      | no ips              | no ports, no protocols   |\n|         | Match labels: | y/deny-all-for-label        |                     |                          |\n|         |   pod: a      | y/deny-all                  |                     |                          |\n+         +               +                             +---------------------+--------------------------+\n|         |               |                             | namespace: y        | all ports, all protocols |\n|         |               |                             | pods: Match labels: |                          |\n|         |               |                             |   pod: c            |                          |\n+---------+---------------+-----------------------------+---------------------+--------------------------+\n|         |               |                             |                     |                          |\n+---------+---------------+-----------------------------+---------------------+--------------------------+\n| Egress  | namespace: y  | y/deny-all-egress           | all pods, all ips   | all ports, all protocols |\n|         | Match labels: | y/allow-all-egress-by-label |                     |                          |\n|         |   pod: a      |                             |                     |                          |\n+---------+---------------+-----------------------------+---------------------+--------------------------+\n```\n\n\n## Will policies allow or block traffic?\n\nGiven arbitrary traffic examples (from a source to a destination, including labels, over a port and protocol),\nthis command parses network policies and determines if the traffic is allowed or not.\n\n```\n$ kubectl cyclonus \\\n  --mode query-traffic \\\n  --traffic-path ./examples/traffic.json\n\nTraffic:\n+--------------------------+-------------+---------------+-----------+-----------+------------+\n|      PORT/PROTOCOL       | SOURCE/DEST |    POD IP     | NAMESPACE | NS LABELS | POD LABELS |\n+--------------------------+-------------+---------------+-----------+-----------+------------+\n| 80 (serve-80-tcp) on TCP | source      | 192.168.1.99  | y         | ns: y     | app: c     |\n+                          +-------------+---------------+           +           +------------+\n|                          | destination | 192.168.1.100 |           |           | pod: b     |\n+--------------------------+-------------+---------------+-----------+-----------+------------+\n\nIs traffic allowed?\n+-------------+--------+---------------+\n|    TYPE     | ACTION |    TARGET     |\n+-------------+--------+---------------+\n| Ingress     | Allow  | namespace: y  |\n|             |        | Match labels: |\n|             |        |   pod: b      |\n+             +--------+---------------+\n|             | Deny   | namespace: y  |\n|             |        | all pods      |\n+-------------+--------+---------------+\n|             |        |               |\n+-------------+--------+---------------+\n| Egress      | Deny   | namespace: y  |\n|             |        | all pods      |\n+-------------+--------+---------------+\n| IS ALLOWED? | FALSE  |                \n+-------------+--------+---------------+\n```\n\n## Simulated probe\n\nRuns a simulated connectivity probe against a set of network policies, without using a kubernetes cluster.\n\n```\n$ kubectl cyclonus \\\n  --mode probe \\\n  --probe-path ./examples/probe.json\n\nCombined:\n+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n|     | X/A | X/B | X/C | Y/A | Y/B | Y/C | Z/A | Z/B | Z/C |\n+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n| x/a | .   | .   | .   | X   | .   | X   | .   | .   | .   |\n| x/b | .   | .   | .   | X   | .   | X   | .   | .   | .   |\n| x/c | .   | .   | .   | X   | .   | X   | .   | .   | .   |\n| y/a | .   | .   | .   | X   | .   | X   | .   | .   | .   |\n| y/b | .   | .   | .   | X   | .   | X   | .   | .   | .   |\n| y/c | X   | X   | X   | X   | X   | X   | X   | X   | X   |\n| z/a | .   | .   | .   | X   | .   | X   | .   | .   | .   |\n| z/b | .   | .   | .   | X   | .   | X   | .   | .   | .   |\n| z/c | .   | .   | .   | X   | .   | X   | .   | .   | .   |\n+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+\n```\n\n## Linter\n\nChecks network policies for common problems.\n\n```\n$ kubectl cyclonus \\\n  --mode lint \\\n  --lint=true\n\n+-----------------+------------------------------+-------------------+-----------------------------+\n| SOURCE/RESOLVED |             TYPE             |      TARGET       |       SOURCE POLICIES       |\n+-----------------+------------------------------+-------------------+-----------------------------+\n| Resolved        | CheckTargetAllEgressAllowed  | namespace: y      | y/allow-all-egress-by-label |\n|                 |                              |                   |                             |\n|                 |                              | pod selector:     |                             |\n|                 |                              | matchExpressions: |                             |\n|                 |                              | - key: pod        |                             |\n|                 |                              |   operator: In    |                             |\n|                 |                              |   values:         |                             |\n|                 |                              |   - a             |                             |\n|                 |                              |   - b             |                             |\n|                 |                              |                   |                             |\n+-----------------+------------------------------+-------------------+-----------------------------+\n| Resolved        | CheckDNSBlockedOnTCP         | namespace: y      | y/deny-all-egress           |\n|                 |                              |                   |                             |\n|                 |                              | pod selector:     |                             |\n|                 |                              | {}                |                             |\n|                 |                              |                   |                             |\n+-----------------+------------------------------+-------------------+-----------------------------+\n| Resolved        | CheckDNSBlockedOnUDP         | namespace: y      | y/deny-all-egress           |\n|                 |                              |                   |                             |\n|                 |                              | pod selector:     |                             |\n|                 |                              | {}                |                             |\n|                 |                              |                   |                             |\n+-----------------+------------------------------+-------------------+-----------------------------+\n```\n\n# How to release\n\nThis uses krew automation; just push a new tag and wait for [the goreleaser action](https://github.com/mattfenwick/kubectl-cyclonus/actions) to run.\n\n# How to test a local krew release\n\n1. Choose one of the following:\n\n     - easy way: `kubectl krew install --manifest=./deploy/krew/cyclonus.yaml`\n\n     - hard way:\n        1. download a binary from [the github project release page](https://github.com/mattfenwick/kubectl-cyclonus/releases)\n\n        2. run a `krew install` against the downloaded binary\n\n            ```\n            kubectl krew install --manifest=./deploy/krew/cyclonus.yaml --archive=/Users/mfenwick/Downloads/kubectl-cyclonus_darwin_amd64.tar.gz\n            ```\n\n2. test it\n\n    ```\n    kubectl cyclonus -h\n    ```\n\n3. clean up\n\n    ```\n    kubectl krew uninstall cyclonus\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattfenwick%2Fkubectl-cyclonus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmattfenwick%2Fkubectl-cyclonus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattfenwick%2Fkubectl-cyclonus/lists"}