 It is time to get started. So this is the Coverno introduction and overview session. If you thought that you were coming to something else, I'm sorry to disappoint you, but I hope that we're able to delight you instead. My name is Chip Zoller. I'm a technical product manager at Nermata, and I'm joined by my colleague, Dala Sharma. So my name is Dulles, and I'm a customer success engineer at Nermata, and I'm based out of Halifax, which is in Oaxaca, Canada. And I'm also a Coverno maintainer. And I do have a couple questions for the audience just by a show of hands. You can just look up from your laptop from just a second. So first question, please raise your hand if you're running Kubernetes in production at least one way. Who is running Kubernetes in production? All right, hands down. Raise your hands again if you are using some policy for your production Kubernetes cluster. Who is using some policy? Okay, cool, good to know. All right, hand it over to Dala's. Thank you, Chip. Okay, so today we are gonna talk about Coverno introduction and overview. I will talk an overview of why we need policies and what is Coverno and Chip will later on dig deeper into types of policies and some interesting use cases. Okay, so starting with that. Wrong direction. Okay, I'm sorry. So let's start with why we need policies today. So if I have to give you a general example that why policy, you can look at an example that using a single cube cut will come on. How can a user get access to the entire host? So he or she can run just a single command and they can get access to the entire host. There might be different reasons this might be occurring. First is that you might not even know that this is a bad pod and you're not supposed to run it. There might be other reasons like we don't have any guardrails in this environment. So these kinds of requests are not blocked. There are no policies that are running that is actually blocking or auditing these kind of requests. And then as more people get involved, they have different backgrounds. They have their own tribal information that they come up and they don't know what to do and what not to do. And of course, Kubernetes is hard. So someone who is new to Kubernetes will find it difficult to get everything in the first code. So yeah, we need policies. We need policies to make sure that such kind of incidents or scenario doesn't happen or is blocked or at least audited. So what can policy deliver? Policy can define laws and it can define some guardrails that can help you to block such kind of request. It provides a proper check and it makes you visible to your security posture of your cluster. So what you can do is using policies, you can define some rules, you can define some guardrails and make sure that the security posture of your cluster is good. Once you have these policies, you can centrally control them and when you're applying them, you get consistency. So you're applying these policies and you're getting security-wise consistency for across all your environment. Once you deploy policies, you'll get violations, you'll get a report, you'll see what's failing, what's not working. This will give you more visibility into your cluster, into your environment. And then policies can perform automations. So policies can do couple of things, they can automate couple of things. We talk about such use cases deeper in next slides, but yes, that is one more interesting things policy can do. And all of this, actually, the important thing is deploying policies, what policies can deliver is it sets certain expectations of others. So if such kind of requests are blocked, people know that, okay, these are the expectations and we are not supposed to deploy something like that, which all in one saves your time, it's reliable and it makes the security side of the cluster very easy. So a little bit about Qverno. Qverno means govern in Greek. It's a CNCF incubated project. It's a policy engine, which is a Kubernetes admission controller. It's natively built for Kubernetes, that means it is easily integrated for Kubernetes. You do not require any programming language to create a policy or write a policy. So if you know Kubernetes, if you are good with YAML, you understand the YAML, the syntax, the format of it, you are good. You can write your policy. There are a lot of policies available, but you can start writing your policy from day one. And it's most popular by start in the policy engine and we have the largest policy library of a policy engine. So if you go to qverno.io and if you see the policies, we have a huge amount of policies there for maybe every use case. So what are the overview and what are some Qverno features on an overview level? So we have validation, Qverno can provide you validation, mutation and generation with the help of these policies. So you can set up some rules and you can validate with the help of the policies. You can validate those rules against with what you are applying. So it provides you validation on the clusters. It provides you mutation to the existing resources. So you can say that, okay, this happens. This is a trigger. It should mute it. Some resources that are existing in Kubernetes. So it provides mutation. It provides generation. So you can create your own trigger in the form of policies and it can generate when that trigger happened in Kubernetes cluster. We have some image verification that Qverno can provide you. So it really helps you in verifying your images and then it generates a report that is created centrally when you deploy Qverno. That means it tells you that what is violation? What are the violations? What policies are violated with all kind of, like what deployments are being violated to what policies? So you get more visibility there and then we have Qverno CLI. So Qverno CLI, you can easily point it to a cluster and maybe do a dry run before you are deploying any kind of deployment. You can easily integrate it into your CI CD pipeline. So before you do a deployment, you can actually verify it whether it's security wise, good or should you have to do any changes. And what can Qverno deliver? These are some use cases, real life use cases that Qverno can help you with. So we have seen some, in the initial slide, in the last couple of slides, we see that there was this, using KubeCuttle you were able to deploy a bad pod and you can get access to the host and you can do all sort of things. So Qverno can help you block such kind of requests. Qverno can help you, not only that, but it can deploy best practices, policies, PSPs in your cluster and you can block such kind of request or you can at least have an audit that okay, these are some of the pods and these are some security wise, not good pods that are running in your cluster. It provides fine grade RBAC, that means a user with a role may create secret with a label, such kind of use cases, something that Qverno can help you with. It helps you in your cost control, for example use cases like, you need to tag particular cost, particular cloud resources like your load balancers or maybe your EBS and you have to generate a cost based on the tagging. So Qverno helps you in automating, Qverno helps you in tagging those resources running in your Qvernities and also it can help you with use cases like, okay, the service type with load balancer should only create a load balancer in AWS which helps with the cost overall. It helps in ops automation. So use cases like, think the config map whenever the new certificate is generated, it helps you in these kind of automation by generating new resources, by doing some kind of automations for you and then you might have a use case where you're using a shared cluster where there are multiple applications running on the cluster. So you need multi-tenancy. So you might need that, okay, when I create a namespace, five different things should be created automatically. It should be, I don't have to do anything, it's just the trigger is the namespace. Once the namespace is created, we need what we need, tech of policy, we need quotas and all those multi-tenancy resources and new Qvernities automatically created and set up for the developer. Qverno can do that for you using generate policy and then we have supply chain security use case. So how do you make sure that you're assigning your image and then you're validating it with what cluster is consuming? So Qverno can help you in these kind of complicated use cases as well. And there are more to that but these are some standard use cases and top use cases that you can achieve using Qverno. And here there is a sample policy on the screen. Now if you see this policy, if you're familiar with YAML, you can actually read that policy. So it's quite simple, it's quite easy to read. You know that it's standard YAML just like a deployment or a pod YAML. So you'll see there's an API version, there is cluster, I'll not go entirely maybe, but you'll see that this policy is applied to a pod. So you have a rule over there, it's applied to a pod, and then there is a message that will be thrown whenever the policy is blocking a pod. And then there is some kind of patterns that are, its policy is validating. So this is a Qverno policy that you can see and all these validate policies are something similar. So they're easy to, you can write it, they're easy to customize as well. So these are very, very simple. It's basic YAML over here. And these are, this is the application Qverno component that will be deployed on your cluster. So you'll see that there is an API request and Qverno actually interrupts that API request based on what policies you have applied and it can validate, mutate, and rate according to that. So there are some validating Webhook configurations, there are mutating Webhook configurations, and then there is cluster role and cluster role binding. So if you want to strictly tighten the Qverno's application permission in your cluster, you can do that. You can change cluster role, cluster role binding and you can restrict Qverno's permission to a particular namespace or if you want to tighten it further. There are custom resource definitions that is config map. So you have a lot of features that you can customize using config map and there is service account secret, the standard stuff. The Qverno deployments over here comes with, they're at a single pod, but it comes with HA. So if you want to deploy Qverno using HA, you can go with that. If you have a standalone cluster and you just want single pod, we have both the flavors of Qverno's deployment and then there's a service, of course. So yeah, this is what the application looks like and that's how the components are deployed on your cluster. And this is a sample policy structure. So we have already seen in the last slide that that was a validated policy. So it looks similar, that's the standard of how a policy is gonna look like. So policy can have one or more rules and it has a match and exclude condition. So a match condition is gonna match with certain humanities resources. For example, there is namespace, there is also this entire group it can match with. And in exclude, if you have some exceptions like, okay, my Qverno should ignore couple of maybe namespace, couple of user group, you can put it in the exclude section and then it have different clauses after the rule. It can actually, it performs the clauses and the clauses, it can mutate, it can verify, it can validate, it can generate. So mutate is gonna mutate existing resources, generate is gonna generate to you. Validate is gonna validate with that and verify image is gonna verify whether your images are signed and the same images are being consumed by a cluster. I think the further section will be taken by Chip and he'll dig deeper into the type of policies and some pretty interesting use cases. Over to you Chip. All right, thank you, Dallas. All right, so let's take a look at in a little bit more depth each of these capabilities that Qverno has and Dallas kind of laid out from an overview what they are. So validation rules. Validation, this is probably the most popular type of rule if you're using any policy engine today. This is your quintessential yes or no response. Here's a resource. I have a policy that says it should look like this. Do you allow it or do you not allow it? Qverno obviously does that quite simple. This occurs during the validation admission phase. So when the API server sends a request to something based on the definition of a policy, it goes through a life cycle or a tube if you will, and two phases occur. The mutation phase occurs first and then the validation occurs second. All of the validate rules occurs surprise during the validation phase, which is the last phase before it's accepted into a cluster. This is the most common rule type. So all of your things when you're thinking about pod security, making sure that pods and containers they're in don't run as root, making sure that you don't run host path, that you don't have a user that's number zero, all these types of things. These all fall under validate rules. There are two failure behaviors that Coverno supports today. The first type is called audit. This is where we will allow the resource to be created if it's in violation of the policy, but we will tell you about it in a policy report, which I'll get to later on. The policy report is just another standard Kubernetes resource. The second action is in force. This pod or whatever the resources, custom resources included, fails the definition of the policy. We will deny its creation. And there are two styles that you can write validate rules in. One is an overlay style expression. And that's the example that Dallas showed a few slides ago. This is what most policies in the validate rule or indeed most policies written in Coverno use a simple expression or a simple overlay style. This is very similar to how customized does it because we're actually using customized in some cases under the covers where you specify the portion of the resource in which you're interested in matching, not the entire representation of the resource, just a portion of it. Second way to write validate rules is with a deny condition. So conditions in Kubernetes we're all familiar with those key operator value. Coverno has the same constructs. Using a deny statement, you can use these expressions to achieve even more power by pulling in some other advanced capabilities which we don't have time to cover, but two styles of a validate rule that you can write with plenty of flexibility to achieve any of those use cases. Mutation capability. Coverno has had mutation capability right out of the gate and it's very, very mature. This is as you may or may not know be the ability that defines the modification of a resource. So going back to the phases of admission review this occurs first in the mutation phase. So when a resource comes in, if there is a policy that says you should mutate this, mutation will occur there, then get shunt to the validation phase later on where there may or may not be a policy to apply additional validations on that. Mutate rules like validate can be written with an overlay style. That is, if you're only interested in applying a specific portion of the resource you can do that by specifying with overlays which is the easiest and simplest way to go about doing it or you can use standard 6902 JSON patches. And these are non-adulterated JSON patches. Coverno supports those perfectly well. And using those JSON patches, you can do things like remove values or change values in a lot of different cases. And by the way, all of these things that we're talking about and this is a common question that comes up work for custom resources as well as standard Kubernetes resources. So it doesn't matter what type of Kubernetes resource it is. Coverno can validate it, can mutate it, can verify images stripped away from it, can generate it, et cetera, et cetera. Mutate also supports the ability to mutate existing resources. So you have existing resources that are in the cluster and you need to provide some sort of retroactive mutation against them rather than performing all new mutation based upon an event on that and be that a create or an update. Coverno has the ability to, via a policy definition, apply retroactive mutations based upon your design. The generation rule type. This is one of the most popular rule types in Coverno and one of the things that really differentiates it from a lot of other policy engines. Coverno has the ability to create new resources of any type based upon a trigger that you define happening in the cluster. The source of that can be either a clone. Here's an existing resource that's somewhere in the cluster. I want you to put it over there in number of times or it can be defined in the policy in what's called a data structure. And in the data structure you define I want my resource to look like this including things like variable templating and expressions and all sorts of things that can go in there. And then when that trigger occurs it will create that resource upon that definition and whatever the defined target is. It also supports synchronization so it can watch the source resource be that defined in the policy or the source resource in the case of a clone and if that changes it can immediately synchronize those contents down to the downstream locations. This also enables things like tamper resistance. If somebody tampers with the downstream resource and synchronization is enabled Coverno will see that and immediately revert the resource back to its previous state. This also works on existing items. This is great for if you have brown field environments which everybody does, you've got existing namespaces and you wanna generate resources into existing namespaces without having to manipulate them or even worry about creating new namespaces Coverno can do that as well based on the same simple policy definitions. This is obviously great for multi-tenancy and indeed this is one of the most popular uses of it where even if you're not using true multi-tenancy you're using soft multi-tenancy for things like applications. If you are using multi-tenancy for separate teams or even separate customers Coverno can be a full namespace provisioner and generate all the resources that you need in order to get that namespace into production quickly. Image verification. This is Coverno's ability to verify the image signatures in an OCI registry of the images that are being proposed to be run in the cluster. Coverno internally uses the Cosign project from Sigstore. Anybody heard of Sigstore recently? Yeah, it's been a lot. Cosign is used to sign the images. Coverno uses Cosign to verify the signature of those images. This is integrated. All of these things that we're discussing are integrated directly into Coverno. There's no bolt-ons. There's no additional things that you install. If you don't want the behavior, you don't get it. As soon as you want it, all you have to do is write a policy. It enables the behavior. This also supports things like attestation checks. Anybody here attesting to their images in any way, shape, or form right now? So a couple brave souls. All right, hopefully at some point in time we get to do more things like provenance but anyhow, we're ready for that. It's already there. And Coverno supports the ability to check attestations of any predicate type, even custom predicates, and you can verify any portion of the attestation payload using any form of expression that Coverno supports of which there are many. All of this works with any OCI registry. There's no isolated list of these only specific ones. If it's an OCI registry and it conforms to the OCI spec, Coverno will work with it, pull those images and look at the image signatures and attestations on them. And you can do some complex multi-way checks. So any keys, all keys, at least one or at least two keys. So you can do things like my entire organization is required to sign all images, but if they're going into a PCI namespace, additionally the security team has to sign off on those images and based upon whatever policy design that you want, it can ensure that anything that goes into that namespace maybe gets two signatures that they have to validate, otherwise it's just one. So policy reports, I talked about this on the validate slide, but policy reports are a standard Kubernetes custom resource that shows the results of validate rules placed in audit mode. So if a validate rule is in audit mode and a resource violates a policy, the resource will be allowed to create, but it will log that in a policy report. This is an open standard from the Kubernetes Policy Working Group. This isn't some esoteric standard that we created just to give you yet another CR. The Kubernetes Policy Working Group defines a standard policy report structure that's by the way adopted by several tools that are out there in the ecosystem. And what this enables is the separation of those who can write and see policy and those who can write and see policy reports. They aren't crushed together in the same thing so somebody has to parse out the results of the policy. They're cleanly separated. The roles that you wish can separate based on whatever desire that you want. Policy report comes in two flavors, a namespace policy report and a cluster wide policy report. Things that are namespace scoped appear in a namespace policy report. Those that are cluster scoped, for example, Node or some other custom resources will appear in the cluster policy report. Policy reports are written in two modes, admission review. That's if the policy is in audit mode and also what we call background processing mode. If you create a rule with background processing enabled, Coverno will on a scheduled basis go and check all of the resources that pertain to that in an existing cluster and if they're in violation, we'll write that into a policy report. So you can do things like drop in a policy in audit mode and get an understanding of the disposition of the resources in that cluster without any admission requests having to come into it. Results are pass, fail, warn, error, and skip. Again, these are all defined in the open standard of the policy of the Kubernetes policy, WG and Coverno supports all of these. CLI, Coverno has a CLI. It allows you to test policies outside of a cluster. The way this works is in two primary fashions. This allows you to check against a defined manifest. As in, I have this policy, I have this or these resources and I expect this result to occur when these are evaluated. If that result is not achieved, it'll be deemed a failure or you can just YOLO and say here, there's a policy, here's a resource, tell me what happens and it'll give you the output. And by the way, that works with things like mutate and generate, here's a policy, here's a resource, give it to the CLI. It should come out if it matches to it. It'll show you the full representation of the generated or mutated resource. This is obviously great in CICD pipelines because now you can shift left and put in the CLI so that your authoring experience is the same and you're able to reason about that process all the way through to the running in the cluster. So whatever the CLI reports, you can do things like deny your, you can fail your PR and this is a very common use case and in fact in the documentation, we have a sample GitHub action that this is all plumbed up for you. You can go and copy and paste it right now as a way to get started. And it's simple enough where you can use it in any project, it's very standard. This is a GoBinary. It's available as a Qt control plugin via crew, via homebrew, lots of other installation methods. Very easy to get started and to install it. This is part of Coverno. This is not an isolated utility that was sort of whipped up to evaluate Coverno's language separately. The code that executes in the CLI is the same code that executes in the webhook. It's just in CLI form factor. All right, so some things that are new in Coverno 1.8. For those that are not aware, we released 1.8 technically a couple of weeks ago, but we had the release blog that we put out there earlier this week. There's a new pod security sub rule. How many of those here are familiar with the either pod security admission or pod security standards? No, I do not mean PSPs. Pod security admission or pod security standards? Pod security admission being the technology which implements the PSS standards, okay. So pod security admission is a new feature. As of Coverno 1.23, it reached stability in 1.25, which was the same version in which pod security policies were removed. So for those who are not aware, pod security policies are gone. That is not deprecated, gone in 1.25. The same libraries that power pod security admission, which is the Kubernetes replacement for PSPs, we pulled that library into Coverno and made a much simpler abstraction using this pod security sub rule. So you can do things like apply the entire restricted profile of the pod security standards in one single rule. Another thing that we added in 1.8 is YAML manifest signature verification. So I talked about the ability to verify image signatures and attestations from the six-door project using Cosign. They also have a sub project which is the signature and validation thereof of YAML manifest. Coverno has brought that feature in and allows you to sign YAML manifest and verify, well Coverno won't do the signing, Coverno will do the validation of those YAML manifests before they're allowed to come into your cluster and also allow you to do things like exclude certain fields. So for example, if you wanna sign a deployment to prevent, ensure that tampering does not occur from the time that that is signed to the time that that's run, but you wanna allow users to only change replicas, you can define that in a simple YAML-based policy and Coverno will validate that signature before allowing it to run. None of that involves any programming language on your part. Coverno also now has the ability to clone multiple objects in a generate rule. So prior to this feature, generate was sort of a one-to-one mapping. You triggered on one resource and you got one resource, but now this allows something like create a new namespace and in the same rule clone out 10 things, for example. You can do that in just a single rule definition now. GitOps friendly pod controller rule autogen. I didn't talk about autogen, but Coverno has an ability whereby you can write a rule for a pod and we will automatically translate that for all of the standard Kubernetes pod controllers. That means that you don't have to write separate rules for deployments, demon sets, stateful sets, jobs, or cron jobs. Coverno will automatically do that if it sees that you're only trying to match on a pod. In this version, we moved that auto generation capability from the spec object up into status. So those of you that are using GitOps tools to deploy your Coverno policies, you can do that very simply without having them go to war or providing any exceptions. We overhauled the reporting system. We completely rewrote the reporting system to be faster and more accurate. Lots more there. Open telemetry support. For those of you who already had Prometheus support, now we added open telemetry. GRPC is what's supported right now. We didn't talk about the James Path system. Those that are familiar with JSON path, there's a similar system out there called James Path. And Coverno completely brings in the James Path system, but we also create brand new filters that are only endemic to Coverno. And in this release, we added two more filters random, the ability for you to create a randomized string based upon a regex pattern that can be as simple or as complex as you want. So for example, if you wanted to generate an API key, if you wanted to generate a pod hash, Coverno can do that internally with no other logic that you need. X509 decode, the ability to decode an X509 certificate and parse out the YAML in any policy definition. So for example, you can now do things like, I wanna know in a policy report, perhaps, if any of certificates that are in my cluster are going to expire in the next 30 days. And I invite you to get involved. Coverno has over 3000 stars. There is a contributing guide. We have good first issues that are labeled and we keep those up to date. Documentation you can find at Coverno.io. Our policy library, there's over 230 sample policies and that grows and these are for ecosystem tools far beyond just Kubernetes itself. So Istio, LinkerD, we've implemented their best practices. Argo, Flux, CertManager, some AWS, I don't even know all of them and it grows all the time. Also that policy library is community driven. Any of you can write a policy maybe for a tool that you don't see for your own use case. We will gladly accept it. We will work with you to test it and make sure that it's solid and then we'll add it to the library and make sure that everybody can access it. We have a weekly contributors meeting. We have a quarterly end users meeting. We have two channels that are on Slack. One is on Kubernetes Slack with Coverno and Coverno Dev. On Coverno, there's about 1400 users and on CNCF Slack. And with that, I wanna thank everybody for coming and we will be glad to take questions. Dallas has the mic. Please wait for Dallas to bring the mic to you. Raise your hand if you have a question. We'll be glad to take that with the remaining time. Hi, thanks for the talk. Is it possible to write a policy for one resource where it's evaluated against another resource in that same namespace? Absolutely, okay. Coverno has the ability to do API calls to the Kubernetes API and get any resource that you want. And it has a rich variable system that allows you to store that as a variable to perform transforms against it and to substitute that variable at basically any point in the policy that you want to. Any other questions? One down here or whatever you're here. Thanks for the talk. Can Coverno, as part of its triggers, send a web hook to a different service and have that service send back a year or nay? No, it does not do that today. That's an interesting use case. Come and talk to us in the Coverno booth. I'd like to understand a little bit more about your use case. Thank you for the talk. Is there a way to put timeouts when I have too many rules and just takes too long to validate something like that? Yeah, so Coverno exposes a field on the policy, on every policy where you can set the web hook timeout behavior that you want, in addition to the failure behavior. So if you'd rather fail open for some reason, you can configure that on a policy. If you want to change the web hook timeout from the default, I think it's like 10 seconds to the maximum, which the API server allows us, 30 seconds, you can easily do that. Those are just the additional two fields that you define. Hello, thank you for the talk. So I have two questions. One is I'm new to Coverno, so first question is how much different it is from OPA or we hear about an open policy agent all the time. And the second question I had is like, can Coverno create attestations for images or any of the other artifacts that you might have? Yeah, so two different questions, very different questions. The first is how does it relate or differ from OPA and OPA with and without Gatekeeper? Coverno was written from the ground up only for Kubernetes. Coverno is not a general purpose policy engine at this stage, and that's a conscious design decision, not a mistake or not something that... And the reason that we wanted to do that is because we wanted to shift the burden away from users of having to write and maintain a programming language. Even if you're capable of doing that, we wanted to shift that burden so that that process is easier. It's easier to maintain, it's easier to reason about. Maybe you who are capable of writing a programming language can collaborate with your security team who is not and everybody be on the same page, you can reason about policies and also you can use your existing tools to manipulate and even write those policies. So if you wanna use customize to do things like add additional exclusions, add additional preconditions, which we didn't talk about, add additional conditions to a deny statement, there's no block scalar with a bunch of YAML underneath it that you have to manipulate. You can do that with existing tools and processes that you have today. The second question is, is Coverno capable of creating attestations? No, Coverno does not create attestations nor does it sign images. It is in the runtime path of ensuring that the attestations and signatures are present and are valid based upon your definition. Any other questions? Hi, at what point are we doing too much YAML and we should use a real programming language? Like is there a recommended boundary or? I don't know that, so I'll start with one thing anecdotally. I'm very involved in the Coverno community. Maybe those of you who use Coverno have probably seen or maybe received help from me from Slack. I'm also very involved in the Kubernetes community in a number of different ways. In the time that I've been, I mean at this point in time, listening to real world use cases from thousands of people, I only know of two use cases that Coverno has no way to accomplish. Both of those are tracking for completion in the next version. So at what point, where is the inflection point between trying to wrangle YAML and having to go to a programming language? And the answer is, that really depends on you, your skill set and what you're trying to achieve. If you have highly, highly complex policies with a bunch of, I can't even come up with a concrete example, a lot of conditional checks that need to just be totally off the wall, that might be better a purpose served for a policy engine that's capable of exposing a programming language. I will also say that we have on the roadmap and we are trying to work towards the ability for Coverno to support a language like Q-lang or cell or something like that. That's not today, but we're looking at that for tomorrow. Thank you, you actually touched on something. I was very interested to see the CoSign implementation there and I can really appreciate that. CoSign does have the ability to kind of do some policy evaluation itself. How does it overlap with what you're doing in Coverno, like for a use case, being able to validate provenance on an image within Toto access stations? Yeah, so Coverno does support checking the in Toto attestations, but one of the differences, and I will not pretend to be knowledgeable to a certain extent on their admission controller, but I believe that there's requires for attestation checks use of Q-lang to be able to validate them. Coverno does all that without Q-lang today with simple expressions using James path or just simple patterns. We have time for one more question and then the moderator's gonna kick us out. I was just trying to understand two parts. One is given that you have multiple policy documents that might match a given resource. Is there any ordering constraints? Yes. Coverno applies. Yes, good question. So two important constructs about Coverno and this is important to take away. There is no possibility in Coverno for one rule to usurp or countermand another. Rules only serve to extend the failure domain, but within a policy there is an application order. If you want that behavior, you can define, I wanna start at the top and evaluate down and only one or the first one must match or all of these must match. You can change that behavior, you can leave it default, it's up to you, but no matter what behavior you choose, you can't have one policy countermand another. So there's, we close that security hole off. The related question was, given that you can have these generated policies, there becomes a kind of a nasty debugging infinite loop potential in there where something could generate a policy, a generator could generate a bunch of other resources which go through Coverno and generate more resources and on and on it goes. How do you debug something like that? We have internal protections in logic built in to catch situations like that so it doesn't cause a runaway train. I don't have full details on that, but we thought of that problem, we experienced it and we have some logic that will prevent that loop from occurring. All right, thank you everybody for coming to this talk. We'll be available here for additional questions.