 So I don't think we need to give much of an introduction to what is Sigstore here, but I think this talk is really, you know, principled around the idea that maybe Sigstore is new to you. So for those of you in the room who are probably already, you know, familiar or invested in Sigstore, this, you know, was probably your journey at some point, but I think we're targeting, you know, folks who are interested in learning what Sigstore is and how things actually work. And that was really the, you know, the kind of premise of what led me to, you know, talk to Zach about, you know, building out this talk. So generally when you ask what is Sigstore, somebody gives you something like this, right? Like this is a high level diagram. It's throwing around a lot of jargon. And, you know, for the most part, it's not the most helpful resource to actually grok exactly what's happening when you sign something with Sigstore. So our goal is to basically dive into each of these components and, you know, break down each step so that we can really kind of go under the hood as to what happens when you sign something with Sigstore. So this is really kind of like preface by my personal experience when, you know, early on in my IT career, I, you know, was learning networking and, you know, kind of read about the, you know, seven layer burrito or the OSI stack or whatever and, you know, tried to really grok what was going on by looking at layers and things like that. But really at the end of the day, like, you know, I didn't truly understand what was happening until this magical moment when I popped up in TCP DOM and, you know, started capturing packets and, you know, with my hands on something real, I could actually understand what was going on in networking, right? Like I felt like I was, you know, that was my kind of Neo Kung Fu moment when I truly understood something. And that's really like the idea here, right? It's like we'd like to actually give you something that you can touch and interface with directly as opposed to just kind of talking about higher level concepts and kind of maybe remove some of the abstractions that Sigstore makes, you know, for developers to make the tool easy and actually kind of dive into how things work under the hood. So the way that we did this is we basically, you know, Zach added a few lines of code and, you know, created a basically a fork of cosine that instead of actually having these things just exist in memory when you run, you know, a cosine signature to actually dump them out to disk, right? So like we actually have these artifacts around, we can inspect them, we can truly understand everything that's going on just because they're, you know, locally there in the file system. And we made this available as well. And there'll be a blog post that will kind of walk you through this if you want to recreate this yourself. So this is, you know, basically, you know, what we did and in this case, we actually just signed this blob of, you know, hello, SigstoreCon. And, you know, fortunately, we don't need this cosine experimental flag anymore due to cosine being GA, which is great. But, you know, again, the key piece here is that, you know, when you run through these steps that are recreatable is that you'll end up with these artifacts on disk and we can actually kind of walk through each of these artifacts and find out what's going on during the signature operation. So first off, like, let's kind of lay out what we're talking about. So we're talking about like keyless signing. Obviously, Sigstore provides multiple ways to sign, but, you know, the keyless signing is, you know, probably the most interesting, particularly from a human perspective, right? Like if you're like a machine, like you're probably not gonna be using this, but as a human, like there's a lot of just intrinsic benefits to this, right? First off is like, we're gonna start here with OIDC and like what we call the OIDC dance. And a little bit of like a plug here is like, the whole concept of what we're trying to do is we're actually trying to assign, you know, your identity to the artifacts that you produce, right? And in the old world of like, you know, using things like, you know, GPG, et cetera, like that identity is basically just a blob of, you know, of crypto like on a file system, right? That's not the best way to assert your identity. Like in most environments, like, you know, SSO and OIDC is kind of the way that actually helps you, you know, assign what that identity is. So there's a lot of kind of benefits into OIDC, right? Like if someone leaves, like you can, you know, revoke their access, you don't have to worry about a key leaking. There's a bunch of, you know, baked in benefits here, but in essence, what we're gonna describe is kind of how this open ID connect flow works. So first off, when I assign something, you know, we're going to be interfacing with the public GA, you know, Fulcio instance, our certificate authority in Sigstore and just like any other certificate authority, like we basically need to convince that authority to kind of, you know, give me a certificate that says this email or this identity is the thing that's actually signing, you know, the artifact in this case, just the blog. So we're gonna walk through the authentication piece. Like how do I actually prove that I control my identity? And I've been kind of discussing like OIDC is kind of prime for this, right? Like as opposed to keys with OIDC, you can enforce things like, you know, non-fishable two-factor or strong factor authentication. You can set up policies around it. You can, you know, trust certain identity providers and things like that. But at the end of the day that OIDC is just going to come back with, you know, a jot that, you know, is basically going to help us take that identity and actually do something with it. So when we get back that OIDC token, what we get back is basically, you know, base 64 encoded, you know, JSON document and that includes a header, a payload and a signature. We'll kind of walk through these. So, you know, we've talked to the identity provider. We've, you know, done these sign-in with Google Flow. We've convinced them that, you know, we actually own our identity. And when we get that jot back, when we look at the header, there's a couple things going on, right? And the question that we're asking ourselves here is like, you know, how should the verifier, which in this case is Fulcio, the certificate authority, actually check the jot that actually gets assigned to us or token. So if we take a look at the header, we can see that, first off, it needs to know that the algorithm to verify this is, you know, RSA 256. There's also a key ID, which is helpful for us to kind of locate which public key we're actually going to be verifying against. This is in case, like, you know, Google or whatever my identity provider is decides to actually rotate those keys. And then we get into the payload, right? And this is definitely the most interesting piece, right? So inside of this jot, we have a number of interesting attributes. Like, the first one here is this issuer attribute. And this basically tells us that, you know, the issuer is OAuth2.6.dev, but in this case it's actually referring to DEX, right? I just mentioned that you're using the Google kind of sign-in flow as one example, but we actually use DEX for reasons. And, you know, we can discuss those if you're interested. Definitely feel free to ask questions. But beyond that, we have a couple of really interesting attributes about Jots. One is this audience component, and this defines that, you know, the audience is SigStore. So when we give you this jot, that means that you can't reuse this to log back into Google or take your Google credential and go authenticate to any old service, right? Like, the idea is that we scope that audience down to only be valid for SigStore, which is an important security attribute. There do be dragons here, right? Like, there's some components with certain, you know, implementations of jot that, you know, might not parse this correctly, but there are additional protections here, right? One is that we have this expiration date, and if we actually kind of zoom into this, we can see that this jot is only valid for one minute. So the risk of this leaking and, you know, causing a very bad day is, you know, diminished by that short time of validity. And then, of course, we actually have the identity, which is, you know, in this case, it's Zach's email. So, you know, feel free to send Zach an email here. Sorry for the slight docks there, Zach. And finally, we have this connector ID. And the reason that we have this is because, you know, we kind of talked about how, or federated claims and then, you know, connector ID, because we use decks, right? And like, the reason behind that is like, you know, we kind of need to like smooth out, you know, different implementations for different identity providers. And in this case, you can kind of see that, like the federated claim actually does, you know, come from accounts.google.com in this case, right? So like, we know that this person who claims to be or who actually was proven to be Zach at ChainGuard went through Google to actually sign and get that piece of identity from this jot. And then finally, you know, if you look at the final bit, we have a redacted signature. And the reason that it's redacted is, you know, not because we like to wear tinfoil hats, but because, as we mentioned, like there are some implementations that, you know, don't do a perfect job of kind of verifying those, you know, those values and we just didn't really want it to leak. So, cool. So, so far we've talked to the OIDC provider. We validated who we are. So we, you know, Google has told us that, you know, this is Zach. We got back a jot and that jot, you know, was basically scoped down so that we could only do six store things with it. Next, what we're gonna do is we're actually going to generate a certificate request, right? So you've probably done this at some point where you basically have a, you know, signature request to a certificate authority if you've ever registered a domain and got a certificate for it, it's very similar. But we'll actually kind of break this down. So in the certificate request, we have a freshly generated public key, right? So we generate a public private key and we, you know, publish that public key in the certificate request. We also have a signed email address. So we have a signature over the email from the OIDC token. And the way that we basically do this is we take that private key that we have and then we sign that, you know, email address and that kind of proves that we're the true owner of this public key. And then finally, you know, there's kind of a reference here to, you know, we see the CSR kind of being null. This is because, you know, we, Sixord doesn't use the standard kind of PKCS number 10, sorry for throwing those, you know, bits of jargon at you if you're not familiar, but that's just kind of the standard certificate signing request that is typical in a lot of these implementations. All right. And then now you've sent your certificate request. Hopefully when you request a certificate, you get a certificate and that's what we're gonna see next. We're skipping over the CT log for the sake of time, but happy to talk to anyone afterwards. So this is a long document and what we're doing is we're printing it out using a tool called step, which is a very handy way to look at a certificate. And so we're just gonna run through the highlights. So very similar in many ways to the job that we saw before. The issuer here is sigstore.dev and we're actually coming through Sigstore intermediate node in the middle. Like the JOT, if you look at the validity, it's only valid for a very short period of time. This is one of the key security guarantees we give you with Sigstore is that the risk of a private key actually leaking is mitigated because the certificates that we're issuing are only around for 10 minutes. So after 10 minutes, such a key is gonna be pretty useless. And then there's usual stuff that's in every certificate, the public key and so on. If we go to the next page, you can see some fun stuff. So there's my email again. So Sigstore basically took my email from the JOT and it stuck it in as the subject alternative name, which is sort of for convoluted reasons the way you specify the name of the party that has been granted the certificate. We also have all these fun numbers right below it. Those are an X509 extension registered to the Sigstore project that indicates what the identity provider used as the source of the identity that wound up in the sand is. So when you're gonna verify this, very typically you wanna know who's signing, but also who says that that person controls this public key. So zjn.chengard.dev as a contested tube by accounts.google.com much, much more convincing than zjn.chengard.dev as a contested tube by Neopets. So the next thing we're gonna highlight is the SCT. This stands for Assigned Certificate Time Stamp. Again, we're gonna gloss over many of the details of certificate transparency here, but this is basically a receipt from the certificate transparency log that says I, the certificate transparency log have seen this corresponding cert and it's gotten a company in signature. And then finally, at the very end of the certificate, you're gonna see a signature and this is actually a signature from that full CO intermediate node. So you can take this certificate and there's gonna be a certificate chain that gets you all the way back up to the full CO root key, which you the verifier will have gotten through tough. We saw a great talk earlier today that went through many of those details, which is great because I didn't put them in this deck. But yeah, and so this basically, with this certificate, you can sort of trace all the way back up to full CO and know that the identity mentioned in the certificate, as long as you trust full CO, that any signature that validates against the certificate is legit for that identity. Great, so now we have our certificate. Let's go ahead and sign something. And typically what you're doing in SIGstore, you're not just signing the naked bytes of the image or in our case the data.txt file. You sort of have to format that in a little bit of an envelope and that's going in the API, something that's referred to as a proposed entry. So there are a bunch of different types. Here we're looking at the default type for signing an artifact in Cosign. I would just call the hashed record. So a lot of Base64 nonsense that I don't expect you to be able to read, but I'm illustrating for you what these things are. So this envelope is going to mention the hash of our artifacts. So if you see that value right there at the top, if you run SHA-256 sum on that data.txt file we created earlier that said hello SIGstore.con, that's what you're gonna get. Finally, you're gonna get a signature over that data, the data in the hash that validates against the public key that we just generated and that goes in our X509 certificate. So remember the X509 cert had a public key in there. That's that if you take that public key you can use that to validate the signature over that data. And then finally we actually stick that entire certificate in here under the slightly misleadingly named publickey.content field. This is actually a Base64 encoded version of that certificate that we just saw. So then Recor is gonna take that proposed entry. It's going to make sure that the signature checks out and it's going to return to you something called a signed entry timestamp. And so this is, we started in log entry.json. This is relatively a simple document. The complicated part is in verification which we'll see on the next slide. But for now the body is the most interesting thing. That's actually a Base64 encoded version of the file that you just saw on the last slide. The astute observer might note that there are like triple or quadruple Base64 encoded things in there by this point. That's just how life goes sometimes. There's also an integrated time. So remember we made a big deal earlier about how the public key was only gonna be valid for 10 minutes. Does that mean you can no longer validate an artifact after 10 minutes? That would be very, very annoying and make this a pretty useless system. So no, you actually can validate things after 10 minutes after the certificate has expired. What you do is you check that the signature was made during the lifetime of the certificate. And so that's this integrated time here. Right now Recor is typically the source of this time. There's some fun ongoing work to allow you to plug in a timestamp authority following a protocol like RFC 3161 or rough time and use that instead or in addition. Yeah, and then finally we're gonna look at this verification stuff. This is information that you can use to cryptographically check that that log entry that we submitted actually wound up inside of Recor. And unfortunately don't have time to go into what a Merkle Tree is, how a transparency log works, but this is sufficient basically cryptographic information that you can check, okay, all this stuff wound up inside of Recor. And then finally we have the signed entry timestamp, which for the lazy or for the offline, if you don't wanna go and do that check all the way back up to Recor, you can just take Recor's word for it. So if you have Recor's public key, you can, this signed entry timestamp will be a signature over a bunch of the rest of the data in this log entry.json. And so that should be enough to convince you again that this other stuff, the body, and the timestamp are legitimate. Yeah, so now you've seen everything. Step four is just publishing, which is going to vary a lot based on your use case, but could look as simple as like FTP. You know, it's just about getting sort of the data, that certificate, that signed entry timestamp, and then the signature over the data. Getting all of that to the end user who's gonna verify it. And there's some ongoing work to turn those four things into one thing we're gonna call a bundle. Shout out to Frederick, who's been working really hard on a specification for that. And for the Kubernetes folks in the room, like I think it's worth calling out that typically the location that we store these values is in an OCI registry. So you don't have to think too hard about where you actually store this, because it sits alongside the container image if you're using containers and Kubernetes, which makes it that whole experience like just super easy in plug-in. Yeah, yeah, and so for those who don't have the luxury if you're working on the integration with a package manager, I see a couple of folks in the room who are doing that right now, you're gonna have to unfortunately take care of this step four yourself. But all that is pushing bits around. There's no fancy cryptography. The fancy cryptography happens before, and at the end where folks are verifying. Speaking of, this is kind of the reverse of that process. This is what a verifier has to check. And it seems kind of complicated, right? Six steps is a large number of steps, but you'll actually see these correspond pretty closely to the steps we took when creating all of this. So you're going to check that the signature is from who you think it's from. The way you do that is by looking at the certificate. Check the subject and the issuer of the certificate. So if you trust universally artifacts from me, which maybe you should, maybe you shouldn't, but you can sort of check for a subject alt name that says dj.netchengar.dev in an issuer or accounts.google.com. You're gonna check that that certificate is valid, that it validates against Fulcio's public key. That Fulcio public key, again, you'll have gotten via TuF. So refer back to the TuF talk earlier in the day. You're gonna check that the signature on the log entry, so that's where you get that timestamp from, is valid for the, sorry, the signature in the log entry. So that's the signature on the actual data itself, is valid for the public key in the certificate. You're gonna check that the log entry timestamp is signed by recor. You're gonna check that the timestamp was during the window in which the certificate was valid. And finally, this is actually really important and really easy thing to forget to do. You're gonna check that the data that was signed is actually the data that you care about. So it doesn't do me any good to check all of these things and then to not say, oh, by the way, I validated this over here and I'm gonna use this totally unvalidated blob and run that. You gotta actually match up the thing you're running or the thing you're downloading to the log entry. Yeah, so at this point, hopefully this has demystified, and I use that word very deliberately, a little bit about how Sigstore and Cosine work. It's not magic, right? All that's just bits and bytes. And I see Bob in the audience here. I would encourage you if you wanna learn more. There's gonna be a blog post version of this, which is cool. If you wanna go even deeper, there is a link which I know you cannot click, but if you just Google it, it'll pop up Sigstore the bash way, which basically takes you through this very like bits and bytes approach to how Sigstore actually works, but totally on the command line, you compose all these JSON documents yourself, and like any good cryptography security project, if you screw up, it just fails and it doesn't tell you why it failed. But it's a really instructive exercise, I think to go through sort of the next level of take it apart to understand how it works. Yeah, we hand-leaved over a bunch today, happy to take questions offline about sort of decks and why there's a transparency log and how that works and so on. But hopefully this sort of took you from having this abstract understanding of how this all works. It's a complicated system to sort of understanding a little bit. Oh yeah, okay, that's how the data flows through the system. That's where this entry comes from. That's what this means. Anything else you wanna add? No? No. Cool. All right, thanks everybody. Thanks. Thank you. Cool. How are we doing on time? Do we have time for a question or two? Okay. Does anyone have questions? Oh, sure, sure, sure. I will hopefully be able to get that back. Yes, yes. Give it a second. So the 10 minute window is here in the validity here in the X509, sorry. Oh, sorry? Oh, the, yeah, this one? Yeah, yeah, yeah, yeah. So the 10 minute window is going to start when Falsio creates that X509 insert and it's going to go for the next 10 minutes. So you better get that proposed entry in the next step to recore within those 10 minutes. Otherwise, that timestamp is going to be outside of that window. Fortunately, the typical time that this takes is like a couple of seconds, so 10 minutes is a pretty big grace period. Sorry, okay. Yeah, yeah, yeah, yeah. So the 10 minutes is a somewhat arbitrary number. It should be pointed out. We chose it as sort of like very, very worst case scenario. This is all going to happen, even if recore. Right now, recore is actually quite speedy due to a bunch of things, including the sharding work, which has sort of sped things up quite a bit. And so we're not worried about that, but in the long, long term, we might worry about, okay, maybe recore is eventually consistent. It takes a while for things to get integrated. So we want that timestamp to happen. We think 10 minutes is kind of a good middle ground between, ah, it doesn't feel like very long at all. It feels like very unlikely that your key would leak in an attacker, we'll get it and be able to sign stuff during that window, but still long enough that you're gonna be able to do what you need to do. Yeah, yeah, yeah, that's a really, really good question. Sorry, oh yeah, great question. That's a really good question, which I'm going to repeat right now. The question was, when you're verifying, how do you know what the subject that you're supposed to be checking is, and in particular, how do you know what the issuer is for that subject? So this is the sort of really unhelpful answer I could give you is that this is out of scope for SigStore. And it's a really unhelpful answer, and that's sort of not where we want to go in the long term, but basically, SigStore handles the mapping, the identity, to the artifact leg of things. We would strongly encourage you look at something like Tuff for doing the delegation for that artifact. So in a closed ecosystem, in an organization that's your own company, you might have one party that's in charge, one service, or one individual, or one team that's in charge of signing all the artifacts. In that case, you can sort of hard code at the verification site, a verification policy that says every artifact that run must be signed by a security team at mycompany.com. I'll pick on William, because I see him in the audience here. If you're gonna do this at the package repository level, then basically the package repository, something like the Python package index, is going to basically need to say, for package X, maintainer Y is trusted to sign that. And the reason I've been sort of so pedantic about also always putting the issuer there is that I think you should consider an identity to be a tuple of sort of an email or a username, comma, the issuer of that identity. So zjn.chengar.dev, as a tested tube by accounts.google.com, as opposed to, yeah, or Neopets, if that's who you really, really want to base the root of trust on. That answer to the question? Yeah, it punted a little bit, but I'm happy to discuss with you offline some cool tricks. Okay, I think my MacBook is telling me we're done. So thank you very much.