 Thank you for coming everybody. It's nice to see you all here and virtually as well. I'm sure there's a bunch of folks there I can't see. My name's Evan Gilman. I work at VMware. I'm one of the maintainers on Spiffy Project. I'm here with my colleague Andrew. Yep, Andrew Harding. Been in Spiffy Inspire projects for about three and a half years. Yeah, I've been four years, five years. Longer than that, yeah. Yeah, four and a half, five. I don't know if it's something I thought. Anyways, yeah, so we have a new thing here for y'all and we're gonna try our best. I've spoken to the room moderator already. We're gonna try our best to keep this as casual session as possible. So we want it to be personal for both in-person and virtual attendees. If you have any questions along the way, anything like that, please feel free to raise your hand. We'll stop, we'll talk, that kind of stuff. We're also, we've all started doing a little bit of a different presentation for you today, both in terms of material. So you'll see some stuff here you probably have never seen with regards to Spiffy. And we also purposely did not practice this because we wanted to feel natural and personal. So we hope that you enjoy it as much as we do and apologies in advance if that doesn't work out, but we're gonna see what happens. You wanna do the agenda? Yeah, so that's our agenda for today. We're gonna talk about the vision of Spiffy, kind of give the high-level overview. So the experience level of the audience, the attendees is probably gonna be varied. So we're gonna give an overview of the Spiffy vision and what it's around for, like what it's trying to solve, where it fits in and like other technology stacks and it's a part of the puzzle, where does it fit in inside that puzzle and what other pieces are generally involved. We're gonna give an overview of the different points of the Spiffy specification, including like a deep dive into the Spiffy ID and interest domains and federation. And then we're gonna kind of recap on the whole picture, the whole Spiffy surface and what it brings to the table. And we listed Q&A at the end, but like Evan said, we wanna keep this like very casual, very relaxed. If you have a question, just like yell or raise your hand, our moderator's gonna do the same thing for the virtual attendees. Like we want to talk about the things you wanna talk about. So we have some materials prepared, but we're okay with wherever the discussion moves, to be honest. Don't be afraid, raise your hand. We're here to talk. The vision. I'll do it. Yeah, so this is a nice little marketing slide kind of. But you can see like this is especially for a large enterprise, this is like not a foreign thing, right? Like people tend to have infrastructure that's dotted across different places. It's a reality for some folks, not for everyone, but it's a reality for some. And if it's not a reality for you yet, it will likely be in the near future. The main challenge when you have this kind of stuff, at least from a security perspective, in my opinion is when you need to talk across these boundaries, like how exactly does that occur, right? And not just like the physical communication, like okay, how do I address this thing? How do I find it? How do I discover it? How do I authenticate it? Not just that, but also like applying security policy in a consistent way across all of these things, right? It can be very difficult because each one of these things on this slide has its own idea about what policy looks like, what language is used, it's own idea about identity, how things are addressed, it's own idea about authentication, how you do off against these platforms, all of these things. And so, I have lived personally in this world in pre-Spiffy days, right? And I wrote a lot of software that did like translation of identity, brokering access between these things, a lot of abstraction to try to solve this problem of talking across different pieces of infrastructure, running in different providers, and maybe with different runtimes or different software platforms and things like this. Everyone has got their own idea of how to solve this problem. And so, Spiffy is an attempt to say, hey, let's do a scheme that is platform agnostic, let's do a scheme that is not anchored to a particular technology or a particular provider. And if we can do this, just provide a stable notion of identity and a way to prove identity across these boundaries, right? All of a sudden, everything above it starts to stabilize too. So that security policy we're talking about starts to stabilize because you have this stable identifier that you can reference and you can have this policy go across multiple platforms without having to change or munch it to be specific to one place or another. You also find other things like tracing, observability, debugging, all of these kinds of things stabilize. As soon as you have a call stack that traverses these platforms, how do you identify each one of those service hops and threads? So once you have this kind of notion of stable platform agnostic identifier, what you find is a lot of other things start to get easier as you jump across these different verticals. So we'll talk about the Spiffy specifications that we'll get down in the details. Ultimately, like Evan mentioned, what it provides you is kind of like this uniform identity substrate and you're gonna get a cryptographically verifiable document and that's what Spiffy brings you. It brings you the document, but it's up to you at that point once you have that cryptographically verifiable document to present that in some way to another party to assert your identity and allow them to authenticate you and hopefully you authenticate them in return. So Spiffy is just like one small piece of this puzzle. We bring the authentication layer, we bring the identity layer to the puzzle and there's things that you have to do on top that you have to actually use that identity. So sometimes you'll have workloads that are Spiffy aware, those can talk directly to the Spiffy Workload API and obtain their materials and then they themselves will engage in mutual TLS, for example, to establish that authenticated secure channel to another workload. We're in your control plane, you might decide to offload that TLS connectivity to a proxy sidecar like Envoy or Ghost Tunnel or whatever. And so we'll bring the authentication with Spiffy, you need to actually use those documents and do the secure connections in between workloads. You can layer authorization on top of that, whether that's with OPA or with something else. You can bring on protocols like GRPC and the write on top of that TLS channel and do secure workload communications that way. But yeah, it's up to you and there's a lot of flexibility in what you end up doing with the identity you receive from a Spiffy implementation. I would just quickly add to the kind of really important part on this that is we get a question about often is authorization in particular? The Spiffy project calls authorization kind of out of scope for what we're doing. What we're doing is we're providing this kind of stable uniform identity that then you can build authorization on top of. So it is a whole nother problem space that is very, very deep in its own right. It is not something that we attempt to solve in any way really. And so you bring that to the table with either OPA or even something simple like built-in allow lists in your app or what have you, right? But as Andrew was mentioning, what we can do is we can bring you these identities or we can bring you them in a very secure way and we can show you, make some recommendations on how you can use them and ways to think about them. But at the end it is up to you to make use of these primitives and build something, right? We've got a question from the platform. What does Spiffy aim to identify? I'm sorry, can you repeat that? What does Spiffy aim to identify? What does Spiffy mean to identify? Aim to identify. That's a very good question. We have a bit of a slide on this, but not exactly. So I'll just say quickly now. Spiffy aims to identify what we call a workload, right? So Spiffy is like cryptographic identity for workloads. What is a workload? And it's a bit of an overloaded term and an overloaded question as well. I think different people and different shops have different requirements for that. The most common thing that we see is we see Spiffy identify on the service, right? So if you could think that I have a Kubernetes cluster and there's a deployment and there's five pods servicing this deployment, the typical pattern that we'll see is like a Spiffy ID will be assigned to that deployment and the pods within that deployment will all receive the same Spiffy ID. This makes authorization easier. It makes a number of other things easier. It's also kind of the mental model that most people follow. There are folks who don't wanna do that. There are folks who say, I want every individual pod to receive a unique identity. They do this for auditing and observability purposes, forensics, things like that. But it does make things a little bit more complicated. So I hope that answers the question, what will we aim to identify as we aim to identify workloads? However, you view that and we have some later slides talking about ways that you may, like naming conventions and ways that you may arrange this based on what you're trying to address. Okay, my turn? What is this? Okay, so yeah, this is the overview, the spec overview. So we're just gonna, I think, kind of run through a few of the really important ones here just to kind of orient everyone, how they fit together, and then we're gonna choose a few in deep dive. So the first spec here is the Spiffy ID spec. It's like the most basic one. This is just the spec that kind of dictates the ID itself, the rules around it, how it's formed. It gives the name. It's like a username for workloads almost, right? It's one way that I describe it. You do the next one? And then there's the Svid. The Svid stands for Spiffy Verifiable Identity Document. And this is the way that you prove identity to someone else, right? It's usually like a signed document of some sort with a Spiffy ID in it, right? Maybe there's a public key in there too that the workload holds on to. We try our best to not like reinvent anything here for a number of reasons. Number one, inventing new documents like this is difficult. Number two, it requires like that new investment from the users. So we try to choose documents that are already widely adopted and well understood, work as much as we can with off the shelf software and things like that. So the two supported Svid types we have right now is X509 and Jot. And I don't know how many people are familiar with these two things. But X509 is generally useful for TLS, powering TLS. Jot is generally useful for securing the message layer, layer seven. And you use them in different places which is why we support both. You may even use them together in fact. We go on the next one. And we have the workload API. So we have this ID, this username. Then we have this document that has the name in it and there's a signature over it. Well that's cool. All my workloads are supposed to get one of the things, how do they get it? So that's what the workload API is all about. It's an API that is like a node local API. And this API is actually unauthenticated and this is like a super critical aspect of it because what that does is it allows a workload to pop up without having any prior injected secret or token or anything else. This workload can kind of pop up and say here I am and the spiffy magic will kind of figure out, okay I know who you are. Here's your spiffy ID, you know, you're off to the races. Let's see, what else about the workload API? So I guess the main reason that we have a thing like this, right, people ask why don't you just put them on desk or why have this API and all this jazz? And I think there's two primary reasons for that. The first is around structure and rotation and control. So we provide over this workload API as we provide you your Svid. We may provide private key associated with those Svids like the case of X509, right? And we also provide the CA asserts that are keys and key material that is needed to validate other Svids. And that key, there may be multiple keys if you're talking about multiple domains and things like this. And so if you wanna put them on desk it gets complicated because now you're into the world of ad hoc naming and what, you know, how do you name the files? How do you group these things together? Is that a directory? Is that this? What happens when you wanna rotate them? These things rotate all, including root CA's all rotate. And if you've ever worked at the E-Pole or anything like that, you'll know. Pain there. So that's one big thing. And because of this, the workload API is also push. So we can like rotate a root and push that update out to all the workloads and like we can accomplish that pretty quickly. So that's a big part of it. Another part of it is portability. So the whole spiffy thing is supposed to be platform agnostic, right? If we tie this, the retrieval of these S-FIDS to a platform-specific API, like a Kubernetes API or something like that, then all of a sudden who loses this portability that we're trying to build in the first place, right? So the portability is another major aspect of this. Do you wanna do the rest? I've been talking a lot. Okay. Your water's over here if you need it. Yeah, probably. Okay. So the next specification that we have in the spiffy set is specification around the trust domain and the bundle now. The trust domain is a security boundary. So if you look at, if we, we'll get into the details of the spiffy ID, but spiffy ID is essentially composed of two parts. It has a trust domain and it has some sort of entity underneath that trust domain. And the idea is that a trust domain itself is this cryptographic boundary with a set of unique signing authorities within it for issuing the identities from that trust domain. And so we have a specification around like, you know, what does a trust domain name look like? Like what, you know, what sort, what is the bundle that contains all the root material and the public keys for that trust domain for the signing authorities within that trust domain? Like what does that look like and how is that shaped? I will also quickly add there that I, you know, I was talking about structure over the workload API and multiple keys and things like that. You know, you may be talking to multiple trust domains, right? And they all have their own set of keys and that's kind of what, this bundle thing that we have, we have a few slides on that later on. Yeah, and then the last kind of specification we'll talk about today, this is, sometimes we call it the Federation API. The, it's actually, you know, just Federation specification within spiffy. And that defines what we call the bundle endpoint. And this is an endpoint that a party can talk to to obtain the spiffy bundle for a given trust domain. And this is to empower federation, right? So you can get, you know, multiple trust domains, obtaining the spiffy bundles for each other and then they're able to authenticate the identities that are minted in, you know, in the other trust domain. So we, this is a pretty basic specification. We'll get into the details of that later. But it's, yeah, it's not anything super complicated. It's basically just an HTTPS endpoint. HTTPS endpoint, it's gotta be authenticated, must be authenticated, that you can talk to to get this bundle material. So this specification is all about like, you know, what are the different profiles for connecting to these endpoints and how do you deal with the responses and things like that. So I'll take this one, since I already kind of talked about it already. This is your spiffy ID, right? So it's a URI, it's pretty much like a username except for your workload or your service. And it is scoped by a trust domain. And like we talked about before, the trust domain is going to be the, have the set of authorities that are gonna be signing identities, you know, for that trust domain. This URI is, you know, the URI spec, I don't know if you've ever dug into it, it's ginormous, it's huge, it's a mess. It's very difficult. It's bigger than it should be. Yeah, way bigger than it should be. And there are some interesting things that fall out of the inherent complexity of that specification. And what, so we've tried to take this URI spec and carve out a nice safe space for a spiffy ID within that specification. We did similar things for X509 and JOT. You know, we want to reuse these standards because they're prolific and they're out there and they're well understood. But we want to like carve out the safe spot for, you know, out of these standards that we, you know, with some defaults and whatnot that we feel are safe. And so one of those things is a limited character set. We don't allow the full range of expression on the characters that are allowed inside URIs. But, you know, a spiffy ID is really kind of this thing that you get, you get to decide for yourself with any organization what makes sense and like what this ID should look like, okay? So after you get that spiffy scheme on there and you define your trust, I mean, after that, it's anyone's business, what you do, right? So, but we do have some guidance as we've seen people craft spiffy IDs over the years and maybe take some routes. You know, we've formed some opinions and maybe some guidance around how you might want to shape your spiffy IDs in order to avoid a certain class of problems. All kinds of creative uses we've seen. I'll do this one, I guess. So we've got a couple of these. We get a lot of questions around this, like how do I name things? It's like turns out that's really hard. So I would say, I thought it would be useful to kind of provide a couple like pro tip best practice type things here. So like one of them, the first one, I guess, is be mindful of naming. People, the nice thing about spiffy ID is that it is kind of like a nice middle ground of machine and human readable. And we want to keep that aspect as much as possible. You know, in the spec itself, we have a section that is like, yeah, like the path of this thing can be whatever you want, whatever makes sense for your org. And we gave some examples of how you might do it. One of those examples there just has like a GUID. It's just like the trust domain and then a GUID after that. And then, you know, the intent is, well, you can do this if you want and you can use that GUID to look something up or whatever. But, you know, you lose that nice property of like it's readable, like I can look at it and like have meaning to it, you know. So all those cases I was talking about before around observability and things like that kind of go away if you go in that direction. So you want to kind of keep it readable. You don't want to like overload it with a bunch of data. What I see people do quite often is that they say like, well, I have these policies that I'm trying to enforce and they're like super expressive. And there's like 15 different pieces of information that I need in order to like evaluate this policy. All right, and so then they go off and say, okay, well, what should my naming scheme be then? I need 15 different things in my naming so that when they call me, I am able to differentiate and do the authorization I want to do. This is like real slippery slope and I think that you will always have this idea, right? You'll always have this idea that, you know, you're making decisions based on the shape of the spiffy ID, right, not just like some opaque string. But I would strongly recommend like strike a balance with that data, you know, don't try to overload it with a bunch of stuff that you may not need, may need, may not need. Instead, what you want to do is you want to choose like the most basic things that are going to be like super, super static, like things that are not really going to change much or like innate properties of this workload or thing you're trying to address, right? That's what I would recommend to include and you kind of draw the line there and things that are more dynamic you'll want to put elsewhere, right? So the second pro tip is it's fairly aligned to that first pro tip, right? Like, you know, the spec is very open-ended and unspecific on how you shape your IDs on purpose because, you know, different organizations have different needs, right? Your different deployments, it needs to be really up to you on how you shape your identities. But, you know, while you're going to try and adopt what patterns work for you, you want to steer clear of like Evan mentioned, shoving a bunch of metadata into your spiffy ID, right? The more specific metadata you put in that spiffy ID and more that can change, the more complicated your authorization logic becomes. You know, where you have, unless you're really good at like centralizing authorization, then you have a bunch of processes like receiving these spiffy IDs and trying to like pluck out different parts and apply policy to these different parts, it gets very complicated. You end up getting really coupled to that authorization logic and if you don't centralize it, then now you've got a bunch of people doing this, this same sort of logic piecemeal and if you ever need to like change the metadata or change how this thing is structured, there's a ripple effect that takes place and there was a talk a few days ago at Production Identity Day, you know, an organization who had gone down one route with their spiffy ID, with their naming and they'd gone a little too complex and when they decided to like reign that back in, it was a large amount of effort to try and like shift and migrate back to a simpler scheme, which ended up being better for them in the long run but it takes effort. So if you get the more specificity you like shoving these IDs, for example, you could go hog wild and start throwing like network locator information inside the spiffy ID of where this workload is, not what this workload is and if you ever go and change where that workload lives, then suddenly like the ID is changing and you gotta like update your authorization policy, et cetera. So you really wanna focus, I think, at least for me, on what the workload is, not where the workload is or other, maybe sort of tangential attributes about that workload. Yeah, and I would even add that, in terms of like pattern and convention, one of the things that we've seen is that Istio being like very early spiffy adopter chose naming convention that worked for them, right? And that naming convention was the slash s a slash service account value, or slash n s slash name space value slash s a slash service account value. And most people, a lot of people I would say have become familiar with spiffy through Istio and the impression that has been left is like this is the canonical way to format a spiffy ID, right? And that's really, I think, an important point to understand is like this is not canonical way. And it doesn't mean that you cannot like borrow those patterns, you know, for one reason or another, like you absolutely can, but you should also understand that those patterns are not going to work for everyone, right? You pluck a workload out of Kubernetes and drop it somewhere else. What meaning does this convention have anymore, right? Name space and service account. So it should be understood that the convention that you choose will not apply universally. It may be good for you, but it may not be good for a next person. That means when you want to talk to a next person with spiffy, you're going to get an ID that is shaped totally different than the one that you're used to, right? And that is a problem we've seen for interop, right? Like people get this idea that like, yeah, this is the convention, right? And like, I'm building all this policy on top of it. And so when a spiffy ID comes in, you know, I parse this sucker and I like pluck these different things out and I feed it through my policy and I make a decision, right? And then of course, the next, as soon as somebody comes and that thing runs through the parser correctly, things blow up, right? So I think I saw you there, Cole. I'll get you right in a second. So that's like, understand that this is a thing that is not going to apply to everyone. And so when you build authorization on top of spiffy, you want to strive for not like trying to pluck this thing apart and make all this sense of it, right? Instead, you should really try to strive for like a straight string compare if possible. It is like the safest way to do this. And it is also the way that will ensure that like in the future, you don't run into bad interop problems. Like everywhere expects this convention, but now I need to federate with a business partner. They have a totally different convention. Okay, now it's really simple for me to just say, in addition to my regular policy, also accept this explicit spiffy ID, right? So you can kind of stay out of trouble if you follow some of these rules. I saw a question here. So the question was that, do we have any examples of conventions that we've seen work really well in the past? I would say that that like, I would say no-ish. Well, I think that addressing a node was kind of more of a spire-ism. You know, I think by far and away the most popular convention is the one that Istio set forth years back. I am hesitant to say that that is like the best one. It's just the most popular one. You know, and Istio has had a fair share of problems of communicating with workloads that are not on Kubernetes because of exactly this thing. And they have fallen in this very opinionated naming scheme. So we're working through that stuff to try and improve the story. There have been some lessons learned which is exactly the nature of this slide. Hmm, well I'd say that one. It's not to say that the convention is bad. It's just to say that if you choose a convention and then go down the path thinking like, this is my convention, right? That's when you start to get into trouble. It should be that you just understand that there can be spiffy ideas that do not conform to your convention and that your stack should be equipped to handle when that time comes. Five slides left and two and a half minutes. Seriously? Yeah. So I think this next one will skip. We really, we talked about trust domains, I think, at length. This slide really quick was just kind of showing you kind of what the spiffy bundle looks like. It doesn't have all the information in there. The spiffy bundle specification, like this is just a standard JWK asset, okay? Where we have a few custom keys, such as defined. And that is that this bundle contains the public keys for one or more routes within that trust domain, one or more authorities. And if your spiffy implementation only supports X519SFIDs, then you might only see X519 related authorities within the bundle if it supports X519JOT. You might see both of those types of routes in there. And you're gonna see more than one, right? Because one of the powerful things about spiffy is this idea of frequent rotation, even of your certificate authorities, right? Even of your root authority material. So as you rotate new authorities in, you're gonna keep adding to this bundle and as old ones are no longer in use, you can start trickling those out. And it just stays up to date and stays rotated. Minute and a half, go. Okay. So those are, we saw trust domain and a trust domain kind of usually has like this one-to-one relationship with PKI. If you're talking about a trust domain, it probably has its own PKI. That bundle that you saw is kind of how we capture those keys. And so if you have the bundle for a trust domain, then you can validate identities from that trust domain, right? So then the question is, how do you get those bundles? How do you get those keys for validation? That's what we call federation or bundle endpoint. So here's like quick diagram of kind of the way that it works. And it's really, really basic. We just swap these bundles across so we'll have a next slide on exactly how that happens. But once these two swap their bundles, then they can exchange us feds and be validated, right? This is actually how it works. It's super basic. We have different profiles right now. There's only two. They're both based on ACPS. One does regular web PKI validation. The other one does the FIATH. And here's like some configuration snippets, how you might zero minutes, one minute, five minutes. Okay. We've got five minutes back there. Oh, sorry. So it's actually not very complicated. And if you're familiar with OIDC, JDBKS, you may have noticed that these bundles are JDBKS formatted. So it's the same spec that OIDC uses. It's literally just a JSON document. So each one of these trust domains exposes this ACPS endpoint that serves up this JSON document. And so long as you know how to find it and authenticate it, you can pull this sucker out and you can validate identities from that other trust domain. And the bundle slide, can you back up actually? If we have some time back up to the bundle slide. Yeah. So you see, here's a spiffy refresh hint set onto the bundle. This is supposed to give the caller an idea of when they should check back. Because we mentioned that these things rotate and Spire in particular has support for root rotation all the way down to leaf. So they do change over time. They may change aggressively. They may change on the order of hours or days. And so this is supposed to be that hint as to how often you're gonna go back there and check this bundle and see if the key material has changed. You can slide back for it now. Yeah. Yeah, so that's basically it, right? And you'll have software in each one that kind of is configured to go hit these things and bring them down and distribute them. Now, the way that these bundles are distributed through your infrastructure is not defined by spiffy. So you build some software that goes out and does this automation, it goes and grabs this bundle and it pushes it down to your workload and your workloads pick it up and use it. The thing that we do define is that workload API. So the API that the workloads hit to get these bundles and their S-Fids and all the other stuff. But how the plumbing between that workload API and the stuff up here is unless that's the spiffy implementation really. So if you've ever heard of spire, spire is a spiffy implementation, it does all that plumbing from bundle and signing all the way down to your workload and providing that API and connecting all of these dots, right? Finally, the way that you do spiffy off is important, we didn't talk about that, I don't think. So when you run into one of these S-Fids, right, and you want to validate it, like the very first thing that you do is you look at the spiffy ID, there's something right here. So these are workloads, if you will. So we have a foo trust domain and a bar trust domain, right? So when somebody calls you, let's say TLS, and they present you a client cert, the very first thing that you do is you look at the spiffy ID and you say, okay, what trust domain is this from? And then you say, okay, do I know this trust domain, do I recognize it? And the way that you do that is say, well, do I have a bundle for this thing, right? And if you do have a bundle, then you know how to authenticate and if you don't, then you're not federated and this thing is not going to authenticate. And so this is one thing that we have been kind of like pushing forward slowly because that type of validation is not something that is found in a lot of places. We have spiffy libraries, which will do this kind of validation for you on TLS and Jot and other things. But Envoy was recently grown support to do this kind of validation as well through TLS Custom Validator, I believe, New Extension. So this New Extension can actually take that spiffy ID, look at the trust domain name, pick the right bundle, validate it and authenticate the connection. So that's super cool. That happened a few months back, I think, a few months ago. Okay, yeah, next one. All right, so this is just kind of a slide giving you the big picture, right? So actually, I can see on this side, I'm going to crowd you. All right, so it's just showing on the top you've got this, you've got trust domain in green. On the bottom, you've got a separate trust domain in blue. You can see that each of those trust domains is hosting a bundle endpoint that the other trust domain is using to pull the bundle from each other and that'll establish our federation. You've got workloads inside each trust domain. They're connecting to the workload API and over that workload API, they're obtaining their S-vids and their bundles, not only the bundle for their own trust domain, but because these two are federated, it can receive the bundle for the other trust domain. And then those workloads within the trust domain can authenticate with each other over MTLS, right? And because the federation workloads across trust domains can also authenticate each other over MTLS. And so, you know, and those S-vids contain the specific IDs of the workloads, so that we have a strong, you know, uniform notion of identity that we can, again, this is just a piece of the puzzle, we can like layer authorization on top of and other things. Anything else you want to say about that, Evan? In the earlier slides, we had some stuff on, like, how to think about modeling trust domains. Yeah, I don't know, we're probably like a little out of time for that, but. Yeah, I have like 30 seconds. Yeah, just leave that one on, I guess, and yeah, strong security isolation, I can be summed up that way, right? Like, anytime that you have a security domain that you want very strong isolation between the two, you usually take two trust domains. A really common example is staging a production, right? Like, you don't want someone to compromise in staging to own the PKI that's used in production. You'll also find regulatory things, region-based stuff. You know, again, it's kind of same as the naming, right? It all depends on your deployment and what your needs are. So yeah, I think that's it. You want to put up the last slide, actually? The last slide has some learn more stuff. Yeah, so we have a website, of course, and GitHub repo, and our Slack is super active. I highly recommend if you're interested to continue conversation, join us there. All maintainers hang out there. Spire developers hang out there. All sorts of folks. And so yeah, we've tried our best to not do any Spire talk. We're actually both Spire maintainers as well. It's sometimes difficult to wear both hats. We've tried our best to not include Spire on this talk, but we'd be happy to answer those questions as well if anyone has them. Thank you. Yeah.