 Hi everyone, I'm Tepe Fukuda from the open source team in Aqua Security and the maintainer of TV, which is a vulnerability scanner for container images. Today, I'll be talking about vulnerability handling with open policy agent. There are a lot of software vulnerabilities in the world. Usually, CVID is assigned to each vulnerability. In order to protect your system from attacks, you need to detect container vulnerabilities in advance. There are a lot of security solutions in the cloud native area, and you can use them for the purpose. This sometimes shows a lot of vulnerabilities. However, you don't have to address all vulnerabilities. Take a look at this chart. A vulnerability basically has a CVSS base score indicating stability. The score varies from 0 to 10. 10 means the most critical. CVSS consists of three metric groups, base, temporal, and environmental. But in this session, I'll be talking about base metrics and the score because NVIDIA provides base metrics only. As you can see, there are not so many high-risk vulnerabilities. Only 5.7% of the vulnerabilities have a score of 8 or more. Probably, you can accept the low-risk vulnerabilities. But third CC claims CVSS was designed to measure the technical stability of a vulnerability but is widely misused as a means of vulnerability prioritization and assessing risk. Yes, it's true. Actually, the CVSS score is different from the impact on the organization. Also, they mentioned that the scoring algorithm is not well-justified and lacks the transparency needed for the community to understand its intended function. Also, I don't recommend using CVSS base score only for handling vulnerabilities. I'd like to suggest you define your own policy for prioritizing vulnerabilities and assessing the risk because the policy depends on your system and organization. For example, the risk of bash vulnerabilities can be accepted because bash is not internet-facing. Also, the risk of cross-site scripting can be accepted because the system is static. But of course, it depends on your requirement. The cross-site scripting might be critical for some systems. A policy should be like this. If a vulnerability matches any rule, we can classify it as negligible. But if a vulnerability doesn't match any rules, you should update the version or fix the security issue somehow. Actually, there is thermal use-free information for vulnerability handling, such as CVSS vector and CWIB. CVSS vector string consists of eight elements called CVSS metrics. Each metric value is used to score the vulnerability. For example, attack vector. This metric reflects the context by which vulnerability exploitation is possible. This metric value will be larger than more remote and attacker can be in order to exploit the vulnerable component. In addition to attack vector, you can find privilege required, user interaction, and so on. CWE common weakness enumeration aims to provide a common base to identify the type of software vulnerability. For example, CWE-17-8 is OS command injection and CWE-89 is SQL injection. Now, you can relate the policy using these metrics. If you want to know if the vulnerability is excess, you can check if CWIB is CWE-79 or not. If you want to know if the vulnerability requires user interaction, you can check if user interaction in CVSS vector is required. So, it allows you to handle vulnerabilities automatically. And I propose to use Open Policy Agent to automate vulnerability handling. Open Policy Agent is open source policy engine and the CNSF project. You have to write a policy written by Wego and pass it to Opera with input JSON. Opera evaluates the policy and returns the result. It's usable as a library and service. Now, you can put the policy into Wego. The policy written in Wego should be like this. On the right, you can see the vulnerability detail of the input. You can see the package name, CWID, CWID, CVSS score vector. On the left, you can see the pretty simple rules. If the package name is BASH, or CWID is CWE-79, or user interaction is required, or CVSS base score is less than 7, the vulnerability is going to be negligible. Note that the vulnerability information is not always correct. If the vulnerability sets user interaction is required, it might be wrong. Don't trust the vulnerability information too much. Even if it's correct and the policy marks it are negligible, it doesn't mean there is no risk. It means you decide to accept the risk. The balance of risk and cost is important. If there are many people in a security team and the organization can take the cost of security, you may be able to look into their patches and the primary source of all vulnerabilities. If it's not the case in your organization, you probably need the policy to accept some risk. As a case study, here's a look at the Ropa integration in Truby. Before that, let me explain Truby a little. It's an open source scanner for container images. Truby has a bunch of features, and especially it can be integrated into the CI system, such as guitar action and Jenkins easily. Recently, Truby supported Ropa integration to filter vulnerabilities. You can pass a regular file defining your policy via minus-minus-ignore-policy option. If your policy marks the vulnerability negligible, it will not be displayed in the result. The structure of each vulnerability input is the same as for the Truby JSON output. It includes civility, CWIDs, CVSS vector, score, and so on. Also, it provides helper functions in rego, like pass CVSS vector with rig, which converts CVSS vector string to an object so that you can easily access each metric. This example ignores some packages like bash, binder license, rpn, and pn, because they are not used in the production environment. Of course, unnecessary packages should be removed from a container image. If it's difficult, you can ignore those packages in a regular policy. Then, vulnerabilities with low and medium civility can be accepted. Also, when it's not exploitable remotely, or it requires high privilege, like administration, needs user interaction, and they will be marked as negligible in this example. Okay, so let me show the demo of Ropa integration in Truby CLI. At first, let's try scanning CentOS 7 without any policy. In this demo, the result detail is not needed, so I redirected it to Webner. Because it's a number of vulnerabilities, 622, it's a hard task to check all vulnerabilities. Next, looking into the policy example, as I explained, it ignores some packages, some civilities, and a vulnerability that can't be exploited remotely, or requires high privilege, like administrator, or requires user interaction, or cross-side request forgery, in this case. Okay, let's apply this policy to the result to be showed. You can press the regular file via minus minus ignore policy option. As you can see, there are 7 vulnerabilities only in the result with the policy. As you saw in the image, CentOS 7 shows 600 vulnerabilities without policy, but it would be only 7 with the policy. Less is not always better. You have to tune your policy according to the requirement in your organization. At last, let me explain opera integration in Kubernetes. This technique can be applied to any scanner, but as proof of concept, I developed a Kubernetes operator called Tribi Enforcer. It works as custom controller to scan an image in advance, and admission controller to validate an image a user tries to deploy. Let's take a look at the architecture. At first, I use the registers and image names I want to deploy as a custom resource. Tribi Enforcer watches the custom resource as a custom controller and fetches the image name. Then, it sends the image name to Tribi Server for vulnerability scanning. To be sober, return the scan result. At last, Tribi Enforcer updates the custom resource with those vulnerabilities. The scan result of the image must exist before you try to deploy it. Besides, a user needs to upload their policy to ConfigMap. Could management provide it by operating, which is ConfigMap, and load the policy into OperaService? What matters is that you can take advantage of the same policy you use with Tribi CLI. And Tribi Enforcer calls OperaService through a rest API. When the user is trying to deploy an image, Cluband has an API sends an admission review to Tribi Enforcer. And the request contains an image name. Tribi Enforcer retrieves the custom resource that matches the image name and extracts the result of vulnerabilities. If there is no scan result, it rejects the image immediately. Then, it sends the vulnerabilities to OperaService. Opera evaluates those vulnerabilities according to the policy. If one of them violates the policy, it returns the deny response. If there is no vulnerability, violating the policy Tribi Enforcer allows the deploy of the image. If you want to see a demo of this Cluband's integration, you can find it in my presentation at CubeCon Europe 2020. The video was uploaded to YouTube, so you can watch it on YouTube. So, you can apply image assurance throughout the developmental cycle. In local development and continuous integration, you can run Tribi CLI with a minus-minus-even-off-policy option. Then, Tribi Enforcer can be used in the Cluband test cluster to reject deploying an image with critical vulnerabilities. The important thing is that you can share the same policy across the whole process. Note that there are still experimental features and not stable. What I wanted to get across in this presentation is that we should define a custom policy for vulnerability handling based on your organization's risk acceptance. Then, Open Policy Agents can be used for that purpose. We can find some proof of concept as Open Integration with Tribi. In those PLC, you can take advantage of the same Open Policy throughout the development lifecycle.