Implement Phases 1-3 of the performance optimization plan to address
issue #1793 - reduce CPU and memory consumption for system-constrained
environments.
Phase 1 - OPA Module Caching:
- Add compiledModules cache to OPAProcessor with thread-safe access
- Cache compiled OPA rules to eliminate redundant compilation
- Reuse compiled modules with double-checked locking pattern
- Expected CPU savings: 30-40%
Phase 2 - Map Pre-sizing:
- Add estimateClusterSize() to calculate resource count
- Pre-size AllResources, ResourcesResult, and related maps
- Reduce memory reallocations and GC pressure
- Expected memory savings: 10-20%
Phase 3 - Set-based Deduplication:
- Add thread-safe StringSet utility in core/pkg/utils
- Replace O(n) slices.Contains() with O(1) map operations
- Use StringSet for image scanning and related resources deduplication
- 100% test coverage for new utility
- Expected CPU savings: 5-10% for large clusters
Full optimization plan documented in optimization-plan.md
Related: #1793
Signed-off-by: Matthias Bertschy <matthias.bertschy@gmail.com>
Reformat the 00-pr-scanner workflow for consistent indentation. Add
artifact-metadata: read to pr-scanner permissions, include GO111MODULE
in the pr-scanner inputs, and set fetch-depth/submodules on the
actions/checkout step
Add a new --labels-to-copy CLI flag that allows users to specify which
labels from Kubernetes workloads should be extracted and included in
scan reports. This makes it easier to tie scan results back to app
teams or repositories by including relevant labels like 'app', 'team',
or 'environment' in the report output.
Changes:
- Add LabelsToCopy field to ScanInfo and OPASessionObj structs
- Add --labels-to-copy flag to scan command
- Add ResourceLabels field to PostureReportWithSeverity for JSON output
- Implement extractResourceLabels function to extract specified labels
- Add unit tests for label extraction functionality
Fixes#1660🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: majiayu000 <1835304752@qq.com>
Fixes#1617. The kustomize build was failing for overlays that reference
base configurations in parent directories (e.g., ../../base). This was
because krusty.MakeDefaultOptions() defaults to LoadRestrictionsRootOnly,
which prevents loading resources from outside the kustomize directory.
Changed LoadRestrictions to LoadRestrictionsNone to allow overlays to
properly resolve and merge base configurations during scanning.
Added tests to verify:
- Overlay directories can successfully load resources from base directories
- Base directories continue to work as before
- The merged configuration includes resources from both base and overlay
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: majiayu000 <1835304752@qq.com>
Add workflow input skip_system_tests and make RUN_E2E respect it. Add
System Tests Report step to publish JUnit XMLs. Update
goreleaser-post-e2e.sh to add GitHub Actions log grouping, capture
per-test logs under test-results/system-tests, and copy JUnit XML
results while preserving directory structure.
Update CI workflow and goreleaser post-e2e script to use Python 3.9.
Rename SYSTEST_REQUIRE_PY311 to SYSTEST_REQUIRE_PY39, prefer python3.9,
and change version checks to refuse venvs created with Python 3.10+. If
python3.9 is missing or wrong, honor E2E_FAIL_ON_ERROR: either fail the
release or skip system tests and clean up.
- Add isHTTPURL helper function for better code reusability
- Improve comments to clarify why ContextDir is returned
- Enhance error message for unrecognized git repositories
Co-authored-by: matthyx <20683409+matthyx@users.noreply.github.com>
- Add URL detection (http:// and https://) in getScanningContext
- Prevent URLs from being joined with current working directory
- Add test cases for self-hosted GitLab URLs
- Ensure proper error handling when git clone fails
Co-authored-by: matthyx <20683409+matthyx@users.noreply.github.com>
Ensure getter functions handle nil downloadReleasedPolicy correctly by creating a new instance when needed, maintaining backward compatibility with existing code while supporting air-gapped mode.
Co-authored-by: matthyx <20683409+matthyx@users.noreply.github.com>
- Fix string field checks in isAirGappedMode (use != "" instead of len() > 0)
- Use centralized isAirGappedMode function in getResourceHandler
- Improve comment clarity to reflect all air-gapped conditions
Co-authored-by: matthyx <20683409+matthyx@users.noreply.github.com>
Extract complex boolean condition into a dedicated helper function for better readability and maintainability.
Co-authored-by: matthyx <20683409+matthyx@users.noreply.github.com>
- Skip version check when --keep-local flag is set
- Skip DownloadReleasedPolicy initialization when in air-gapped mode
- Skip KSCloudAPIConnector initialization when --keep-local is set
Co-authored-by: matthyx <20683409+matthyx@users.noreply.github.com>
hey! added the default matchers option for image scanning as requested in #1838. now you can choose between stock matchers and CPE matchers when scanning images.
what's new:
- added --use-default-matchers flag to scan/image/patch commands
- true = stock matchers (default behavior)
- false = CPE matchers (more precise)
usage:
# use CPE matchers for more precise detection
kubescape scan image nginx:latest --use-default-matchers=false
# or in scan command
kubescape scan --scan-images --use-default-matchers=false
everything's backward compatible - existing code works exactly the same. just added the new option for folks who want more control over their vulnerability detection.
fixes#1838
Signed-off-by: aadarsh-nagrath <anagrath1@gmail.com>
Implemented two new tools: 'list_configuration_security_scan_manifests' for listing available configuration scan manifests and 'get_configuration_security_scan_manifest' for retrieving details of a specific manifest. Added a resource template for configuration manifests and integrated these tools into the mcpserver.
Signed-off-by: Ben <ben@armosec.io>
Right now, sending a sigint will start a graceful shutdown, which can take quite a while.
By calling stop() in the signal handler it unregisters the handler so that a subsequent
sigint received during a graceful shutdown will kill the process immediately.
Signed-off-by: Ian Fox <code@whatthefox.dev>
Fix: Correct runtime.Caller usage and handle error in CurrentDir()
- Changed runtime.Caller(1) to runtime.Caller(0) to correctly fetch the current file's directory.
- Added proper check for the 'ok' value returned by runtime.Caller.
- Improved robustness by panicking if runtime information retrieval fails.
Signed-off-by: rash1411 <107741585+rash1411@users.noreply.github.com>
* deprecate control name in posture exception policies
Signed-off-by: Amir Malka <amirm@armosec.io>
* deprecate control name in posture exception policies
Signed-off-by: Amir Malka <amirm@armosec.io>
* deprecate control name in posture exception policies
Signed-off-by: Amir Malka <amirm@armosec.io>
* deprecate control name in posture exception policies
Signed-off-by: Amir Malka <amirm@armosec.io>
---------
Signed-off-by: Amir Malka <amirm@armosec.io>
- Introduced a single context in main() to handle interrupt signals (os.Interrupt, syscall.SIGTERM).
- Removed repetitive context creation in the program by reusing the propagated context.
- Improved code readability and maintainability by centralizing context management.
- Ensured consistent handling of graceful shutdown across the program.
Signed-off-by: Ruslan Semagin <pixel.365.24@gmail.com>
This commit introduces the ability to specify targets in image
exceptions. Each target will have the following 4 attributes:
1. Registry
2. Organization
3. ImageName
4. ImageTag
These attributes will be used to match against the canonical image name
of the image to be scanned. The vulnerabilites and the severities
specified in the VulnerabilitiesIgnorePolicy object will be considered
only if the image to be scanned matches the targets specified for that
policy. Regular expressions can also be used to specify the image
attributes.
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
Added initial commit to start loading image exceptions from json files.
Currently, it supports vulnerability exceptions using their CVE-IDs.
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
This commit introduces the "exceptions" flag in the scan image command.
Users can pass a list of vulnerabilities they ignore while scanning an
image using this flag. Also added tests for the same.
Fixes: https://github.com/kubescape/kubescape/issues/1564
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
In particular,
Replace scanResponseChan struct with a reply channel in req.
This removes one chokepoint with tracking a map of channel with a mutex wrapping by not sharing data across different requests and
makes it easier to reason about the correctness of the behavior.
Other changes are mostly cosmetic to group your operations related to
the primitives you are operating on, reducing the average lifetime of
a local variable (matters mostly for humans; compilers are very good at this nowadays).
Also this is net benefical by reducing LOCs by 45.
Signed-off-by: ttimonen <toni.timonen@iki.fi>
It plays wtih channels and goroutines, so having it
behave correctly is not completely trivial and test
worthy.
Signed-off-by: ttimonen <toni.timonen@iki.fi>
Add a new column in the PDF output to reference each control that has
been executed as control ID.
Signed-off-by: Massimiliano Giovagnoli <me@maxgio.it>
Wrote new tests to cover the unhandled statements in the
`NewFixPathLocationResolver` and `ResolveLocation` functions.
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
Wrote new tests for `categorytable` and `frameworkscan`
Refactored the `shortFormatRow` function for:
- Imporved readability
- Consistency
- Improve code modularity
- Encapsulation: The formatted string construction is encapsulated
within the function, maintaining code modularity and separation of
concerns.
Added the `MockISeverityCounters` mock struct to test the
`renderSeverityCountersSummary` function.
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
Improvments:
1. filterCVEsBySeverities
- This approach is faster than iterating over the severities slice
for each CVE. The map is created in advance, eliminating the
need for repeated string comparisons.
2. getSortPackageScores
- Avoids unnecessary map lookups by creating a slice of
imageprinter.PackageScore pointers.
3. getSortedCVEsBySeverity
- Avoiding Map Lookups
- Efficient Sorting
- Optimized Output
Added tests for tableprinter/utils
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
Added tests for the following functions:
- `generateTable`
- `NewTableWriter`
- `PrintImageScanningTable`
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
Added tests in the jsonprinter.go, junit.go pdf.go prometheus.go files
and updated the `Score` functions to handle invalid scores.
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
Wrote new tests for the functions in the resourcetable.go file.
Enhancements:
1. `generateResourceHeader`:
- Dynamic Header Length
- Efficient Header Creation
- Clearer Code Structure
2. `appendFailedPathsIfNotInPaths`:
- Create a set to efficiently check if a failed path already exists in
the paths slice
- Append failed paths if they are not already present
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
Description:
This pull request introduces a new test case TestGetFrameworkCmdWithNonExistentFramework in the framework_test.go file. The purpose of this test case is to verify the behavior of the getFrameworkCmd function when it's run with a non-existent framework argument.
In this test case, we:
Create a mock Kubescape interface and a ScanInfo object
Call the getFrameworkCmd function with the mock interface and ScanInfo object
Run the command with a non-existent framework argument
Check that there is an error and the error message is "bad argument: account ID must be a valid UUID"
This test case enhances the test coverage of the getFrameworkCmd function and ensures that it correctly handles non-existent framework arguments.
Signed-off-by: Umair <58398786+Umair0343@users.noreply.github.com>
Description:
This pull request introduces a new test case TestGetControlCmdWithNonExistentControl in the control_test.go file. The purpose of this test case is to verify the behavior of the getControlCmd function when it's run with a non-existent control argument.
In this test case, we:
Create a mock Kubescape interface and a ScanInfo object
Call the getControlCmd function with the mock interface and ScanInfo object
Run the command with a non-existent control argument
Check that there is an error and the error message is "bad argument: account ID must be a valid UUID"
This test case enhances the test coverage of the getControlCmd function and ensures that it correctly handles non-existent control arguments.
Signed-off-by: Umair <58398786+Umair0343@users.noreply.github.com>
Title: Add Test Case for Non-Existent Image in GetPatchCmd
Description:
This pull request introduces a new test case TestGetPatchCmdWithNonExistentImage in the patch_test.go file. The purpose of this test case is to verify the behavior of the GetPatchCmd function when it's run with a non-existent image argument.
In this test case, we:
Create a mock Kubescape interface
Call the GetPatchCmd function with the mock interface
Run the command with a non-existent image argument
Check that there is an error and the error message is "image tag is required"
This test case enhances the test coverage of the GetPatchCmd function and ensures that it correctly handles non-existent image arguments.
Signed-off-by: Umair <58398786+Umair0343@users.noreply.github.com>
Pull Request Description:
Changes Made
Added a new test case TestParseSetArgs_InvalidKey in the config package to cover scenarios where an invalid key is provided in the set command arguments.
Test Case Details
Function Tested: TestParseSetArgs_InvalidKey
Test Objective: Ensures that the parseSetArgs function correctly handles the scenario where an invalid key is provided, returning an appropriate error message.
Test Input: Command arguments with an invalid key, e.g., invalidKey=value1.
Expected Output: The function should return an error message indicating that the provided key is unknown, along with the list of supported keys.
Motivation
This new test case enhances the test coverage for the parseSetArgs function, ensuring robust handling of invalid keys during the configuration setting process. By validating that the function produces the expected error message for such cases, we contribute to the overall reliability of the codebase. This addition further strengthens the testing suite for the config package, promoting code quality and correctness.
Signed-off-by: Umair <58398786+Umair0343@users.noreply.github.com>
Pull Request Description:
Changes Made
Added new test cases for different shell completions in the completion package to enhance test coverage.
New Test Cases
TestGetCompletionCmd_RunBashCompletionNotExpectedOutputs: Tests that the output for Bash completion does not match the specified unexpected outputs.
TestGetCompletionCmd_RunZshCompletionNotExpectedOutputs: Tests that the output for Zsh completion does not match the specified unexpected outputs.
TestGetCompletionCmd_RunFishCompletionNotExpectedOutputs: Tests that the output for Fish completion does not match the specified unexpected outputs.
TestGetCompletionCmd_RunPowerShellCompletionNotExpectedOutputs: Tests that the output for PowerShell completion does not match the specified unexpected outputs.
Motivation
These new test cases aim to further validate the behavior of the GetCompletionCmd function for various shell completions. By ensuring that the actual output does not match the unexpected outputs, we strengthen the reliability of the completion script generation for different shells.
These test cases enhance the robustness of the codebase and provide additional validation for the autocompletion script generation functionality.
Signed-off-by: Umair <58398786+Umair0343@users.noreply.github.com>
Wrote new tests for the printer package and refactored the CalculateMove
function to prevent potential out of bounds crash
Refactored the `addFix` function for better readability, understanding
and chaining method calls.
Used formatted string for logging.
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
This PR focuses on adding unit tests for multiple packages in the
project. The main changes include:
- Addition of new tests for the 'printer' package in the
'core/pkg/resultshandling/printer' directory.
- New tests for the 'results' package in the
'core/pkg/resultshandling' directory.
- Addition of tests for the 'config' package in the
'httphandler/config' directory.
- New tests for the 'testutils' package in the 'internal/testutils'
directory.
- Addition of tests for the 'imagescan' package in the
'pkg/imagescan' directory.
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
Wrote new tests for the following packages
- operator
- patch
- scan
Also fixed potential crash in the RunE function of the image subcommand
in the scan package.
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
Wrote ne tsts for the following packages:
- completion
- config
- download
- fix
- list
Also addressed a potential crash in the compleition, download, and list
subcommands when no arguement was provided to the Args, RunE or Run
functions.
Updated `DownloadSupportCommands`, 'ListSupportActions' function to return sorted slice of
strings.
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
Signed-off-by: cbrom <kb.cbrom@gmail.com>
changed test input to clearly show its not a valid
Signed-off-by: cbrom <kb.cbrom@gmail.com>
added tests for valid json input to JSONDecoder function
Signed-off-by: cbrom <kb.cbrom@gmail.com>
check for specific error message instead of just error return
Signed-off-by: cbrom <kb.cbrom@gmail.com>
check for specific error message instead of just error return
Signed-off-by: cbrom <kb.cbrom@gmail.com>
package imports added
Signed-off-by: cbrom <kb.cbrom@gmail.com>
removed unnecessary mock json file
Signed-off-by: cbrom <kb.cbrom@gmail.com>
min function moved to kscloudapi.go
Signed-off-by: cbrom <kb.cbrom@gmail.com>
added necessary functions to make a post api call
Signed-off-by: cbrom <kb.cbrom@gmail.com>
getLatestVersion now uses KSCloudAPI functions
Signed-off-by: cbrom <kb.cbrom@gmail.com>
reverted moved function min back
Signed-off-by: cbrom <kb.cbrom@gmail.com>
removed unncessary functions and simplified post method
Signed-off-by: cbrom <kb.cbrom@gmail.com>
modified call to APIPostRequest
Signed-off-by: cbrom <kb.cbrom@gmail.com>
renamed HTTPPost request function and added httpClient param (for testing purposes)
Signed-off-by: cbrom <kb.cbrom@gmail.com>
changed function name call
Signed-off-by: cbrom <kb.cbrom@gmail.com>
removed HTTPPost function test
Signed-off-by: cbrom <kb.cbrom@gmail.com>
net/http imported
Signed-off-by: cbrom <kb.cbrom@gmail.com>
bytes import removed
Signed-off-by: cbrom <kb.cbrom@gmail.com>
test added for HTTPPost function
Signed-off-by: cbrom <kb.cbrom@gmail.com>
removed json decoder as it is not necessary anymore
Signed-off-by: cbrom <kb.cbrom@gmail.com>
removed HttpPost function
Signed-off-by: cbrom <kb.cbrom@gmail.com>
Wrote new tests for the following packages in the cmd package:
- completion
- config
* In addition to tests, updated the code for the `stringKeysToSlice`
to return the final string slice in sorted order of keys.
Added new MockIKubescape struct in the core/mocks package
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
1. Use time.Time for expiration to simplify expiration checks.
2. Added a stopChan and a Stop method to properly stop the invalidateTask goroutine instead of directly changing values
3. Used Ticker in invalidateTask for periodic expiration checks
4. Leak Prevention: The invalidateTask() loop checks the TTL value before continuing. If the TTL is zero, the goroutine exits gracefully, preventing a memory leak.
Signed-off-by: sulemaanhamza <sulemanhamza97@gmail.com>
Fix typo in error description
Bug fix where kubescape get policies from file
Signed-off-by: Mehdi Moussaif <m.moussaif42@gmail.com>
Missing '.json' extension when getting Framework Paths
Signed-off-by: Mehdi Moussaif <m.moussaif42@gmail.com>
Appropriate test case for FrameworksPaths
Bug fix where kubescape fails to read from frameworks local paths
Signed-off-by: Mehdi Moussaif <m.moussaif42@gmail.com>
Wrote new tests for the following files:
- controllink.go
- display.go
- fileutils.go
- getter/getpoliciesutils.go
- getter/utils.go
Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
* add access key flag to the scan command
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* support triggering ns
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* Fixed json keys
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* get k8s config
Signed-off-by: David Wertenteil <dwertent@armosec.io>
---------
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* set cloud provider using nodes
* use scan metadata for scanning scope
* code cleanup
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* handle error
Signed-off-by: David Wertenteil <dwertent@armosec.io>
---------
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* print result to stdout when format argument specified
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* print pretty format to stdout if format is not specified
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* remove not relevant log
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
---------
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
Co-authored-by: rcohencyberarmor <rcohen@armosec.io>
* store scan results in storage
Signed-off-by: Amir Malka <amirm@armosec.io>
* store scan results in storage
Signed-off-by: Amir Malka <amirm@armosec.io>
* save resources in their namespaces, load namespace from env var, extend the config obj
Signed-off-by: Amir Malka <amirm@armosec.io>
* setting context name
Signed-off-by: Amir Malka <amirm@armosec.io>
* updated k8s-interface
Signed-off-by: Amir Malka <amirm@armosec.io>
* scanning a deleted resource
Signed-off-by: Amir Malka <amirm@armosec.io>
* cr changes
Signed-off-by: Amir Malka <amirm@armosec.io>
* cr changes
Signed-off-by: Amir Malka <amirm@armosec.io>
* fix
Signed-off-by: Amir Malka <amirm@armosec.io>
* remove unused constants
Signed-off-by: Amir Malka <amirm@armosec.io>
* use t.Setenv
Signed-off-by: Amir Malka <amirm@armosec.io>
* added tests for rbac triplet slugs
Signed-off-by: Amir Malka <amirm@armosec.io>
* updated namespace logic
Signed-off-by: Amir Malka <amirm@armosec.io>
* fix test
Signed-off-by: Amir Malka <amirm@armosec.io>
---------
Signed-off-by: Amir Malka <amirm@armosec.io>
* adding corrections to cmd
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* remove decorative line
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* wip: changed results indicator
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* replace status test with icons
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* print workloads in a different line
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* update display
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* deprecate commands
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* removed unused functions
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* fixed tests
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* update cloud provider detection
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* rename column name
Signed-off-by: David Wertenteil <dwertent@armosec.io>
---------
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* support scanning scope
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update go mod
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update white list
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update go mod
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* scope empty return control should tested
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update rego scope for system test
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update test + mock
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* add comment
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update rego library
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update k8s-interface
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update opa utils - lots of file changes in this commit since armoapi-go bump up in opa-utils
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* move to temp k8s-interface - till PR in k8s-interface repo will approved
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update k8s-interface with released tag
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update go mod in httphandler
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* support unified configuration
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* unitest adjustment
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* config-unified
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* CR corrections
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* remove system test till it will be merged
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* add relevant system test
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* remove delete test
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* return config delete system test
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
---------
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
Co-authored-by: rcohencyberarmor <rcohen@armosec.io>
* Implementing container image name normalization built-in function for Rego
Signed-off-by: Ben <ben@armosec.io>
* updating go.mod t include docker/distribution
Signed-off-by: Ben <ben@armosec.io>
* fix test
Signed-off-by: Ben <ben@armosec.io>
---------
Signed-off-by: Ben <ben@armosec.io>
* support scanning scope
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update go mod
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update white list
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update go mod
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* scope empty return control should tested
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update rego scope for system test
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update test + mock
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* add comment
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update rego library
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update k8s-interface
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update opa utils - lots of file changes in this commit since armoapi-go bump up in opa-utils
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* move to temp k8s-interface - till PR in k8s-interface repo will approved
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update k8s-interface with released tag
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update go mod in httphandler
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* PR review corrections
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* change test name
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* scanning scope support for framework
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* test/mock adjustments after merge
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* add more informative log to the user
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update go.mod and go.sum of the http handler
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* remove framework just scanning scope not matched to framework config scope
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* add system tests to workflow
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* add system test to github workflow
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
---------
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
Signed-off-by: David Wertenteil <dwertent@armosec.io>
Co-authored-by: rcohencyberarmor <rcohen@armosec.io>
Co-authored-by: David Wertenteil <dwertent@armosec.io>
* code refactor
Signed-off-by: Amir Malka <amirm@armosec.io>
* use scaninfo object in resource handler
Signed-off-by: Amir Malka <amirm@armosec.io>
---------
Signed-off-by: Amir Malka <amirm@armosec.io>
This commit adds a CLI command and an associated package that scan
images for vulnerabilities.
Signed-off-by: Vlad Klokun <vklokun@protonmail.ch>
feat(imagescan): fail on exceeding the severity threshold
Signed-off-by: Vlad Klokun <vklokun@protonmail.ch>
* add cmd
Signed-off-by: Daniel Grunberger <danielgrunberger@armosec.io>
* support single workload scan
Signed-off-by: Amir Malka <amirm@armosec.io>
* fix conflict
Signed-off-by: Amir Malka <amirm@armosec.io>
* added unit tests
Signed-off-by: Amir Malka <amirm@armosec.io>
* added unit tests
Signed-off-by: Amir Malka <amirm@armosec.io>
* more refactoring
Signed-off-by: Amir Malka <amirm@armosec.io>
* add scanned workload reference to opasessionobj
Signed-off-by: Amir Malka <amirm@armosec.io>
* fix GetWorkloadParentKind
Signed-off-by: Amir Malka <amirm@armosec.io>
* remove namespace argument from pullSingleResource, using field selector instead
Signed-off-by: Amir Malka <amirm@armosec.io>
* removed designators (unused) field from PolicyIdentifier, and designators argument from GetResources function
Signed-off-by: Amir Malka <amirm@armosec.io>
* fix tests
Signed-off-by: Amir Malka <amirm@armosec.io>
* use ScanObject instead of workload identifier
Signed-off-by: Amir Malka <amirm@armosec.io>
* refactor logic after CR
Signed-off-by: Amir Malka <amirm@armosec.io>
---------
Signed-off-by: Daniel Grunberger <danielgrunberger@armosec.io>
Signed-off-by: Amir Malka <amirm@armosec.io>
Co-authored-by: Daniel Grunberger <danielgrunberger@armosec.io>
* add print in the cli to which version the kubescape was update
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
* update will suggest to our user to update by following kubescape installation guide
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
---------
Signed-off-by: rcohencyberarmor <rcohen@armosec.io>
Co-authored-by: rcohencyberarmor <rcohen@armosec.io>
External observers don’t need to be aware of the fact we need to
sanitize leading document separators in YAML files. This should be
hidden inside our public function - `ApplyFixToContent()`.
Signed-off-by: Vlad Klokun <vklokun@protonmail.ch>
Previously when there was a typo in a test file name, we silently
failed. This commit makes the test explicitly fail if a test data file
was not found.
Signed-off-by: Vlad Klokun <vklokun@protonmail.ch>
* control parallelism of opa rule processing by env var
Signed-off-by: Amir Malka <amirm@armosec.io>
* go 1.20
Signed-off-by: Amir Malka <amirm@armosec.io>
* update go.mod go.sum
Signed-off-by: Amir Malka <amirm@armosec.io>
---------
Signed-off-by: Amir Malka <amirm@armosec.io>
Also:
* declared scanner resources as an enum type
* replaced stdlib json, added uit tests for skipped resources
* unexported worker pool
* more unexported methods (i.e. everything that is not part of the interface)
* refact(core): clarified mock injection logic and added a few unit tests at the caller's (CLI init utils)
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
This PR factorizes the list of calls to the host-scanner API in a loop.
More godoc-friendly doc strings are added.
Signed-off-by: Frédéric BIDON <fredbi@yahoo.com>
This parallelize the Process() portion of the OPA processor.
The main change is that called methods to evaluate a rule no longer
mutate the internal state of the opaprocessor and allocate maps (less
often, in larger chunks) that are merged at the end of the processing.
Signed-off-by: Frédéric BIDON <fredbi@yahoo.com>
* Interfaces are unchanged
* Deprecated: low-level API funcs marked for deprecation:
HttpPost, HttpGetter, HttpDelete (an augmented version of the KS Cloud
client will expose the post report API, which is currently the sole
use-case of low-level API)
* Doc: the package is now godoc-friendly
* Style & code layout:
* listed all exposed types via aliases, for clarity/less confusing
imports
* unexported private types
* factorized query param logic
* factorized type <-> JSON using generic func & io.Reader
* "utils" are now limited to a few common utility functions
* centralized hard-coded strings as (unexported) constants
* concision: use higher-level http definitions such as constants,
cookie methods, etc
* included type-safety guards to verify that interfaces are
actually implemented by the exported types
* Tests: existing test assertions are unchanged
* tests are beefed-up to assert proper authentication flow (token & cookie).
* added unit tests for utility methods
* Perf:
* unmarshalling API responses is now flowing without extraneous memory allocation via string representation
* request headers are now passed withot extraneous map allocation
* JSON operations are now fully supported by jsoniter (no longer use encoding/json)
* Changes in functionality:
* the client is now fully extensible with KSCloudOption
* use the option functor idiom to keep constructors short
* methods that used to mute errors (i.e. return nil, nil) now bubble up errors
* the captured cookie is now captured in full, not just its value
(other cookie parameters returned are stored)
* added a request/response dump option, for debugging
* added support for SubmitReport and retrieval of UI url's
* backported utm changes (reports use case)
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
* adding ks version
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* Initialize scanInfo
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* print if logger level is lower than warning
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* wip: scan default frameworks when scanning files
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* change print to log
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* wip: Add end-line after last log
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* wip: silent spinner when logger is warn
Signed-off-by: David Wertenteil <dwertent@armosec.io>
---------
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* Fixed HTML template
Signed-off-by: David Wertenteil <dwertent@armosec.io>
* Adding HTML output format example
Signed-off-by: David Wertenteil <dwertent@armosec.io>
---------
Signed-off-by: David Wertenteil <dwertent@armosec.io>
description:It includes risk analysis, security compliance, and misconfiguration scanning with an easy-to-use CLI interface, flexible output formats, and automated scanning capabilities.
short_description:Scan resources and cluster configs against security frameworks.
release:
draft:false
footer:>-
---
Released by [GoReleaser](https://github.com/goreleaser/goreleaser).
First, it is awesome that you are considering contributing to Kubescape! Contributing is important and fun and we welcome your efforts.
The Kubescape project manages this document in the central project repository.
When contributing, we categorize contributions into two:
* Small code changes or fixes, whose scope is limited to a single or two files
* Complex features and improvements, with potentially unlimited scope
If you have a small change, feel free to fire up a Pull Request.
When planning a bigger change, please first discuss the change you wish to make via an issue,
so the maintainers are able to help guide you and let you know if you are going in the right direction.
## Code of Conduct
Please follow our [code of conduct](CODE_OF_CONDUCT.md) in all of your interactions within the project.
## Pull Request Process
1. Ensure any install or build dependencies are removed before the end of the layer when doing a
build.
2. Update the README.md with details of changes to the interface, this includes new environment
variables, exposed ports, useful file locations and container parameters.
3. Open Pull Request to the `master` branch.
4. We will merge the Pull Request once you have the sign-off.
## Developer Certificate of Origin
All commits to the project must be "signed off", which states that you agree to the terms of the [Developer Certificate of Origin](https://developercertificate.org/). This is done by adding a "Signed-off-by:" line in the commit message, with your name and email address.
Commits made through the GitHub web application are automatically signed off.
### Configuring Git to sign off commits
First, configure your name and email address in Git global settings:
This document explains how kubescape automates publishing to the Kubernetes plugin package manager, krew.
## What is Krew?
Krew is a plugin manager for `kubectl`. It allows users to discover and install `kubectl` plugins easily. You can learn more about krew at [https://krew.sigs.k8s.io/](https://krew.sigs.k8s.io/).
## How kubescape publishes to krew
We use the [krew-release-bot](https://github.com/rajatjindal/krew-release-bot) to automatically create pull requests to the [kubernetes-sigs/krew-index](https://github.com/kubernetes-sigs/krew-index) repository whenever a new release of kubescape is published.
### Setup Overview
The automation consists of three components:
1.**`.krew.yaml`** - A template file that the bot uses to generate the krew plugin manifest
2.**`.github/workflows/02-release.yaml`** - GitHub Actions workflow that runs the krew-release-bot after a successful release
3.**`.goreleaser.yaml`** - GoReleaser configuration that defines the krew manifest (though upload is skipped)
### Why Use krew-release-bot Instead of GoReleaser's Built-in Krew Support?
You might have noticed that **GoReleaser has built-in krew support** in its `krews` section. However, almost all projects (including stern) use `skip_upload: true` and rely on **krew-release-bot** instead. Here's why:
#### Problems with GoReleaser's Built-in Krew Publishing
To use GoReleaser's direct krew publishing, you would need to:
```yaml
krews:
- name:kubescape
skip_upload:false# Instead of true
repository:
owner:kubernetes-sigs
name:krew-index
token:"{{ .Env.KREW_INDEX_TOKEN }}"# Required!
pull_request:
enabled:true# Requires GoReleaser Pro for cross-repo PRs
```
This approach has several critical issues:
1.**Permission Barrier**: Almost no one has write access to `kubernetes-sigs/krew-index`. You would need special permissions from the Krew maintainers, which is rarely granted.
2.**Security Risk**: You'd need to store a GitHub personal access token with write access to the krew-index in your repository secrets. This token could be compromised and used to make unauthorized changes to the krew-index.
3.**GoReleaser Pro Required**: To create pull requests to a different repository (cross-repository), you need GoReleaser Pro, which is a paid product.
4.**Manual Work**: Even if you had access, you'd need to manually configure and maintain the repository settings, tokens, and potentially deal with rate limits and authentication issues.
#### Why krew-release-bot is the Right Solution
The **krew-release-bot** was created by the Kubernetes community (in collaboration with the Krew team) specifically to solve these problems:
- **No Repository Access Required**: The bot acts as an intermediary with pre-configured access to krew-index. You don't need write permissions.
- **No Tokens Needed**: It uses GitHub's `GITHUB_TOKEN` (automatically available in GitHub Actions) via webhooks and events. No personal access tokens required.
- **Designed for Krew**: It's specifically built for the krew-index workflow and integrates with Krew's automation.
- **Automatic Merging**: The Krew team has configured their CI to automatically test and merge PRs from krew-release-bot (usually within 5-10 minutes).
- **Officially Recommended**: The Krew team explicitly recommends this approach in their documentation as the standard way to automate plugin updates.
- **Free and Open Source**: No paid subscriptions required.
#### The Real-World Evidence
Looking at recent pull requests to `kubernetes-sigs/krew-index`, **almost all automated plugin updates are created by krew-release-bot**. You'll see patterns like:
```
Author: krew-release-bot
Title: "release new version v0.6.11 of radar"
```
This demonstrates that the entire Kubernetes ecosystem has standardized on krew-release-bot, not GoReleaser's built-in publishing.
#### Summary
While GoReleaser's built-in krew support exists in the code, it's **practically unusable for the krew-index repository** due to permission and security constraints. The krew-release-bot is the de facto standard because:
- It works without special permissions
- It's more secure
- It integrates with Krew's automation
- It's free and recommended by the Krew team
This is why we use `skip_upload: true` in GoReleaser and let krew-release-bot handle the actual publishing.
### The Template File
The `.krew.yaml` file in the repository root is a Go template that contains placeholders for dynamic values:
shortDescription:Scan resources and cluster configs against security frameworks.
description:|
Kubescape is the first tool for testing if Kubernetes is deployed securely
according to mitigations and best practices. It includes risk analysis,
security compliance, and misconfiguration scanning with an easy-to-use
CLI interface, flexible output formats, and automated scanning capabilities.
Features:
- Risk analysis: Identify vulnerabilities and security risks in your cluster
- Security compliance: Check your cluster against multiple security frameworks
- Misconfiguration scanning: Detect security misconfigurations in your workloads
- Flexible output: Results in JSON, SARIF, HTML, JUnit, and Prometheus formats
- CI/CD integration: Easily integrate into your CI/CD pipeline
homepage:https://kubescape.io/
caveats:|
Requires kubectl and basic knowledge of Kubernetes.
Run 'kubescape scan' to scan your Kubernetes cluster or manifests.
```
The `{{ .TagName }}` is replaced with the release tag (e.g., `v3.0.0`), `{{ trimPrefix "v" .TagName }}` removes the version prefix, and `{{ addURIAndSha ... }}` calculates the SHA256 checksum for the binary archive.
### Release Workflow
The release workflow (`.github/workflows/02-release.yaml`) can be triggered in two ways:
1.**Automatic**: When a new tag matching the pattern `v[0-9]+.[0-9]+.[0-9]+` is pushed to the repository
2.**Manual**: Via `workflow_dispatch` with an optional `skip_publish` input
When the workflow is triggered:
1. GoReleaser builds and publishes the release artifacts (unless `skip_publish=true` is set)
2. The krew-release-bot step runs conditionally:
- It **runs** when triggered by a tag push OR by `workflow_dispatch` with `skip_publish=false`
- It **skips** when triggered by `workflow_dispatch` with `skip_publish=true` (default)
3. When it runs, the bot:
- Reads the `.krew.yaml` template
- Fills in the template with release information
- Creates a pull request to the `kubernetes-sigs/krew-index` repository
- The PR is automatically tested and merged by krew's infrastructure
### Workflow Permissions
The release job has the following permissions:
```yaml
permissions:
actions:read
checks:read
contents:write
deployments:read
discussions:read
id-token:write
issues:read
models:read
packages:write
pages:read
pull-requests:read
repository-projects:read
statuses:read
security-events:read
attestations:read
artifact-metadata:read
```
These permissions are necessary for GoReleaser to create releases and upload artifacts.
### Testing the Template
Before committing changes to `.krew.yaml`, you can test how the template will be rendered using Docker:
```bash
docker run -v $(pwd)/.krew.yaml:/tmp/.krew.yaml ghcr.io/rajatjindal/krew-release-bot:v0.0.47 \
This will output the generated krew manifest file, allowing you to verify:
- The version field is correct
- All download URLs are properly formatted
- The SHA256 checksum will be calculated correctly
### Why skip_upload in GoReleaser?
In `.goreleaser.yaml`, the `krews` section has `skip_upload: true`:
```yaml
krews:
- name:kubescape
ids:
- cli
skip_upload:true# We use krew-release-bot instead
homepage:https://kubescape.io/
description:It includes risk analysis, security compliance, and misconfiguration scanning with an easy-to-use CLI interface, flexible output formats, and automated scanning capabilities.
short_description:Scan resources and cluster configs against security frameworks.
```
This is intentional because:
- GoReleaser generates the manifest but doesn't have built-in support for submitting PRs to krew-index
- krew-release-bot is the recommended tool for krew automation by the Krew team
- Using krew-release-bot provides automatic testing and merging of version bump PRs
### Manual Release Testing
You can test the release workflow manually without publishing to krew by using `workflow_dispatch`:
1. Go to Actions tab in GitHub
2. Select "02-create_release" workflow
3. Click "Run workflow"
4. The `skip_publish` input defaults to `true` (publishing will be skipped)
5. Set `skip_publish` to `false` if you want to test the full release process including krew indexing
### Making Changes to the Template
If you need to update the krew manifest (e.g., change the description, add platforms, or update the binary location):
1. Edit the `.krew.yaml` file
2. Test your changes with the Docker command shown above
3. Commit and push the changes
4. The next release will use the updated template
### Installing kubescape via krew
Once the plugin is indexed in krew, users can install it with:
```bash
kubectl krew install kubernetes-sigs/kubescape
```
Or after index update:
```bash
kubectl krew install kubescape
```
### Further Reading
- [Krew official documentation](https://krew.sigs.k8s.io/docs/developer-guide/)
_An open-source Kubernetes security platform for your IDE, CI/CD pipelines, and clusters_
_Comprehensive Kubernetes Security from Development to Runtime_
Kubescape is an open-source Kubernetes security platform. It includes risk analysis, security compliance, and misconfiguration scanning. Targeted at the DevSecOps practitioner or platform engineer, it offers an easy-to-use CLI interface, flexible output formats, and automated scanning capabilities. It saves Kubernetes users and admins precious time, effort, and resources.
Kubescape is an open-source Kubernetes security platform that provides comprehensive security coverage, from left to right across the entire development and deployment lifecycle. It offers hardening, posture management, and runtime security capabilities to ensure robust protection for Kubernetes environments.
Kubescape scans clusters, YAML files, and Helm charts. It detects misconfigurations according to multiple frameworks (including [NSA-CISA](https://www.armosec.io/blog/kubernetes-hardening-guidance-summary-by-armo/?utm_source=github&utm_medium=repository), [MITRE ATT&CK®](https://www.microsoft.com/security/blog/2021/03/23/secure-containerized-environments-with-updated-threat-matrix-for-kubernetes/) and the [CIS Benchmark](https://www.armosec.io/blog/cis-kubernetes-benchmark-framework-scanning-tools-comparison/?utm_source=github&utm_medium=repository)).
Kubescape was created by [ARMO](https://www.armosec.io/?utm_source=github&utm_medium=repository) and is a [Cloud Native Computing Foundation (CNCF) incubating project](https://www.cncf.io/projects/).
Kubescape was created by [ARMO](https://www.armosec.io/?utm_source=github&utm_medium=repository) and is a [Cloud Native Computing Foundation (CNCF) sandbox project](https://www.cncf.io/sandbox-projects/).
_Please [star ⭐](https://github.com/kubescape/kubescape/stargazers) the repo if you want us to continue developing and improving Kubescape!_
## Demo
<img src="docs/img/demo.gif">
---
_Please [star ⭐](https://github.com/kubescape/kubescape/stargazers) the repo if you want us to continue developing and improving Kubescape! 😀_
# Deploy the Kubescape CEL admission policy library
kubescape vap deploy-library | kubectl apply -f -
# Create a policy binding
kubescape vap create-policy-binding \
--name my-policy-binding \
--policy c-0016 \
--namespace my-namespace | kubectl apply -f -
```
### MCP Server
Start an MCP (Model Context Protocol) server for AI assistant integration:
```bash
kubescape mcpserver
```
The MCP server exposes Kubescape's vulnerability and configuration scan data to AI assistants, enabling natural language queries about your cluster's security posture.
Kubescape uses [Open Policy Agent](https://github.com/open-policy-agent/opa) to verify Kubernetes objects against [a library of posture controls](https://github.com/kubescape/regolibrary).
### Operator Mode (In-Cluster)
By default, the results are printed in a console-friendly manner, but they can be:
For continuous monitoring, deploy the Kubescape operator via Helm.
* exported to JSON or junit XML
* rendered to HTML or PDF
* submitted to a [cloud service](docs/providers.md)
It retrieves Kubernetes objects from the API server and runs a set of [Rego snippets](https://www.openpolicyagent.org/docs/latest/policy-language/) developed by [ARMO](https://www.armosec.io?utm_source=github&utm_medium=repository).
Kubescape is an open source project, we welcome your feedback and ideas for improvement. We are part of the Kubernetes community and are building more tests and controls as the ecosystem develops.
---
We hold [community meetings](https://us02web.zoom.us/j/84020231442) on Zoom, on the first Tuesday of every month, at 14:00 GMT.
## ☸️ In-Cluster Operator
The Kubescape project follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
The Kubescape operator provides continuous security monitoring in your cluster:
* Feel free to pick a task from the [issues](https://github.com/kubescape/kubescape/issues?q=is%3Aissue+is%3Aopen+label%3A%22open+for+contribution%22), [roadmap](docs/roadmap.md) or suggest a feature of your own.
*[Open an issue](https://github.com/kubescape/kubescape/issues/new/choose): we aim to respond to all issues within 48 hours.
*[Join the CNCF Slack](https://slack.cncf.io/) and then our [users](https://cloud-native.slack.com/archives/C04EY3ZF9GE) or [developers](https://cloud-native.slack.com/archives/C04GY6H082K) channel.
Kubescape changes are tracked on the [releases page](https://github.com/kubescape/kubescape/releases).
---
## License
Copyright 2021-2023, the Kubescape Authors. All rights reserved. Kubescape is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
Copyright 2021-2025, the Kubescape Authors. All rights reserved.
Kubescape is a [Cloud Native Computing Foundation (CNCF) sandbox project](https://www.cncf.io/sandbox-projects/) and was contributed by [ARMO](https://www.armosec.io/?utm_source=github&utm_medium=repository).
Kubescape is released under the [Apache 2.0 license](LICENSE).
Kubescape is a [Cloud Native Computing Foundation (CNCF) incubating project](https://www.cncf.io/projects/kubescape/) and was contributed by [ARMO](https://www.armosec.io/?utm_source=github&utm_medium=repository).
GOOS=linux GOARCH=amd64 go build -o kubescape-linux-amd64 .
# Linux (arm64)
GOOS=linux GOARCH=arm64 go build -o kubescape-linux-arm64 .
# macOS (amd64)
GOOS=darwin GOARCH=amd64 go build -o kubescape-darwin-amd64 .
# macOS (arm64 / Apple Silicon)
GOOS=darwin GOARCH=arm64 go build -o kubescape-darwin-arm64 .
# Windows (amd64)
GOOS=windows GOARCH=amd64 go build -o kubescape-windows-amd64.exe .
```
---
## Building Docker Images
Kubescape uses [GoReleaser](https://goreleaser.com/) to build its Docker images. The Dockerfiles are specifically designed to work with GoReleaser's build pipeline, which handles cross-compilation and places binaries in the expected directory structure.
### Build with GoReleaser
The recommended way to build Docker images locally is using GoReleaser. Note that `RELEASE`, `CLIENT`, and `RUN_E2E` environment variables are required:
```bash
# Build all artifacts and Docker images locally without publishing
# --skip=before,krew,nfpm,sbom skips unnecessary steps for faster local builds
Please read the [GoReleaser documentation](https://goreleaser.com/customization/dockers_v2/#testing-locally) for more details on using it for local testing.
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
# Install other tools as needed
go mod download
```
### Run Tests
```bash
# Run all tests
make test
# Run tests with coverage
go test -cover ./...
# Run specific package tests
go test ./core/...
```
### Run Linter
```bash
golangci-lint run
```
### Code Formatting
```bash
go fmt ./...
```
---
## Troubleshooting
### Build Fails with "module not found"
```bash
# Update dependencies
go mod tidy
go mod download
```
### CGO-related Errors
If you encounter CGO errors, try building with CGO disabled:
```bash
CGO_ENABLED=0 go build -o kubescape .
```
### Docker Build Fails
Ensure Docker daemon is running and you have sufficient permissions.
If you encounter an error like `failed to calculate checksum ... "/linux/amd64/kubescape": not found`, it usually means you are trying to run `docker build` manually. Because the Dockerfiles are optimized for GoReleaser, you should use the `goreleaser release --snapshot` command described in the [Building Docker Images](#building-docker-images) section instead.
```bash
# Check Docker status
docker info
```
### Out of Memory During Build
For systems with limited memory:
```bash
# Limit Go's memory usage
GOGC=50 go build -o kubescape .
```
---
## Dockerfiles
| File | Description |
|------|-------------|
| `build/Dockerfile` | Full Kubescape image with HTTP handler |
Short:"Delete configurations in Kubescape SaaS version",
Long:``,
Run:func(cmd*cobra.Command,args[]string){
},
}
deleteCmd.PersistentFlags().StringVarP(&deleteInfo.Credentials.Account,"account","","","Kubescape SaaS account ID. Default will load account ID from cache")
deleteCmd.PersistentFlags().StringVarP(&deleteInfo.Credentials.ClientID,"client-id","","","Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armosec.io/docs/authentication")
deleteCmd.PersistentFlags().StringVarP(&deleteInfo.Credentials.SecretKey,"secret-key","","","Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armosec.io/docs/authentication")
downloadCmd.PersistentFlags().StringVarP(&downloadInfo.Credentials.Account,"account","","","Kubescape SaaS account ID. Default will load account ID from cache")
downloadCmd.PersistentFlags().StringVarP(&downloadInfo.Credentials.ClientID,"client-id","","","Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armosec.io/docs/authentication")
downloadCmd.PersistentFlags().StringVarP(&downloadInfo.Credentials.SecretKey,"secret-key","","","Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armosec.io/docs/authentication")
downloadCmd.PersistentFlags().StringVarP(&downloadInfo.AccountID,"account","","","Kubescape SaaS account ID. Default will load account ID from cache")
downloadCmd.PersistentFlags().StringVarP(&downloadInfo.AccessKey,"access-key","","","Kubescape SaaS access key. Default will load access key from cache")
downloadCmd.Flags().StringVarP(&downloadInfo.Path,"output","o","","Output file. If not specified, will save in `~/.kubescape/<policy name>.json`")
listCmd.PersistentFlags().StringVarP(&listPolicies.Credentials.Account,"account","","","Kubescape SaaS account ID. Default will load account ID from cache")
listCmd.PersistentFlags().StringVarP(&listPolicies.Credentials.ClientID,"client-id","","","Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armosec.io/docs/authentication")
listCmd.PersistentFlags().StringVarP(&listPolicies.Credentials.SecretKey,"secret-key","","","Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armosec.io/docs/authentication")
listCmd.PersistentFlags().StringVarP(&listPolicies.AccountID,"account","","","Kubescape SaaS account ID. Default will load account ID from cache")
listCmd.PersistentFlags().StringVarP(&listPolicies.AccessKey,"access-key","","","Kubescape SaaS access key. Default will load access key from cache")
mcp.WithTemplateDescription("Complete vulnerability manifest either for a specific workload or image. Use 'list_vulnerability_manifests' tool to discover available manifests."),
mcp.WithDescription("Discover available security configuration scan results at workload level (this returns a list of manifests, not the scan results themselves, to get the scan results, use the get_configuration_security_scan_manifest tool)"),
mcp.WithString("namespace",
mcp.Description("Filter by namespace (optional)"),
mcp.WithTemplateDescription("Complete configuration scan manifest for a specific workload. Use 'list_configuration_security_scan_manifests' tool to discover available manifests."),
logger.L().Start("Kubescape Operator Triggering for configuration scanning")
_,err=operatorAdapter.OperatorScan()
iferr!=nil{
logger.L().StopError("Failed to triggering Kubescape Operator for configuration scanning",helpers.Error(err))
returnerr
}
logger.L().StopSuccess("Triggered Kubescape Operator for configuration scanning")
returnnil
},
}
configScanInfo:=&cautils.ConfigScanInfo{}
operatorInfo.OperatorScanInfo=configScanInfo
configCmd.PersistentFlags().StringSliceVar(&configScanInfo.IncludedNamespaces,"include-namespaces",nil,"scan specific namespaces. e.g: --include-namespaces ns-a,ns-b")
configCmd.PersistentFlags().StringSliceVar(&configScanInfo.ExcludedNamespaces,"exclude-namespaces",nil,"Namespaces to exclude from scanning. e.g: --exclude-namespaces ns-a,ns-b. Notice, when running with `exclude-namespace` kubescape does not scan cluster-scoped objects.")
configCmd.PersistentFlags().StringSliceVar(&configScanInfo.Frameworks,"frameworks",nil,"Load frameworks for configuration scanning")
configCmd.PersistentFlags().BoolVarP(&configScanInfo.HostScanner,"enable-host-scan","",false,"Deploy Kubescape host-sensor daemonset in the scanned cluster. Deleting it right after we collecting the data. Required to collect valuable data from cluster nodes for certain controls. Yaml file: https://github.com/kubescape/kubescape/blob/master/core/pkg/hostsensorutils/hostsensor.yaml")
returnfmt.Errorf("for the operator sub-command, only %s and %s are supported. Refer to the examples above",vulnerabilitiesSubCommand,configurationsSubCommand)
}
returnnil
},
}
operatorCmd.PersistentFlags().StringVar(&operatorInfo.Namespace,"namespace","kubescape","namespace of the Kubescape Operator")
expectedErrorMessage="for the operator sub-command, only "+vulnerabilitiesSubCommand+" and "+configurationsSubCommand+" are supported. Refer to the examples above"
logger.L().Start("Triggering the Kubescape Operator for vulnerability scanning")
_,err=operatorAdapter.OperatorScan()
iferr!=nil{
logger.L().StopError("Failed to trigger the Kubescape Operator for vulnerability scanning",helpers.Error(err))
returnerr
}
logger.L().StopSuccess("Triggered Kubescape Operator for vulnerability scanning. View the scanning results once they are ready using the following command: \"kubectl get vulnerabilitysummaries\"")
The patch command is used for patching container images with vulnerabilities.
It uses [copa](https://github.com/project-copacetic/copacetic) and [buildkit](https://github.com/moby/buildkit) under the hood for patching the container images, and [grype](https://github.com/anchore/grype) as the engine for scanning the images (at the moment).
## Usage
```bash
kubescape patch --image <image-name> [flags]
```
The patch command can be run in 2 ways:
1.**With sudo privileges**
You will need to start `buildkitd` if it is not already running
* Run with '--verbose'/'-v' flag for detailed vulnerabilities view
* Install Kubescape in your cluster for continuous monitoring and a full vulnerability report: https://github.com/kubescape/helm-charts/tree/main/charts/kubescape-cloud-operator
```
## Limitations
- The patch command can only fix OS-level vulnerability. It cannot fix application-level vulnerabilities. This is a limitation of copa. The reason behind this is that application level vulnerabilities are best suited to be fixed by the developers of the application.
Hence, this is not really a limitation but a design decision.
- No support for windows containers given the dependency on buildkit.
patchCmd.PersistentFlags().StringVarP(&patchInfo.Image,"image","i","","Application image name and tag to patch")
patchCmd.PersistentFlags().StringVarP(&patchInfo.PatchedImageTag,"tag","t","","Tag for the patched image. Defaults to '<image-tag>-patched' ")
patchCmd.PersistentFlags().StringVarP(&patchInfo.BuildkitAddress,"address","a","unix:///run/buildkit/buildkitd.sock","Address of buildkitd service, defaults to local buildkitd.sock")
patchCmd.PersistentFlags().DurationVar(&patchInfo.Timeout,"timeout",5*time.Minute,"Timeout for the operation, defaults to '5m'")
patchCmd.PersistentFlags().BoolVar(&patchInfo.IgnoreError,"ignore-errors",false,"Ignore errors and continue patching other images. Default to false")
patchCmd.PersistentFlags().StringVarP(&patchInfo.Username,"username","u","","Username for registry login")
patchCmd.PersistentFlags().StringVarP(&patchInfo.Password,"password","p","","Password for registry login")
patchCmd.PersistentFlags().StringVarP(&scanInfo.Output,"output","o","","Output file. Print output to file and not stdout")
patchCmd.PersistentFlags().BoolVarP(&scanInfo.VerboseMode,"verbose","v",false,"Display full report. Default to false")
patchCmd.PersistentFlags().StringVarP(&scanInfo.FailThresholdSeverity,"severity-threshold","s","","Severity threshold is the severity of a vulnerability at which the command fails and returns exit code 1")
patchCmd.PersistentFlags().BoolVarP(&useDefaultMatchers,"use-default-matchers","",true,"Use default matchers (true) or CPE matchers (false) for image scanning")
returnpatchCmd
}
// validateImagePatchInfo validates the image patch info for the `patch` command
kubeconfigPath=preReqCmd.PersistentFlags().String("kubeconfig","","Path to the kubeconfig file. If not set, in-cluster config is used or $HOME/.kube/config if outside a cluster.")
rootCmd.PersistentFlags().StringVar(&rootInfo.DiscoveryServerURL,"server","","Backend discovery server URL")
rootCmd.PersistentFlags().MarkDeprecated("environment","'environment' is no longer supported, Use 'server' instead. Feel free to contact the Kubescape maintainers for more information.")
rootCmd.PersistentFlags().MarkDeprecated("env","'env' is no longer supported, Use 'server' instead. Feel free to contact the Kubescape maintainers for more information.")
constenvFlagUsage="Send report results to specific URL. Format:<ReportReceiver>,<Backend>,<Frontend>.\n\t\tExample:report.armo.cloud,api.armo.cloud,portal.armo.cloud"
funcinitLogger(){
logger.DisableColor(rootInfo.DisableColor)
logger.EnableColor(rootInfo.EnableColor)
ifrootInfo.LoggerName==""{
ifl:=os.Getenv("KS_LOGGER_NAME");l!=""{
rootInfo.LoggerName=l
}else{
ifisatty.IsTerminal(os.Stdout.Fd()){
rootInfo.LoggerName="pretty"
rootInfo.LoggerName=iconlogger.LoggerName
}else{
rootInfo.LoggerName="zap"
rootInfo.LoggerName=zaplogger.LoggerName
}
}
}
logger.InitLogger(rootInfo.LoggerName)
}
funcinitLoggerLevel(){
ifrootInfo.Logger==helpers.InfoLevel.String(){
}elseifl:=os.Getenv("KS_LOGGER");l!=""{
@@ -56,35 +56,51 @@ func initCacheDir() {
logger.L().Debug("cache dir updated",helpers.String("path",getter.DefaultLocalStore))
logger.L().Fatal("failed to get services from server",helpers.Error(err),helpers.String("server",rootInfo.DiscoveryServerURL))
return
}
logger.L().Debug("configuring service discovery URLs",helpers.String("cloudAPIURL",services.GetApiServerUrl()),helpers.String("cloudReportURL",services.GetReportReceiverHttpUrl()))
assert.Equal(t,fmt.Sprintf("The framework you wish to use. Run '%[1]s list frameworks' for the list of supported frameworks",cautils.ExecName()),cmd.Short)
assert.Equal(t,frameworkExample,cmd.Example)
err:=cmd.Args(&cobra.Command{},[]string{})
expectedErrorMessage:="requires at least one framework name"
scanCmd.PersistentFlags().StringVarP(&scanInfo.Credentials.Account,"account","","","Kubescape SaaS account ID. Default will load account ID from cache")
scanCmd.PersistentFlags().BoolVar(&scanInfo.CreateAccount,"create-account",false,"Create a Kubescape SaaS account ID account ID is not found in cache. After creating the account, the account ID will be saved in cache. In addition, the scanning results will be uploaded to the Kubescape SaaS")
scanCmd.PersistentFlags().StringVarP(&scanInfo.Credentials.ClientID,"client-id","","","Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armosec.io/docs/authentication")
scanCmd.PersistentFlags().StringVarP(&scanInfo.Credentials.SecretKey,"secret-key","","","Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armosec.io/docs/authentication")
scanCmd.PersistentFlags().StringVarP(&scanInfo.KubeContext,"kube-context","","","Kube context. Default will use the current-context")
scanInfo.TriggeredByCLI=true
scanCmd.PersistentFlags().StringVarP(&scanInfo.AccountID,"account","","","Kubescape SaaS account ID. Default will load account ID from cache")
scanCmd.PersistentFlags().StringVarP(&scanInfo.AccessKey,"access-key","","","Kubescape SaaS access key. Default will load access key from cache")
scanCmd.PersistentFlags().StringVar(&scanInfo.ControlsInputs,"controls-config","","Path to an controls-config obj. If not set will download controls-config from ARMO management portal")
scanCmd.PersistentFlags().StringVar(&scanInfo.UseExceptions,"exceptions","","Path to an exceptions obj. If not set will download exceptions from ARMO management portal")
scanCmd.PersistentFlags().StringVar(&scanInfo.UseArtifactsFrom,"use-artifacts-from","","Load artifacts from local directory. If not used will download them")
scanCmd.PersistentFlags().StringVarP(&scanInfo.ExcludedNamespaces,"exclude-namespaces","e","","Namespaces to exclude from scanning. Notice, when running with `exclude-namespace` kubescape does not scan cluster-scoped objects.")
scanCmd.PersistentFlags().StringVarP(&scanInfo.ExcludedNamespaces,"exclude-namespaces","e","","Namespaces to exclude from scanning. e.g: --exclude-namespaces ns-a,ns-b. Notice, when running with `exclude-namespace` kubescape does not scan cluster-scoped objects.")
scanCmd.PersistentFlags().Float32VarP(&scanInfo.FailThreshold,"fail-threshold","t",100,"Failure threshold is the percent above which the command fails and returns exit code 1")
scanCmd.PersistentFlags().Float32VarP(&scanInfo.ComplianceThreshold,"compliance-threshold","",0,"Compliance threshold is the percent below which the command fails and returns exit code 1")
scanCmd.PersistentFlags().StringVar(&scanInfo.FailThresholdSeverity,"severity-threshold","","Severity threshold is the severity of failed controls at which the command fails and returns exit code 1")
scanCmd.PersistentFlags().StringVar(&scanInfo.IncludeNamespaces,"include-namespaces","","scan specific namespaces. e.g: --include-namespaces ns-a,ns-b")
scanCmd.PersistentFlags().BoolVarP(&scanInfo.Local,"keep-local","",false,"If you do not want your Kubescape results reported to configured backend.")
scanCmd.PersistentFlags().StringVarP(&scanInfo.Output,"output","o","","Output file. Print output to file and not stdout")
scanCmd.PersistentFlags().BoolVarP(&scanInfo.VerboseMode,"verbose","v",false,"Display all of the input resources and not only failed resources")
scanCmd.PersistentFlags().StringVar(&scanInfo.View,"view",string(cautils.ResourceViewType),fmt.Sprintf("View results based on the %s/%s. default is --view=%s",cautils.ResourceViewType,cautils.ControlViewType,cautils.ResourceViewType))
scanCmd.PersistentFlags().StringVar(&scanInfo.View,"view",string(cautils.SecurityViewType),fmt.Sprintf("View results based on the %s/%s/%s. default is --view=%s",cautils.ResourceViewType,cautils.ControlViewType,cautils.SecurityViewType,cautils.SecurityViewType))
scanCmd.PersistentFlags().BoolVar(&scanInfo.UseDefault,"use-default",false,"Load local policy object from default path. If not used will download latest")
scanCmd.PersistentFlags().StringSliceVar(&scanInfo.UseFrom,"use-from",nil,"Load local policy object from specified path. If not used will download latest")
scanCmd.PersistentFlags().StringVar(&scanInfo.HostSensorYamlPath,"host-scan-yaml","","Override default host scanner DaemonSet. Use this flag cautiously")
scanCmd.PersistentFlags().BoolVarP(&scanInfo.Submit,"submit","",false,"Submit the scan results to Kubescape SaaS where you can see the results in a user-friendly UI, choose your preferred compliance framework, check risk results history and trends, manage exceptions, get remediation recommendations and much more. By default the results are not submitted")
scanCmd.PersistentFlags().BoolVarP(&scanInfo.OmitRawResources,"omit-raw-resources","",false,"Omit raw resources from the output. By default the raw resources are included in the output")
scanCmd.PersistentFlags().BoolVarP(&scanInfo.EnableRegoPrint,"enable-rego-prints","",false,"Enable sending to rego prints to the logs (use with debug log level: -l debug)")
scanCmd.PersistentFlags().BoolVarP(&scanInfo.UseDefaultMatchers,"use-default-matchers","",true,"Use default matchers (true) or CPE matchers (false) for image scanning")
scanCmd.PersistentFlags().StringSliceVar(&scanInfo.LabelsToCopy,"labels-to-copy",nil,"Labels to copy from workloads to scan reports for easy identification. e.g: --labels-to-copy=app,team,environment")
scanCmd.PersistentFlags().MarkDeprecated("silent","use '--logger' flag instead. Flag will be removed at 1.May.2022")
scanCmd.PersistentFlags().MarkDeprecated("fail-threshold","use '--compliance-threshold' flag instead. Flag will be removed at 1.Dec.2023")
scanCmd.PersistentFlags().MarkDeprecated("create-account","Create account is no longer supported. In case of a missing Account ID and a configured backend server, a new account id will be generated automatically by Kubescape. Feel free to contact the Kubescape maintainers for more information.")
// hidden flags
scanCmd.PersistentFlags().MarkHidden("host-scan-yaml")// this flag should be used very cautiously. We prefer users will not use it at all unless the DaemonSet can not run pods on the nodes
hostF:=scanCmd.PersistentFlags().VarPF(&scanInfo.HostSensorEnabled,"enable-host-scan","","Deploy Kubescape host-sensor daemonset in the scanned cluster. Deleting it right after we collecting the data. Required to collect valuable data from cluster nodes for certain controls. Yaml file: https://github.com/kubescape/kubescape/blob/master/core/pkg/hostsensorutils/hostsensor.yaml")
scanCmd.PersistentFlags().MarkDeprecated("enable-host-scan","To activate the host scanner capability, proceed with the installation of the kubescape operator chart found here: https://github.com/kubescape/helm-charts/tree/main/charts/kubescape-operator. The flag will be removed at 1.Dec.2023")
scanCmd.PersistentFlags().MarkHidden("host-scan-yaml")// this flag should be used very cautiously. We prefer users will not use it at all unless the DaemonSet can not run pods on the nodes
scanCmd.PersistentFlags().MarkDeprecated("host-scan-yaml","To activate the host scanner capability, proceed with the installation of the kubescape operator chart found here: https://github.com/kubescape/helm-charts/tree/main/charts/kubescape-operator. The flag will be removed at 1.Dec.2023")
workloadCmd.PersistentFlags().StringVarP(&namespace,"namespace","n","","Namespace of the workload. Default will be empty.")
workloadCmd.PersistentFlags().StringVar(&scanInfo.FilePath,"file-path","","Path to the workload file.")
workloadCmd.PersistentFlags().StringVar(&scanInfo.ChartPath,"chart-path","","Path to the helm chart the workload is part of. Must be used with --file-path.")
resultsCmd.PersistentFlags().StringVar(&formatVersion,"format-version","v2","Output object can be different between versions, this is for maintaining backward and forward compatibility. Supported:'v1'/'v2'")
Short:"Submit an object to the Kubescape SaaS version",
Long:``,
Example:submitCmdExamples,
Run:func(cmd*cobra.Command,args[]string){
},
}
submitCmd.PersistentFlags().StringVarP(&submitInfo.Credentials.Account,"account","","","Kubescape SaaS account ID. Default will load account ID from cache")
submitCmd.PersistentFlags().StringVarP(&submitInfo.Credentials.ClientID,"client-id","","","Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armosec.io/docs/authentication")
submitCmd.PersistentFlags().StringVarP(&submitInfo.Credentials.SecretKey,"secret-key","","","Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armosec.io/docs/authentication")
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.