 All right, you guys ready to get started? Chat about this stuff. If I was to do a quick poll of the audience, who here knows like the JSON schemas of image manifest and that kind of stuff, getting down to that low level details? I know a few of you do. Okay, we got about 50-50. I think everybody rose their hand, I'd probably know. So that's probably the part of the challenge here. So welcome. This is gonna be modifying the immutable one. So we're gonna talk about how you can attach artifacts to OCI images. By that we're talking about everybody's been saying stuff like generating S-bombs. And we're talking about how we create the S-bombs. Other people are saying how to consume the S-bombs. This is saying how you can connect those to your image and start shipping them out to people who need to deploy them later on. And so let's chat. The background of me, I'm not gonna go through the full details. I do work for Boxboat. Got other people here. I'm sure someone's hiring all that good stuff. But the important details from this one are that I'm an OCI maintainer and a lot of this work comes out of the OCI. We've got a working group we were going through a lot of efforts on this stuff. And on some of the slides in the demos you're gonna see a tool called RegCuttle. It comes out of a RegClient project and I'm the maintainer of that one. So when you see that, that's me just picking a tool because it's what I know. All right, so for the background, for those that didn't raise your hand on the underlying stuff, you probably already know that container images have file system layers. They've got their own config. You've probably done a Docker build at some point and then probably changed to other build tooling and trying different stuff out. You've probably seen it, there's a SHA-256 checksum for like pinning an image to a specific digest and so someone can't change it in that way and you might have a rough idea what's going on but not quite. And I'm sure at some point you've come across multi-platform images where someone's saying we need to start building for all these Mac M1s out there because everything else has been built for all the Intel machines. And so under the covers, there's a lot going on in OCI so I wanna hit a little bit and make sure you understand what's happening under the covers because that's gonna apply for when we actually start talking about how we start to attach things together. So under the covers, the important detail here is that everything is happening in OCI when you push it to a registry is a content address will store. And so what that means on the first line is I'll take a digest and if I curl that digest, the name of that digest from the registry and pull down that blob, pipe that through a SHA-256 checksum, it's gonna output that same value. And so it's the digest of the content itself is the name of the content and that's how you do the content address ability. Fancy name there. In this case, I'm looking at a layer and so you see a whole bunch of the files in the layer so it's just a compressed tar file and so that's like half the image, right? The other half of the image is gonna be your JSON config. What user am I running it as? What are the commands that I'm kicking off when I start this container up? If there's a history in there, you can see all the previous historical steps, environment variables, all that stuff. That all gets passed as a JSON blob. Same idea, content address will store, you just serialize it into a byte array, do the digest on that and now you have another address for that blob as well. And these three shortest blobs, registry doesn't care which thrown a blob. So JSON, tar, binary, text, whatever, it takes whatever you wanna throw in there as long as it just maps to the digest to the string you gave it. So now you got these two pieces, we need to put them together because an image, not necessarily one layer, it might have multiple layers and it's gotta config and so to assemble them together, we have as an image manifest. Yeah, another piece of JSON here that we're looking at. So I know this probably gets a little bit tedious but bear with me for a second. Where we've got the config descriptor and that descriptor has the digest that we're talking to. We've got the layers in there that we're referencing and so in this case, I've got a single layer that we're talking to and you put those two things together, you put them in the JSON, you serialize the JSON, you calculate the digest on that JSON. Now you have the digest of your image manifest. This is the pin digest, whenever you say I wanna pull an image by its digest, this is what you're pulling. If you ever change one of the layers, you change the content of the layer, you change the layer digest and that changes this digest as well because it's all included in there. So that's how you make that structure. Graphically, it looks a lot like this. We've got a tag, the tag, think of it as like a symbolic link. You can have multiple tags when you do the same thing. You can have a tag that used to point to one digest and the future points to a different digest and then that points to your manifest. That manifest is immutable because it's referenced by the digest. All this content is referenced under there. So pretty pictures, I feel like that wakes some people up sometimes. I know I'm holding you right before the coffee break and so it's gonna be a little struggle here. Immutability is the nice feature we get out of all this. So when you do this, you've got a merkle tree, you've got a dag, a directed ace like the graph out there and you've got the content addressable store we already talked about. You put all those things together and you get this immutability. So in case I'm going too far back into the college days, the merkle tree is when you have a data structure that has a hash itself and it's content, all the child nodes are hashed and so on and you already change it and so that was that structure we were looking at there. Okay, so far hopefully nods in the room. We've probably got a little bit too deep in the weeds for some people, but that's kind of where this talk is going. Another piece here that's important are the multi-platform images. And so to do this, we have a different kind of manifest. That different kind of manifest just has multiple descriptors for each one of the different platforms specific manifest and so it's a manifest of manifest. So you have this hierarchical pointing. And when you do this, when you're looking through that array of descriptors there and you say, okay, which one do I want to pull? You have to put something in there that can identify one versus the other and the way we're identifying it for the multi-platform manifest, we put the platform in there. And so you put that extra field in there, you say this is the platform for ARM, the other one is the platform for AMD and then we're going through looking for year manifest, you can pick it from the list and the runtime just does this for you transparently under the covers. But importantly, this has its own digest as well. So you can serialize this one, you send that digest in there and when you send this to your runtime, the runtime knows how to figure out its own platform under the covers. All right, graphically we're now up to this where you've got our tag that's pointing to the multi-platform manifest, that knows the island is called an index and so you have an index, just the terminology is how to pick, that points to multiple manifest for each one of your platforms, that points to each of the configs and all the layers out there. So we built this nice big graph and now you put one last piece on this puzzle and then we can actually get into the fun part of the talk. And the last piece is that for the longest while we've been able to push artifacts to a registry. Anybody ever hear about pushing a Helm chart to a registry or something like that? If you're gonna push a Helm chart to a registry, you just push a blob. And their blob, I think they actually happened to push a tar file out there, a compressed tar file, but it could have been anything they wanted to. You push that blob and the thing they change is the media type that is on that config descriptor. They change that media type on that one piece and that tells anybody running it that this is no longer a container image or trying to run with a container image run time, but this is some other tool that should be looking at it, working at it, even though both of these are image manifest. We just kind of overloaded that one tool out there just so that we get that portability. So we overloaded that, but otherwise in this example here, I made a little electron bill of materials and I just said that this does contain electrons, shipped that and I can attach that to any image I want to if I decided to. Okay, so that's all the fundamentals. This is stuff that already exists out there. People are doing this today, their Helm charts out there, their container images, their multi-platform images. This is kind of the underlying bones of what's going on under the covers. The challenge OCI faced was we're saying, okay, great, we've got all these S-bombs out there. We've got all these other tools. How can we associate one to the other? And if anybody was in here for Rose's bit, her conversation earlier, the discussion went, hey, we're shipping the container images out there. We really want to ship the S-bomb alongside of them and somehow associate the two together. Because it's not the best if you say, we're going to have this century repository of all the S-bombs that some government agency manages for us. I know I come out of the DC area, trust us, we work for the government, might be a famous term out there, but I'm sure a lot of people in here are like, no, no, no, we're not going to trust them. So, trying to get a centralized entity isn't going to necessarily work. Trying to have every person go out to a different place to try to figure out where this S-bomb isn't going to work. You don't want to like figure out, okay, it's under the released folder or on GitHub for this one project, someone else put it on their website. Now we want to ship these things together. We already have a way to ship an image. We can already ship other artifacts within the container registry. We just need to associate the two together. So, the challenge we face was how do we modify this immutable thing? Because our container image is immutable, it can't change, but we want to be able to say, for this container image, what's the S-bomb? What's the signature? What's all this other data out there? And we had a few requirements. So the working group was spun up and said, here are your go-to requirements and some of those things we were looking at was efficiency, we want to make sure we weren't making a whole lot of API calls. Other challenges we were looking at were, how do we both attach and detach content? If you start shipping out an image, you might say the upstream had it signed with their signature, but when we brought this in-house and we brought it to our own registry, we wanted to sign it with our own ID. We don't care about that upstream signature, so we just don't even want to pull that in-house. Or maybe they had more metadata than you even wanted to include or you needed to add extra metadata that wasn't there. So, a lot of different challenges along those lines. We also, we couldn't predict what everybody was going to include. You could start including cat pictures with all your container images you wanted to and we didn't want to try to write the spec for how to attach cat images to the image to container images. Gets a little complicated. So, the nice thing about this problem is that we weren't faced with the impossible, we actually had multiple solutions out there and some of them were already being used. And so our challenge wasn't how to create this, it was how to pick. And so the first option we were looking at was the Aura's team was out there and they said, we're gonna make a new artifact manifest. We're gonna push that out to the registry, we're gonna have a new definition that's not gonna have this config blob because we don't need that, but we just have our own little blob so if whatever needs to go in the artifact, we're gonna have this subject view we're gonna put in there and that subject view is just another descriptor, has this digest and that's gonna point back to the image we're extending. But now, from our manifest on the left-hand side of the screen, there's no way you can go from that arrow back to the right. So now we need to add new API. And so we add the new API that refers API that when you query that with our manifest digest from the left-hand side, it'll spit back the list of descriptors for all the manifests on the right-hand side of this picture. So that's how he made that mapping we were gonna have to add something to the registry. Couple pros and cons of this one, I mean it was nice and efficient, you had the API and the registry was gonna do it all for you but none of this is gonna work on existing registry today. Any registry out there that doesn't know what that artifact manifest that blue box on the right looks like is gonna reject it because while they accept any blob at all all those green boxes they'll take whatever you throw at them. They don't care about that part. When you're a manifest, the registry is parsing it because it's doing stuff like garbage collection. It's doing all of that. Association clean up, it's doing some validation in there so if you push something in there it doesn't recognize, it just rejects it. And so that was one of the big challenges we looked at for this. So he said, well, it's easy enough to change this a little bit. OCI has the model where we say you can extend any manifest out there. You can take a manifest that has five fields and you can have six field into it that's got some extra structure in it. And as long as you parse it and you see the field you recognize you can work with it and someone else that knows how to process the more fields they can do their thing. And so we could add the subject field to an existing manifest and so now we have another way to make this back reference. So now we can push this thing that's got this back reference in it using an existing media type just extend it a little bit to a registry. That means it's now portable. We can push this exact same manifest to a new registry or an old registry and it moves from one side to the other and back. And it's all nobody cares. Everybody just, it passes from one to the other. We still have the challenge that we can't find this though without having this new API. And this new API would be a new feature you have to add to the registry. So we're halfway there, we're not quite there, but we're getting there. And so the last thing we were looking at that I'll go over is that we were saying we could add a custom tag. And this comes from the stake store group. Anybody's seen CoSign? I think there might be a few people that might be signed some images. Might have been up on stage earlier. People talking about stuff that need to be signed. So they came out and said we're just gonna have a special tag that is the digest of that manifest on the left. Again, we like that digest. It's a nice, immutable thing. We can always reference. So we just make the tag with the value of the digest. She had to change a little bit of the syntax a little bit so you can change the colon to a dash so it gets parsed as a tag instead of as a reference or as a digest itself. But you change that one little bit there and now you can reference it as a tag and now anybody can use that to look up some abstract thing, whatever that tag points to. And the thing we would point to would be maybe the manifest in this case that we wanted to use. Maybe it's pointing to a list of manifests, something like that, but you could just make that pointer in there. So we had a couple options. Different A, B, and C and the question you might be saying is okay, well you threw a whole bunch of options to ask, which one did you pick? And the answer to that is yes. And for, we do have some people laughing out there and the reason is yes, because we picked them all, we couldn't choose. We're bad at making choices. We're bad at a lot of things, but making choices is definitely one that we're not experts at. So at least as part of the release candidates, and this is still up for debate on the first bullet point, is that we did add the artifact manifest. And so I'll put a big asterisk there. We're back and forth right now. It's probably gonna get there eventually, but if you're writing something new right now, there's some disclaimers that I'll go through later on. We add the subject field, and not only the subject field to the new artifact manifest, but we add it to the image manifest. And so you can extend things like we said, so that went in there. We add the new referrers API. So there is, API is gonna go on a registry server, but this is only gonna be on new registries to implement the new feature that we're talking about. So for all the registries that don't implement this, if you're a client and you're pushing this stuff up there, the client is now responsible for maintaining that tag. Anytime they're talking to a registry, it doesn't have the new feature. So with this, we now have the full backward forward compatibility. We've got a nice solution, and graphically it gets a little busy, little bit busy, and I actually had to take some of the arrows off here to make it flow a little better, so those subject clients there will go all the way back to the manifest on the left. But what we have is you pull your manifest from the version three, you go down and you say, here's my digest for the manifest that v3.2. Let me go out and see if there's anything that refers to it. And so you go hit the refers API, and if that exists, great, it's gonna come back out with this index. Nice thing about that index is that data type structure that already exists right now in all the specs. So we didn't have to invent anything new. And that index as we were talking about just a bit ago is a manifest to manifest. So you can just point to as many of these we want to, which means we can have a whole lot of artifacts we're all referencing at this point, which is great. And by the way, if it doesn't work and we have to fall back, we use this tag and the tag and point to the exact same data structure. So the clients don't care how they get the data structure, they're getting the exact same data back from the registry, whether they're talking the new stuff or the old stuff. And the reason we want the new stuff is having the registry manage this for us is great, but in case it doesn't, the client can manage it when you at least have something that's functional. All right, before I go too much farther, I get a lot of questions on this next topic, which is, hey, you talked about adding this subject field to the artifact manifest that you just added. You talked about having the subject to the image manifest, they'll refer to a single image. But hey, what about the multi-platform images, right? And people keep asking that question, can we have that subfield over there so the multi-platform image can point to things? And the way I'm going to start that is to say the picture on the left exists, where if you're saying I've got an artifact and I want to extend a multi-platform image with some metadata, you want to sign a multi-platform image, you want to add an s-ball with that level, you can do that. You can sign at the top level or you can sign each individual manifest, you probably want to do both, but you can do that. It's the picture on the right that we don't allow. And the picture on the right that we don't allow, the reason we don't want to have an index that points back to something else, is because at that point, you know from the index that you're creating both the subject field and potentially all the child fields, which means you can predict both of those descriptors, or not predict, you know exactly what both those descriptor values are. And the way you walk this, even though those things both point to the left, the way you walk this is in a circle. And we were talking about earlier, we made this DAG structure, the directed acyclic graph. I didn't really go into the whole what that means, but a directed acyclic graph means that it's acyclic. There are no cycles. You don't want loops, loops are bad in those, the island. So what's happening here is you have this B3 tag, you have a query of the B3 tag, you pull the image manifest there, and you say, tell me everything that refers this image manifest, so logically you walk over to that index on the right, then you say, tell me all my child nodes from this index, you go walking back to the left, repeat in infinite, and that's no good. The other nice thing we try to focus on here with all the changes we were making was to say, hey registries need to do some garbage collection, even though we don't specify in the spec, they still want it. And so the logic we put out there was to say that as long as you have the manifest exists that you're pointing to, keep the artifact that's out there. So even though the artifact itself isn't tagged, the manifested points to it still exists, so we can say, don't garbage collector, we're still in use, keep this artifact around. And so that makes it a lot more efficient, so when you have a registry out there and you've got all this stuff sitting up in your repository, you don't have to tag everyone, these individual artifacts, keep them from being cleaned up later on. It's nice to just know as long as the image is there, all the metadata is there with it. So we made all these definitions, bunch of pictures, if there are people back there that like to see the code as well, here's the low level JSON, and this is the JSON used in the fallback, so I actually go through and show you, if I pull an image, I get the digest that image, I define that tag with that digest in there, and I go query this manifest API for that tag, where I get back as an index, and in that index, the important thing here is to note that we've got a descriptor that says, here are the different entries in my manifest, and I've got some metadata I pulled up. So the metadata I pulled up is gonna say, here's the artifact type and the annotations, and the reason we wanna pull up the artifact type and the annotations is that when we get a list of all these manifest that extend our image, you're gonna have a signature, you're gonna have an S-bomb from Cyclone DX, you're gonna have an S-bomb from SPDX, you're gonna have attestation of the build process that went through, you're gonna have a whole bunch of these manifest, you don't wanna pull each one and figure out what it is, and so we pull that metadata up, and so this is, the refers API is gonna do this for you on the server, or if you're in client, you're managing this, you're gonna do it yourself, and the place you pulled up from is from the manifest of our actual artifact itself, and so the artifact itself, we mentioned earlier, you'd change that media type on the config, and that's how you know what this artifact is, so we change that config a little bit, you can put annotations over there, you can put all kinds of other metadata, and as long as that subject is there, that creates that association between the two. So I'm sure a lot of people are thinking, this is fantastic, you showed me all this lower level detail that I probably don't even care about, I'll give you good news, there's code that just does this for you all out of the box, and so you don't have to write any of this yourself, right, okay, that's the good news. I will at least show it off, and I did tell you that some of us are just gonna have some of my code in here, there are other options, I'll show you some of the options as well, but let me spin up two registries, I'm gonna define a few variables here that are gonna be used to reference these two registries, and one's gonna be listed on port 5001, the other's gonna be listed on port 5002, and I'm only gonna use some OCI media types for my stuff, so I went through a little bit of effort to make sure that I didn't have to keep track of Docker media types, OCI media types, and other kinds of things, I just kept it simple, so I made two different media types there. The first registry I'm spinning up is going to be the CNCF distribution registry, listed on port 5001, that registry has not been updated, so that is gonna be an OCI v1.0 registry that doesn't have any of the new features yet, so this is as is today, if you went talking to a registry out in the cloud today, it's probably what you would be talking to, something like this that doesn't have the new APIs, doesn't have the new artifact, and so anytime I push something up to here, I gotta do it the old way. The second registry I'm gonna spin up is called ZOT, so I'll come up with another line here, the ZOT registry has been updated, they jumped early on this release candidate and wanted to show off that they can do some new layers and greatest features, so I'll show how that one works, and like I say, their registry supports the new artifact manifest, their registry supports the new referrals API, and it's that latter one that we really care about, and so that API is gonna be interesting. You also see me turn off TLS, turning off TLS is fantastic for demos, not great for production, but it just makes my life so much easier, so I did that. And lastly, I needed to put an image out there, so I went and grabbed an image out from Docker Hub, and I'm just kinda doing a little bit of self-dogfruiting, I just kinda grabbed my own image because I knew that I had on the OCI media type, so I just wanted to keep it simple, and I wanted to keep a single platform, so I actually went through and found the descriptor for just a single platform out there, so I didn't want to go through like a multi-platform index and get too complicated. I like things to say, you know, as complicated as all this text is, I wanted to keep it at least somewhat simple. All right, so I'm gonna copy this manifest over from the internet, back over to my local registry, and then you can see the manifest is up there in my local registry now, and this is, like I say, single platform manifest, OCI, image, v1, all that good stuff. All right, that's just the setup. So we haven't done anything fancy yet, that's just the initial setup, and this is the part that everybody's gonna like, is that the part you have to worry about if you're attaching stuff is a very short slide here. I'm gonna run a sift command to generate an S-bomb, so I wanna have an example here, and pick your tool, I just happened to pick this one because it was very easy, simple one-liner. I'm generating a Cyclone DX S-bomb, and this is again where I'm getting into my regcuddle command where I say I wanna do an artifact put, and so I'm gonna push an artifact up to the registry. I'm setting the subject line, and I'm also gonna start setting some annotations, some media types of other things to say this is what this artifact is, because otherwise it doesn't know, it just kinda puts it up there a little abstractly, and that's not even good. So I push it up there with all those, and I'm gonna do a second one as well, so we can see what two of them look like together. And so the second example I'm gonna push up there is gonna be SPDX, because I don't wanna pick favorites, if you ever pick favorites in a room of security people with an S-bomb, that's chaos. So I don't like chaos, like things nice and simple and peaceful. So now we have two artifacts are getting pushed up here, and for anybody that's generating stuff that needs to start shipping your images, this is it, you're done. That was all you had to do, and your job is out, finished and complete. And the nice thing is once you have done this, from the end user side, when they start pulling this stuff, they don't have to know where to look. All they have to know is they can list the artifacts on an image, and this will go out and hit that refers API three. The refers API isn't there, it's gonna look at that fallback tag. And there's, we have two manifest that list. So let me scroll back there a little bit, you can see that it is an OCI image manifest, or sorry, there is a descriptor in there with that, this is an index of multiple images. First one being the Cyclone DX, and the second one down below is gonna be the SPDX, and you can see the annotations, you can see the artifact type, all that detail we need to be able to query this stuff later on, programmatically query this stuff later on. So again, this was a tag because it was on the fallback registry, so this tag does exist, it looks a little ugly, so this is why people don't like it, they don't wanna see all these tags out there. The one nice thing is we only have one tag, so there's not like a sig tag, an annotation tag, all these other things, we just have the one tag for everything. And then if I go and query that tag with the manifest git, you're gonna see that this is gonna look very familiar, it's gonna, unless you had a really short term memory loss here, it's gonna look identical to that, three lines up. And in case that was like too fast to go by, I'll even scroll up there and show you that there was here with the manifest list, scroll up a little bit, there was a previous one, they're the same, because that was exactly how we queried it. All right, so whether it's artifact list or the fallback tag, we're getting the same thing with the manifest git as well. So from that, the big challenge is, that's great, I wanna actually fetch my Cyclone DXS ball and SPX, something like that, so I've got the artifact git command here, where I say git me an artifact that has this subject field that points to this image. So I pass the subject and I pass that and I say filter and only show me the thing with this one media type for the artifact. And so now as long as I keep these media types predictable, I can do this and there's my SPOM right just that easy. So for the end user, all I have to do is memorize that last command. They don't have to know everything in between, they just had no last command of when I see an image, run this command, I get the SPOM and I'm done. So that's the nice part, that's the easy part. If you ever wanna do this with Curl, I won't go through this entire slide, but I will tell you that all this stuff, if you don't turn on authentication on your registry server, a lot of this stuff gets easier. If you know all your media types in advance, this stuff gets a lot easier. When you don't know all that and you try to implement that with Curl, it gets a little ugly. So that's where the tools come in nice and so that's where people start writing tools on top of this. But you can actually run these low level queries, get the manifest, pull the digest out of one of the entries and go through all that. If you're curious, I'll leave that for later on. All these slides are up online, you can go replay all these presentations later on, but I don't wanna bore you too much with the Curl details here. I do wanna show you though that we had two registries, right? And I only showed you what was going on one registry. Let me copy this artifact from a V1 registry to the new registry of the new release can of stuff that has the Repers API. And if I do that, copy those quick because it's all local in the same machine. I run the list command and you'll see I get the artifact list back. So I'm able to query this listing of all the artifacts associated with my image. I copied everything in one unit. If I do the tag listing, I don't have that digest tag anymore. I just have my one app tag. And if I even try to go back and query that tag and try to pull it, I'm gonna get, let's see, do I go up on that one? So yeah, I'm gonna hit the manifest API and I'm gonna hit that API for this one digest with that little fallback digest we had. That's gonna come up with saying not found. Four of four didn't even exist. So manifest unknown right there on that line. So without that, you might be saying, okay, how that happened? Well, you saw the big pretty picture earlier on. I just had to hit this new API called refers. I hit that query that API and suddenly what I'm getting out of this was that manifest list. So now it's the same way you get the data, two different registries, two different methods to get the data, but the same data on both of them. So that's the beauty of this. All right, one last bit of detail here for anybody in an air gap environment. Do I have anybody in like DOD air gap environment kind of stuff that has to worry about that? One, two, three, four, okay, handful. If you're at the OCI layout is a great method to move images around on a file system whenever you're copying them. So you can just copy an image from a registry into the structure. It puts it into a directory on the disk. You can zip it up, ship it around, and I can do the artifact list in there. Now, it's just a directory. So I do have the tag in there. I don't have a registry server generating that API response. But in that directory there's an index that basically represents all the tags inside the directory. This is the equivalent of having a repository on a registry on your file system. And then you can just copy this stuff all around. So if you're curious about that, another good side to come back to later on if you wanna look into that and see a little bit more details there. All right, I'm gonna keep jumping ahead because I wanna save a little bit of time in case people have questions or wanna heckle me later on. But there are other tools to do this because I think a lot of people will say, you know, great, you showed me all the Reg Cuttle commands. There is another tool out there called Oris. So if I said Oris, discover on this thing, you're gonna see all those manifests listed in there or all the different artifacts that are associated with my image and same for both registries. Whether I hit it on the new API or the old API is able to find it. So that's working great. And also you're saying, I did all this on my laptop. Well, if I go hit the GitHub Container Registry in a production environment right now on an image that I pushed, they're all up there right now. And so I'm doing this as part of my GitHub Pipelines today right now on an image that's out there in the real world. And again, I could also go through, so let me show you real quick on what that artifact is. I've got three different things attached to it. I picked out Dockerstar generating some of their attestations on things. So I got that attached to this. I've got again the two S-bombs as well. So a couple of those. So as many S-bombs or as many artifacts whatever you wanna attach, attach everything you want to. And also not just Reg Cuttle, I could have also done the Oris discover command again on GitHub Container Registry. And it's gonna say, hey, you've got all these different artifacts associated with this image. Cool. So we've got a way to do this. We got commands to do this. We got tools out here. What should we do? What's the next steps? Where are we gonna go? So for registry servers, this is all a lot of the stuff is still new. We're still creating this stuff. So if you are a registry and you don't filter on unknown fields, what do I mean by that? There's this new subject field we just added. So some registries are a little picky about what data comes in. OCI says you're not supposed to be, but there are a few people that are doing that. So we're working with them. We're getting really close, I think, unless they've already done it. They may have. And there's also the config media types that changed. There were some registries that were saying if it's a config media type that's not a container image, I don't wanna allow it. Docker Hub just recently turned that off and that was awesome for people that wanted to do like Helm charts pushed up there, that kind of stuff. We're finally able to use Docker Hub for this stuff. Additionally, the new artifact manifest. We'd like to see support for that, but that comes with a big asterisk. I'll get on that in just one second here. And the enable the refers API. So that's the thing that I think we're really pushing for right now is to get registries start adopting this. Like I say, release can't, this is just coming out the door from OCI. We've been having means and trying to get this stuff. Getting to a GA release, we're still a little ways off from that, but hopefully in the not too distant future. So anybody that's running a registry we're saying let's get this stuff out there and standardized. I think the more important part is for the people running clients, right? I think we probably got more client people in here than registry people. So if you're a client and you want portability to go from one registry to another, use that image manifest. We did say earlier on that slide, there's this new artifact manifest we created. I keep throwing asterisks on there. Part of the asterisks is that we're not really quite sure how and when we're gonna transition to that. And so we're still working through those details right now. And the other part of that is that any registry that hasn't been upgraded couldn't accept this manifest. And so for portability, use the old image manifest for a long while. To use this, this is all transparent. You don't know when you're pulling a Helm chart that has came with an image manifest. You just know you got a Helm chart. So who cares what manifest it is for a good long while. At some point it'll be nice to have things that are artifacts look like artifacts, some things that are image look like images, but we're not there yet. It's gonna take us a while to get everything upgraded. The other important thing that fallback tag, if you're writing a client of your own, you have to do that management. If you're using someone who's written the client, they're gonna do this all for you. And you just use their APIs and their tooling, they'll implement this for you. But when you have this stuff that's being implemented on the client side and not the registry doing the referrals API, what they're doing is they're gonna have to go up to that registry and manage that tag, which means if the tag's already there, someone's already pushed an artifact, you have to pull down the existing list of all the artifacts, add your new entry to that list, and then repush the new list. If anybody's ever thought about systems where you're doing like a whole lot of things going on simultaneously, you might be thinking race conditions, and that is one of the downsides of this. Is that you can have multiple clients out there pushing this stuff and clobbering each other in the process. That's one of the beauties of getting this done server side versus client side. The other important part here is the artifact type. When you pick that, if you looked at the artifact types, I was picking with the example, with the exclusion of my example early on, I was picking some media types that were well known. They came from IANA, they're registered up there, so if you go and look at Cyclone DX and IANA, they've got their list of here all the media types that have been registered with us. I picked those for all the media types I used, that way anybody else is using the same queries and you can find this same Cyclone DX S-Bomb, no matter what image it is. As long as every image uses the same media type, it's easy to find from one image to the next image to the next image. So you ask people, use some very predictable media types and hopefully that comes from the project itself saying this is our media type that we've standardized everything on. Additionally, we ask to use annotations very responsibly. And it's one of the challenges. We're pulling those annotations up from the manifest up into our listing and there are people who like to put a lot of stuff in an annotation. I'm sure people have been on the Kubernetes side has probably seen a lot of abusive annotations before on your side as well. And container image manifest, they're not overused too much yet, but I think they're gonna get there before too long and what we're seeing from registry operators is saying, if we've got to index all this detail so we can generate this API response, we're just gonna start rejecting manifests so they start cramming too much data in there. So if you want that portability, be responsible, only put the data in those annotations that you need to be able to do these queries on yourself, don't put the whole world in there. Be nice to the registry servers, they'll be nice to you. All right, so the catches, the big catch here is we're not done. We're still implementing stuff. And so as it's still being implemented, the registries, the clients, all this stuff is at various stages. There's still some debate on if and how we're gonna do that artifact manifest type. We spent three hours of glorious, fun meeting time yesterday back and forth and we're still not quite to a final solution. We'll get there, we're gonna work it out, but it's just gonna take us a while to sort out how we wanna figure that out. But for anybody that wants to do this today, like I say, I'm doing this right now in my own images. I trust it enough that I'm putting it out there so you can try it out, you can at least do some experiments, see how the code works for you. And this is the nice way that I think we're gonna see for going forward into the future of how we wanna have these things ported, passed around all these SBOM signatures, other metadata, passed around with our image in a way that we can now associate the two together and ship them together and transform. So I hope we're gonna get to that point. And so with that, I know that was a little bit of a speed run. I know there's a lot of low-level code, but hopefully that answered at least some questions that the future is here for what we're doing and it's been a long walk on the OCI to get to this point. It's been a long, painful walk for some people in the back of the room. But we're getting there to the point we're actually ready for I think end users start using us. So I hope that some people will get a little bit of inspiration from that. So with that, throw it out there for any questions. Do I see it as distribution, discoverability, or both? And I would say yeah, both, because not only can you ship your SBOM and move them around from one place to the other and keep them associated with the image itself, but you can query that image with the listing and say show me everything is associated with that image. And you may not know in advance what all these different artifact types are that are gonna be associated with the image. There can be new stuff that appears the next day that wasn't there before and so it gives you that discoverability. Yes, have I had the recursion discussion? Dig into a little bit more where you're going with that. You can do that, absolutely. And because this is a directed acyclic graph, there is always an end. There is always a bottom to that path. And so you can go down as far as you wanna go. You can have a signed SBOM that's not signed with SBOM type, but just an external signature type if you wanted to. And that would be an external artifact associated with the SBOM that's then associated with your image. You can absolutely do that. Any other questions? Okay, all you gotta do now is just turn it on. You ready? Toddie, go ahead. When can we start the spec for which part? For the cats. I keep putting cats in all my presentations. So I think, yeah, we're right there. We're ready to do it. Let's knock that out next week. All right, gotta have those. I need to include those in every one of my images from this point forward. All right, I saw the stop sign. I think my time is all up. If you got any other questions for me, I think we're just at a coffee break now. So I don't wanna hold you from coffee or tea or anything like that, but feel free to ping me and we'll chat later on. Thanks.