 In Canada people watching in bars and hockey things so that would be more fun and then have maybe bingo buzzword bingo or something but Let's see. He's gonna give it a try. He's not sure how to he's gonna try him tether. Oh boy Hmm Heatherine's always a roll of the dice. I've done it once or twice But we'll see it. Let's at least get him on camera. And then if we need to reschedule You just look at the schedule Did I book anything for Friday? I hope I didn't no you did not I didn't smart woman I am there isn't a working group meeting tomorrow. We don't stream those We could I don't know what's your Friday look like? Chris we have I've deserted DevOps or did I own DevOps on my calendar? That's it Okay, so maybe I mean I can I can watch that on something else, so Yeah, if he yeah, let's see if he can get in if he can't maybe we'll just do we'll do Friday. I work Gotta make sure I didn't book something else on a Friday, but yeah And he's still trying folks give him a chance our speakers had a power outage He's either in New York or San Francisco one of the other places where but that's really if he's in San Francisco This is the second neighborhood outage. I think that's San Francisco in the past month Hmm, you think you can't blame COVID for that. No So it's construction season here as we call it So that's when I expect the lines to get cut like last year when it happened and everything, you know It looks like he's not getting in too bad because this is gonna be a really good talk. I was really looking forward to it Slacker He's yeah, he's he's vanished. I think if we go to the 15 minute mark Chris and he's still not here Here he comes in how slow is we gonna get this there we go, I mean if he can screen share that's gonna be remarkable There you are so you're here do we have sound? No, no sound. Oh god, we're having a day. This is Monday for real. Yeah So Lewis would you like to reschedule for Friday at the same time? Is that open for you? Or did you plan on taking Friday off after summit like a good person would have or Okay, you get sound. I think I'm confused I think I'm completely back Okay, that's sorry about that. That's okay So I do see a very odd view right now. Yeah, you what do you got? It's like a iPad view almost or something really that's odd. Okay. Let me You see you see my slides. Nope. Oh, you have double Okay, here it comes. Nope Nope try again. Oh You know what when I restarted which makes me happy. Yeah makes everyone who's going to summit happy. All right, everybody Hey everybody, welcome to another Monday open shift commons briefing with another wonderful upstream project this one Claire We have Lewis de los Santos here who's a principal software engineer working on the Claire project for red hat And he's going to take us inside the indexer and so I'm gonna let Lewis introduce himself introduce what everything's going on in the Claire world today And if you ask your questions throw them in the chat and we will answer them at the end of the presentation So take it away Lewis and thanks for your persistence. Yes. Thanks for the introduction So today we're going to do a talk called inside the indexer how Claire before extracts and persists the content of containers So what this talk is really trying to uncover is is getting The community or the watchers of its presentation more acquainted with the internals of how Claire works Claire's fundamental goal is to provide insights about containers To the client whether that's a developer or an operations team We want to show you what exactly is inside the container and what might be vulnerable and Have your teams patch those things or or act accordingly to do this It becomes obvious that we need to understand what's inside the container extract the contents and Place them into some kind of schema, which is searchable and that's what this talk focuses on inside the indexer Indexer is a service which actually takes all the layers from a container looks inside them Pools out the contents and creates a report So what is indexing indexing is a term that that we use with the process of Extracting the contents of the container itself It is the first step in Claire's analysis pipeline So inside Claire's pipeline, we're trying to take a container and we're trying to understand What content is vulnerable? We split this pipeline into several phases and indexing is the very first phase It's responsible for creating an index report, which we're going to go into detail in just a bit So if we're looking at the complete Claire pipeline to create a vulnerability report, this is what we're looking at This is the 30,000 foot view. I have highlighted the Portion of the application the portion of the pipeline which we're going to cover today in this talk What you'll notice is we take a container manifest We feed that to the indexer the indexer performs a bunch of work Which we're going to go into in detail in this talk and then it generates an index report, which is the findings of the work that it just performed on the container manifest So there's a couple key components here now if you'd like to follow along or you go back and you want to look at this talk If we're in Claire core, which is our project. This is the engine This is what's really doing the scanning and in the Claire project If you do you want to follow along in our source tree the indexer code is in this internal Package and then there's the indexer directory here Almost everything we're going to cover in this talk is laid out within this indexer directory And there will be a lot of References back to this so if you are interested in follow along or just you know You're looking at this talk at a later date and you're trying to piece together what we're talking about to the code This is the directory of interest So the key components in this little section. I'm going to cover the data models basically how we go and Structure our data to accomplish this goal of extracting the contents and reporting what we found inside the container So first we have a manifest The manifest represents a container image for us. You'll notice it's made of a slice of layers Those are order-dependent. So if you go and you created a container, you know with With Docker or pod man Those layers are created with a parent-child relationship and we represent that with the slice So when you submit a manifest to us, you're creating The same concept as the layers hierarchy the map sorry the containers hierarchy of layers You represent that with a slice of layers to us and then just the hash digest of the manifest the content addressable hash Signifying the manifest as a whole Now this is the index report. This is how we communicate to clients. What exactly we found inside containers So we'll start again with the with a hash, right? This is a hash of The manifest as a whole so you can think of it as a unique identifier for the container and its layers in that unique Ordering and what happens to obtain this hash You might know about this if you're if you know about how Docker images are built But if you don't this hash is actually computed by taking the hash over each Individual layer inside the container and that computes a final content addressable hash The state this is used Internally and it is exposed to HTTP clients who might want to query the indexer So the way this works is that when you submit a job to the indexer If you were to try to submit the same job We would actually give you back this structure and give you the state of the index so Claire is smart enough to know like hey, we're working on this right now But here's the state you might want to pull the state if you want to pull the state Just those wait until you see an error or you see that it is successful so we don't do this in quay right now, but as a Usability factor you could write clients which just kind of sit there and like pull on their job It's part of the design specification for the indexer itself packages this acts as a Let me actually take a step back. You'll notice packages distributions repositories. They're actually maps, right? It's a map string with the actual structure of the package distribution of repositories So the index report is really acting like a portable database We do this for deduplication reasons It would be unfortunate if we just continued to write the same package strings for every layer that we found it in or Had to duplicate that information So when you're looking at the index report, you actually kind of want to treat it as a database which has Key values that you can string together to understand where certain packages were found So the way this works is you'll look at the packages We'll call it a database and it has the id and then it has the package name. So right now This you can picture this as a deduplicated database of all the packages that were found inside your container same thing with distributions We could technically identify more than one distribution We typically don't if it's a normal container, but sometimes there is dist upgrades or sometimes, you know, there'll be more than one file that gives us a hint on the distribution of the actual container and this is You know, whether the container is rel whether the container is sent OS whether the container is Debian that's what this is representing And then repositories these is if these are Usually language repositories. So if we find pip if we find NPM, they'll be represented here and then the environments is what strings this together So when you're looking at environments, this will basically give you the idea of saying, okay We found this package in this layer at this file system path And we needed to do this to support language packages Because once you start supporting language packages, you have this predicament where the same packages could exist in multiple directories across the file system for instance, if you are using NPM and you have a Forms library, you might use that in five projects that are scattered around The containers environment. So we record each one uniquely without having to duplicate the packages identity by Compressing them into these small databases. So that's really the bulk of what the index report is providing you Now there's just some bookkeeping Whether you had a success or not. So this is again if you're a client that's polling and you want to know Okay, did we have a successful index or not you can pull for that and then if we didn't if success is false Then we'll give you a detailed error message, which is just helpful for debugging That's the index report. That's the output of the indexer So now we have scanner interfaces, this is a very important concept when dealing with the indexer because this is the Externally implemented sections of code The each scanner is rep is in charge of taking a container layer and Then parsing through it and finding the desired content that they're interested in so We wrote these as interfaces allowing other teams other upstream contributors to come in and say, okay, I want a Jar package scanner You'd come in you'd implement this interface which takes the layer looks for jars and just Parses them into packages returns it to the clear code very simple and this has been proving itself useful with the CRDA integrations We've done I was working with a ruin on code ready containers and I discussed this with him I was like how our interface is doing and he showed us the PR It was all code add nothing needed to be changed. So this abstraction has been working pretty well for us The same goes for distribution scanner or repository scanners This play is an important role Later on in the talk, but as you can imagine the indexer is Taking container layers and trying to understand what's inside them. This does the bulk of that work We hand each Implementation a layer and it can go ahead and scan through it and understand with its own business logic the clear code Proper isn't too concerned about what's happening in there So the flexibility is there's a lot of flexibility there to to perform package scanning distribution scanning and repository scanners scanning the way the Ecosystem sees fit whether that's npm or python or whatever And then there's a coalescer. So this this is probably my favorite part of the indexer As somewhat this took a little bit of time to figure out, you know, how do we do this, right? So Let me think of the best way to explain this when you have a normal container it's a series of Discrete tar balls, right and they represent file system layers Now inside those layers There might be what's called a whiteout file and what that allows us to do is handle deletions between the layers Now Claire doesn't necessarily need to understand that but at some way shape or form Claire needs to understand I've had these layers There might be situations where the packages I found in layer one Don't even exist in the later layers So we don't want to put that in the final index report because they were deleted in some intermediate layer So the coalescer Is another interface which handles this business logic So it can go ahead and it looks at layer artifacts, which are similar to the index report But they represent the individual packages distributions repositories found inside an individual layer So the coalescer will take a list of these artifacts And with its own business logic, it will understand Whether it should actually keep or remove Artifacts from the final index report Um in a similar fashion as if you were a container runtime And you had to apply A set of layers on top of each other to get the final container file system image that's going to run on the host We do this. We obviously don't have to do it with the file system in mind We have to do it with the end goal of creating an index report in mind Um, so a little bit of in-depth detail there Um, there's two implementations of the coalescer currently. There's one specifically for rel that you'll find And then there's a generic one. So let's take a look at that real quick Um inside this inside our root directory if you go into internal indexer Linux because this is a Linux focus coalescer the coalescer is inside here And this would be a really valuable piece of code to understand how we actually go about Creating these final index report And there's a little bit of heuristic in here Um, we have to kind of identify distributions Um in a very piecemeal way right because while it's not the common case What could happen is that you have layer zero Layer one and then finally in layer two We find something that gives us a hint on the distribution of the container we now have to somewhat backfill that information to previous containers Uh, and then attribute the packages found in those previous containers with the distribution information We found uh later on and this is just the nature of claire, right? Like this is kind of what makes claire a unique application in the fact that It's dealing with piecemeal information the entire way through and we're kind of finding Novel ways to stitch this information together and then create um A cohesive result that represents the final image So the architecture of the indexer itself It's has a restful HTTP API and we've written this in such a way that You could theoretically if your application needs were simply just I want to know what's inside the container I don't care about vulnerabilities or matching them against anything You could go and you can take the uh the indexer and use it as a discrete service It has no other dependencies. So if for some reason you had the idea of like, okay You know, I'll go and I'll do my own vulnerability matching Given that I have this little piece of a code this service that's able to give me the contents of a container Then you can simply just use this alone And there's a restful HTTP API to do that It is also architected and modeled As a finite state machine and the reason we did this Well, if you're not quite sure what a finite state machine is It's a set of logical steps States if you will that house Business logic So as you're moving through this business logic, you're transitioning via states What this allows you to do is um When we were re-architecting clear v4 we wanted to be able To basically quickly say, okay, there's something else we need to do We don't want to refactor the entire application So if we model it in a state diagram like this, don't don't worry about knowing all this We're literally going to go over every step in this But if we model it as a state Diagram and then we decided like Hey after scan layers, we actually needed to do this new thing We just pop it into the diagram and then do the plumbing necessary Almost no code has to be refactored Which has worked out very well for us because when we were re-architecting For instance Uh index manifests came as a requirement much later in our development cycle And it was almost no refactoring was necessary because we just created a new state and popped into the state diagram It is a common pattern. I'm just explaining it in case uh, you're not too aware of of of what that looks like So I have a little snippet of code here about um How the state machine runs And let me go back to the source code just in case you do want to follow along the actual state machine is in the same directory the internal indexer And we call it a controller to follow along with a lot of the semantics around claire Maybe a small aside is that a lot of times you'll see Interfaces and then controllers and the way we kind of architected claire as a whole is that People uh upstream individuals very simply just implement interfaces and the controller handles most of the business logic This separation has made contribution pretty seamless Because contributors don't need to worry about database. They don't need to worry about How claire actually stitches things together all they really worry about is implementing interfaces and then we have controllers Which control these interfaces? So if you are interested in following along anyway, this controller is the actual implementation of the state machine And the guts of it is really in controller.go here um, so i'm just going to go over the actual um run Method here because I think if you are trying to follow along then it can give you good insights we have this um, this dictionary or this map of state names to state functions And as you could assume state functions Are the actual business logics of each of these states So you'll probably see like a fetch layer function um What we do is we get the current state of the state machine And then we automatically run That state function that state function is going to return a new state. It's a very recursive Algorithm here. It's going to return a new state We're going to see if we need to do any error handling. We're going to check if we're the terminal state Um, which is a canonical way of saying everything's done. You you can halt the machine um Once we have once we determine it's not the terminal state We set the machine state to the one that was just returned We do a little bit of bookkeeping here Which writes the new state to the database This goes back to If a client is polling The indexer this is actually the hook that says hey, there's been an update to the to the index report You probably want to be aware of that if we can't do that We do some error handling and then finally we just recursively call run Which just does the whole thing again with the new state So it's a it's a It's a recursive algorithm. Um, but again, what's nice is that When we update the state diagram, we we don't really refactor anything. We just add a new We just add a new state function and then we update the state map Okay, so now I want to dig into each of these states Individually, um to give you an idea of Of what the indexer is doing. Um So the very first state that that we enter when you submit uh container manifest to the indexer is called check manifest And it's exactly what you think it is. It's we determine if we've ever seen this manifest before so We can do this because of content addressability So, I don't know if you if anyone has watched previous talks, uh with me and claire We're always hammering on this the content addressability aspect What this really means is that if we see, um A manifest with a particular hash It's content addressable. It's the same content No matter when we scan it again. Uh, no matter when we see it We can always be sure that the same layers with the same content make up that manifest Therefore if claire sees it it can go Oh, okay, I've seen this manifest I don't need to do anything else. I can literally just return The index report that I've already computed for this manifest Now in this case, we're going to say claire has not seen this manifest. So it's going to go, okay Move it through the pipeline. Uh, we need to we need to move it forward Now there's a bit of a um A subtlety here. Um, and just something that's nice to know When you're working with, um Multiple scanners What we'll actually do here is let's say that um Let's say claire has seen the manifest but now The implementer of the jar scanner For claire made some changes to it And it might detect things a little differently The check manifest state is smart enough to say, oh that jar scanner has changed So i'm actually going to submit this manifest down the pipeline to the next state But i'm only going to scan it with the new jar scanner um, so This adds to the ability of just doing as little work as possible um And you can see that actually in the source code. There's a little section where we We clip off Scanners, um if they have actually scanned the manifest before so just a little tidbit of information that I think is uh Is nice to bring along Just in case if you see it in the source code So now once we have said, okay, we haven't seen this manifest before And now we're going to Uh, move it down the pipeline. The next state is what we call the fetch layers state um, so in this In this state claire is trying to determine Which layers it actually needs to go out Spend system resources to fetch download decompress possibly And then scan So in this diagram here, I express the common case Of claire deciding this base layer. Um, I've seen it already. I don't need to go and grab it It might be ubi8 base layer. It might be a ubuntu base layer it's a very common case because A lot of containers are just built from the same from In the docker file. Um, so this is another example of basically how we're doing less work When it's possible to do so When claire fetches the layers, it's going to buffer set buffer them to disk Um, this is a small change which adds a lot of benefits from claire v2 to claire v4 claire v2 would actually do all the work in memory. Um, which can be problematic if you're trying to pull down gigs of layers, right? So now we buffered a disk when you're running claire It's we advise, you know, definitely have at least 100 gigs of scratch space SSDs will help Because we actually do use the disk layer quite a bit For buffering data, um, especially for very large layers Now we go into the next state. Um, so we have the layers. They're local on the file system Now we take the scanners Which were computed in the check manifest state. We say, okay, we have this list of scanners We know what we want to, uh, scan inside the container. Now we do that work. So the way, uh, the scanning state works Is, um, it takes that list of scanners And it will concurrently, uh, via go routines Fan out The scanning business logic, the controller does this right? It knows the implemented scanners that are configured it'll Fan them out and then hand them each layers And then they just begin scanning the layers And then they return their contents Back to the controller and then the controller will write those Contents to the database. So in the scan layer phase Is when we are actually computing what's inside each layer and then storing the partial results of each layer into the database So to touch on this a little bit, um, I I went over this in the components section a little bit But just as a refresher, uh, because there's a lot of data, uh, throughout the talk So I wanted to put little reminders. This is what the package scanner the distribution scanner and repository scanners look like Um, as you can tell, uh, when you call their scan methods, they're given a layer um, if we go back just a bit You will know that the layer was buffered to disk so Uh, it's a little bit abstracted, but the scanner can get a tar handle to the layer if they want Or we do have some abstraction methods on the layer that says hey, just give me this file So an example of this if I was implementing, uh, an mpm package scanner I would implement the scan method to look at the layer Grab a tar handle and then look for all the node modules directories that I can find parse any pack parse any packages found Into clear core packages and just return them and then your implementation is done So that's the level of abstraction that you can expect if you're trying to implement these scanners Yourself or your own purposes inside claire Um, that's all you have to do So then when we get back these claire core packages these claire core distributions and repositories We simply just write them to the database, uh, with our with our own database handling logic all internal declares Um, any implementers will not have to worry about that Um, this is a look inside Um, the claire data model of how we actually stitch these, um items that are found during scanning Uh together, uh into, um an erd for searchability. So we created the, um idea of scan artifacts inside the claire database And what this is really doing is it's just, uh tying together The ability to search saying okay, we found this package in this layer and it was found by this scanner This data model makes it possible to say A new scanner has been changed Let's scan that layer again, uh, because we're recording exactly, um the scanner Name version and kind which found these artifacts So this is just a little bit of details in how we stitch everything together inside claire's database And then we get into the coalescing step Um, so I mentioned coalescing a little bit about how, um, this is how claire Putes all this partial data into a final index report And the way this works is Um, the business logic in in the controller will go ahead and it'll ask for the scan artifacts For both these layers right the the two layers that we scanned It's going to go and it's going to get this layer artifact structure Which has the packages the distributions the repositories And it's going to go ahead and it's going to get, um The the other layer artifacts from df0 And you're going to feed both these layer artifacts to the coalescer Now what the coalescer wants to figure out Is, um, how can I attribute packages to distributions? We touched on this a little bit, but the distribution information might be, you know, in layer 10 And the packages database might be in layer two So we have to somehow coalesce this and, uh, backfill distribution information Um, we also have to figure out which packages Should remain in the final index report and what packages should be deleted Uh, you know, based on The state of each individual layer So the coalescer works similar to the Ganners in the fact that, um, the business logic in the controller Will spawn coalescers with go routines run them in parallel They'll both create their own, uh, representation of the final index report And then we just merge them together, uh, to get the final index report With the final set of contents That are left inside the image So this is, um, in the index manifest, um, state is where we make the contents Of a container searchable Um, it's not a super complex data model or, um, erd diagram But basically what we are doing is we just have a giant link table Um, that basically says, um We found this package in this manifest. We found this distribution in this manifest Uh, we found this repository in this manifest. Um Where this comes in handy is when A new vulnerability enters the clare system Vulnerabilities are usually tied to packages, um, and distributions, right? So If you have the rel pulp, uh, security database, um, when you look at a vulnerability, it's going to say like open ssl rel 8 You can take that vulnerability and ask the indexer. Hey, which manifests have Open ssl and are of the distribution rel 8 And this index manifests makes that possible to give you that answer Uh, and it happens after coalescing So we get the final computed results of what's available inside the container image We index that hence the name indexer and then it becomes searchable, uh, in in the way the aforementioned way When a vulnerability is is attributed to a particular package and distribution And this is exactly what the data model looks like. Um At the end, I'll go through, um The uh, erd diagram and I'll go through basically the, uh database code And then finally we have, uh index finished. Um, and this is very simple state. This basically just, uh Massages the, um the state and success, uh keys Uh, well the values in the index report and then writes them to the database Deferring work so claire Um, we touched upon this throughout the talk But one of claire's main goals is to do as little work as possible. So we can Compute results and give them to the client as fast as possible So I want to just review real quick some of the ways that uh claire v4 does this deferment of work So the big first part is just the manifest scene start, right Because of content addressability if we have seen a Manifest before we're simply just not going to do any work We're just going to go right to the database and we're going to say, okay I have an index report for this manifest hash. I'm just going to return it Now again, this is excluding when scanners might have changed Or claire is just configured in a in a separate way Or a different way rather, uh than When claire can understand that its configuration has changed It will go ahead and it will scan the manifest again um, so another way of deferring work is Determining which layers to actually scan This is fundamentally the same as the check manifest state just on an individual layer basis So again content addressability indicates that if I see this hash if I ever see it again The contents haven't changed therefore. I don't need to re-scan it So it's another way that we're able to do less work and another reason why Indexing large amounts of images might not be as scary as it sounds As long as they are sharing, you know several layers A very common thing to do is have a base layer with a dependency layer And then finally a third layer that just changes, you know, your application Um And if that's the case Then claire is really only doing work on a single layer every time you push An application update as long as your dependencies aren't changing And you write your docker containers in a same way Which utilizes this? This uh separation between base dependencies and application Um, this is just touching upon um When we do decide that we're only going to scan particular layers We just go right out to our own database that has this information in it already Grab the information and then bring that information with us For the other steps the other portions of the pipeline Cool. So that is inside the indexer. Um, I have some information here for you Um, which is my email address if you'd like to get in contact with me I have the claire github repository And the claire core github repository Um, so that's all I have for the presentation. Uh, I'm Into either doing a little bit of code digging or we can go write the questions. Um, what do you think diane? A little q&a here because there's one real quick question And the other thing that I would have you do is go to your site and show The schedule for community meetings Because you've just done an amazing run-through to give insights into how to contribute and how it all works So I want to make sure people know how to find you and get into the To the community and and get started And while you're doing that, I'll read off. Um, andre's Question here So which phase of the general ci cd pipeline should be the appropriate position for claire scanners After some deployment or somewhere as a testing linting health check phase of ci cd Or as part of the security vulnerability management and qa process I know you have opinions about that, but I think everybody has an opinion about I think yeah, definitely There's opinions about that me personally um if I Have a build system And I am performing, you know staging builds Um, when you create those staging containers and they get pushed to a repository, that's really your time to do that scanning understand The vulnerabilities, uh, that might be inside your container before they ever hit production, right? If you don't have a staging environment and you simply push containers and then deploy them to production You still have that period of time where you've built a container. You've pushed it to a registry It's available for claire To analyze do that right before you were actually deploy your code. Um So in the ci cd pipeline, I would say as a you know as a general best practice Do it as early as possible, right like as soon as you have the container built um, and obviously before you push it out to an environment Um, then I would do the scanning uh as early as possible in your ci cd pipeline All right, and andre says thank you very much for that explanation. You're welcome. Um, and narandev has a um, I'm sure it's a Interesting thing that he's posted is wait. There's a state management solution for golang um It can you talk a little bit about that? I you must have mentioned it earlier and um, um I'm not exactly sure what you're referring to. Um, but We have written that state machine code. Um, just in pure go as a incarnation of our own, uh development We're not using a library for state management. Um, but if you are interested in state management And you'd like to see how claire does it. I would definitely check out that code It's probably a decent representation of what a uh, you know f fsm or finite state machine implementation in go could look like um Yeah, it was it was written to serve a purpose. It might not be the shiniest cleanest thing But it works and it works well. So if you do want to take a look at how we we work, um That finite state machine architecture in again, you can go to our source Which is claire core. It's the internal directory indexer and controller um, and what's really interested to you would be this controller go and state go um, and this is basically how we created the State transition tables, uh, which maps straight States to functions Uh, but yeah, no no library, uh, no State management solution for that. We just we just coded it Yeah, that's it's usually how things get done and then eventually someone says hey That could be something something and useful somewhere else too. So yeah, um modularity and and creating libraries Absolutely. Yep someday, but I think um, what what you've just done, um, which I wish I could get every upstream project to do Is to really explain how claire works internally and in order to contribute to a project That's like one of the often one of the missing pieces because you know a bunch of engineers from red hat and elsewhere That have been contributing over and over and taking the time to really explain how it works is, um, Wonderful, and so I can't thank you enough. I'm hoping that will drive people who watch this and want to use claire in whatever projects or products or states that they want to We'll come to these community meetings and then You know take a look at it whether you want to create, you know, take a look at the state management solution or Code base, I guess rather than solution Or to contribute to this that would be a lovely thing and so Thank you for powering through your power outage there. I'm just pointing Lewis and making this happen My pleasure Anything else you want to add in terms of um, what's next for claire and the claire community? Yeah, maybe just a couple of touch points on uh, what's coming up on the our internal agenda Right now we have the 4.1 release baking And this release has a pretty paramount feature called what we're calling enrichments um, what you might have noticed when we redesigned claire v4 uh, we wanted to remove false positives as much as we can um, by doing so we've removed nvd as a vulnerability data source We did that somewhat opinionated I think a lot of people share our opinions that nvd might not be the best source of data However, when we did that, uh, we removed a lot of the severity information that people became Custom to so the enrichment specification and 4.1 roadmap goal is all about allowing auxiliary data information to Enrich our vulnerability report So we took kind of a best of both worlds approach in my opinion is that We're sticking with the official upstream vulnerability data But now we're just enriching that data with nvd metadata So it's a little it's a little different from going to nvd and trusting all of it instead We have the trusted source and then we're adding information to the information that we already trust So this is a 4.1 goal and you'll notice that a lot of information for vulnerabilities will become richer And if you'd like to follow that development in any way shape or form you can go to quay claire And on ours is big enough to see oh a little bit bigger would be better. There you go Perfect. So you can go to our discussions and inside this design tab right here You'll see claire enrichment specification and just by the way, uh, we practice open design So any big ticket changes that are going to happen to claire will be in this section So it's just a good good area just to watch Um, and this is the claire enrichment specification Uh, and there's a link to our github repository. So the spec is here And the implementation details are here Um, I'm working mostly on this implementation, but community contributions are completely welcome every single, uh, detail Uh, to my best ability is outlined here. Some things may come up just from, you know, implementing software is not It's not always so easy to, uh, foresee everything that's necessary, but The majority and the the chunk of work that needs to happen is all here and welcome for community development. So if you'd like to speed up the, uh The rate at which nvd data winds up back in clay, it's a good one to just, you know, be abreast of and take a look um Yeah, other than that, I think that Just kind of being aware that uh, we have a community development meeting. Um every second Tuesday of the month Not hesitating about that. Is it every second Tuesday and fourth Tuesday? Or is it just every second Tuesday? Every second Tuesday. I'm not sure We'll fix that then. We'll fix that All right, that's good peer review. This is why we do this. All right We're gonna have to do a pull request for it. That's great. Um, that's awesome. Yeah, yeah So cool. So what um, I'm hoping um, I'm looking to see if anyone else has any questions Whether you're out there in twitchland or um in blue jeans or wherever you tubing and watching this or on facebook even um post your questions Otherwise, um, we're all clear with all the questions and I will go we'll let you go back to your day Lewis and if you can share your slides with me, I'll share it with the community as well and we'll upload this to youtube and hopefully um Now that everybody understands how the indexer works, they'll be excited about contributing to it And um and come to a community meeting. So thanks again for taking the time today. My pleasure. My pleasure. It's very fun Recording has stopped