trivy icon indicating copy to clipboard operation
trivy copied to clipboard

distribute misconfiguration policies out of band

Open itaysk opened this issue 1 year ago • 1 comments

Currently Trivy's misconfiguration scanning/IaC scanning checks are embedded into the Trivy binary and shipped with it. This means that in order to update checks a user needs to update Trivy, which is not ideal. This issue is about separating the checks from the engine and distributing the checks package to existing clients, just like vulnerability scanning which downloads the Trivy vulnerability database automatically.

History and related work

Originally, Trivy's misconfiguration scanning relied on rego policies from appshield that were packaged into an OCI artifact stored in GHCR and distributed to the Trivy client automatically. When we started centralizing checks in defsec and merging with Terraform/CloudFormation checks which were written in Go, we deprecated this mechanism and started simply embedding all the checks.

Recently there was an attempt to extend the trivy DB to accommodate arbitrary data, in that case for the Kubernetes API compatibility feature. But this was later reverted in favor of embedding the data in defsec.

itaysk avatar Sep 20 '22 09:09 itaysk

Discussion points:

  • Air-gapped scanning
  • Compatibility issues (e.g. policy -> engine)
  • Schema changes + custom policies
  • Include rego schemas in distribution?
  • How to track required schema versions + version schemas
  • Should we keep rules in the defsec repo but distribute a release artifact containing the policies? Coupling of defsec -> rules is fairly high, so there may be few advantages to creating a separate repo?

liamg avatar Sep 20 '22 13:09 liamg

For the moment at the end of the last call we agreed as a first step:

  • Package all rules up into an image and tag with the latest defsec version (separate major, major.minor and major.minor.patch tags)
  • Add a function to defsec that knows how to download the latest MAJOR image that matches it's version
  • Call this function from trivy and add all rego from the image to the trivy cache directory to a subdirectory named iac-rules
  • Trivy should instruct defsec to look in this directory to find all rules, excluding builtin ones.

liamg avatar Sep 26 '22 15:09 liamg

Same as this approach? https://github.com/aquasecurity/appshield/pkgs/container/appshield

knqyf263 avatar Sep 28 '22 14:09 knqyf263

Yep, we've come full circle :recycle:

liamg avatar Sep 28 '22 18:09 liamg

To add to what @liamg said and to summarize my chat with him, I would like to propose the following:

  1. Bringing back the OCI artifact policy logic into Trivy, with necessary changes. I have a working PoC to demo that this could be done with very minimal logic changes needed. Later on if there's a need we could abstract it out.
  2. If we do so, we'd have at our disposal the following ways to specify rules:
    1. Use embedded policies (current, good for air-gapped solutions, or those who are fine with existing policies)
    2. Use published policies (fetches the defsec OCI artifact, could have the option to specify URL too later)
    3. Use custom local policies (air-gapped, custom policy use cases)
      1. Custom policy + embedded libraries
      2. Custom libraries + embedded policies (I doubt this would make sense for someone)

Trivy should instruct defsec to look in this directory to find all rules, excluding builtin ones.

I would agree with this. To start, we could make the above choices exclusive of each other. Which means you can only use one of the options and not a combination of them.

The combination of any of them will be a little more involved as there could be possible rego namespace collisions with variety of policies, for instance.

simar7 avatar Sep 29 '22 00:09 simar7

hi all,

I'd just like to share my update on this prior to my upcoming vacation just in case any of you wanted to pick it up while I was gone.

I’ve pushed my changes to Trivy on a branch here https://github.com/aquasecurity/trivy/compare/policy-fetcher?expand=1 feel free to push any changes to it if you pick it up.

Most of that is old logic we used to have in the past with appshield (minus the tests as it's still a WIP). It's been adapted to use defsec.

We would probably need to figure out what set of options we'd like to have. Currently we've deprecated --skip-policy-update and in my branch I've added an option to --disable-embedded-policies. I need to think a little more about it to see if that's the best choice but I welcome any suggestions.

simar7 avatar Sep 30 '22 00:09 simar7

Some more info, if you need to test locally how to setup and run you could do this:

  1. setup a local registry: docker run -it --rm -p 5000:5000 registry
  2. bundle and push an artifact rm -rf bundle bundle.tar.gz && rsync -avr --exclude=README.md --exclude="*_test.rego" --exclude="*.go" --exclude=test --exclude=advanced internal/rules/docker internal/rules/kubernetes bundle/ && cp internal/rules/.manifest bundle/ && sed -i -e "s/\[GITHUB_SHA\]/25bc95418f1181cc211121f678f4725c26112209325ccfbf389e1e3dd7f8cb46/" bundle/.manifest && tar -C bundle -czvf bundle.tar.gz . && oras push localhost:5000/defsec:1 --config /dev/null:application/vnd.cncf.openpolicyagent.config.v1+json bundle.tar.gz:application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip
  3. run trivy by removing any cached policies and metadata.json: rm -rf /Users/simar/Library/Caches/trivy/policy/metadata.json /Users/simar/Library/Caches/trivy/policy/content/ && rm -rf ./trivy && make build && ./trivy --debug conf --skip-policy-update=true --disable-embedded-policies=true /Users/simar/repos/defsec/test/testdata/dockerfile/DS005

should scan and detect as usual.

simar7 avatar Sep 30 '22 00:09 simar7

PR is ready for review: https://github.com/aquasecurity/trivy/pull/3015

simar7 avatar Oct 19 '22 01:10 simar7