 Hello, everyone. Welcome to Cloud Native Live, where we dive deep into the code behind Cloud Native. I'm Annie, and I'm a CNCF ambassador, and I will be your host tonight. So every week, we bring a new set of presenters to showcase how to work with Cloud Native technology. They will think, they will raise things, and they will answer all of your burning questions. Join us every Wednesday to watch live. In addition to this event, there's a lot more going on in the CNCF world, so you can check those out on the various CNCF and Elephantman pages, for example, Cube Day Japan, Cloud Native Security Day, and so much more. It's up and coming. But this week in Cloud Native Live, we have Flynn here to talk to us about the Zero Trust Network Policy with Linkerd. As always, this is an official live stream of the CNCF, and as such, it is subject to the CNCF code of conduct. Please do not add anything to the chat or questions that would be in violation of that code of conduct. Basically, please be respectful of all of your fellow participants as well as presenters. And as always, we take questions throughout the hour that we have here together. So pop the questions into the session chat and we'll get to them as well there. So with that over, I'll hand it over to Flynn to kick off today's presentation. Thank you. Glad to be here. I am Flynn. I'm a tech evangelist for buoyants, the people behind Linkerd. You can reach me as Flynn at buoyant.io by email or at Flynn on the Linkerd Slack. We are going to talk today about Zero Trust Network Policy and Linkerd. Zero Trust is there's a lot to this topic, so we're a little heavier on the slides as opposed to demo this time around. And we'll see how it works. There's a link in the chat to the repo with all the demo code I'm going to be working with, all the stuff I'm going to be showing. I would encourage you to take a look at that. If you have questions, stick them in the chat. We'll get to them as soon as we can. OK, Zero Trust Network Security. Zero Trust has actually been a major focus for Linkerd for some time. It's a little bit of a weird name. It should really be zero assumptions about trust instead of Zero Trust, but that takes too long to say. So we just call it Zero Trust. It's all about be explicit about trust as opposed to assuming things about trust. In addition to being a big focus for Linkerd, it's a big push in the industry. In the United States, the White House actually issued a mandate that all the federal agencies have to worry about this by the end of next year. So yeah, a little bit of a big deal. When you talk about distributed applications, like we do all the time in the cloud native world, some of the impacts that Zero Trust have are first, you don't get to assume that the traffic between your workloads is safe or that it was what was actually sent. So you need mechanisms for confidentiality and integrity and authentication. You cannot assume that the network is trustworthy. You cannot assume that IP addresses, for example, won't change under you, which means that you really need to be thinking about identity in terms of workloads, not the network. You can't assume that because somebody was able to do a given thing half an hour ago, it's still OK for them to do it now. This is usually phrased as check every access every time. And in fact, you have to do that everywhere as well. There isn't really a perimeter that you can draw around anything in the cloud native world. So instead, you just have to do checking all the way down the call graph every access every time. This is a very whirlwind overview. There's a blog post or an article up on InfoQ that talks more about this that I would encourage y'all to read. There's a lot more that could be said about this one. But the core of it really is you try to make zero assumptions about what is secure and what is not secure. And you check every access every time, no matter where it's coming from or where it's going to. Lincority actually has tools that help out with all of these things. On the front with confidentiality, integrity, authentication, that's why we're doing mutual TLS between all the workloads everywhere. We'd use workload identity via, we take the Kubernetes service account for a given workload and then bootstrap that into an x.509 certificate identity. That's the way we handle workload identity. We're going to talk today about policy, which is how we handle authorization. And we put sidecars everywhere, partly so that we have things running in the places that they need to be running in order to do the enforcement everywhere. So let me take a moment here to point out, yeah, absolutely do throw in questions as they come up, please. But we're going to continue on a little bit and see if questions show up. If we look at a Kubernetes cluster very simply, you might have a typical cluster where you've got an ingress talking to the web, talking to the Foo and Bar services, and then Foo and Bar also talk to each other. When you throw LinkerD into the mix, we end up actually rerouting all that network traffic so that instead of going directly from the ingress to the web, it instead goes from the ingress into the LinkerD proxy over to another LinkerD proxy into the web service. This means that the proxies are in a great position to go through and do mediation of all the network communication, to enforce access control, all of this stuff that we just talked about. There's also a control plane in LinkerD that kind of tells the proxies what to do. As far as the way that this model is used for policy, Kubernetes and LinkerD both default wide open. They allow any communication to happen from any workload to any other workload. The important thing to remember in the core of all of this policy discussion is that the point of policy mechanisms is that they give you the ability to say no. In particular, this is a way that we can give LinkerD the ability to reject a request that has not been explicitly authorized by a policy. It's also worth pointing out as we go through this discussion, authentication, authN, is about knowing who an entity is. Authorization, authZ, is about knowing how far we trust that entity. These are two very separate things that often get mixed up. LinkerD has two separate policy mechanisms that work together. The first one, which has been part of LinkerD for a long time, is workload-based authorization policy where you get to say this workload is allowed to talk to this other workload. And if you don't say that, the workloads don't get to talk to each other once you turn this on. There's also a route-based authorization policy where you can say a given workload is authorized to make a particular request from another workload but not just broad things. And then there's a question from the audience from Google. Does LinkerD use, in any way, PSP? PSP expands to too many things in my head for me to be sure which one Ugo is talking about. So how about clarify that? And then we'll see, we'll go forward from there. Perfect. Yeah. Okay. Important note for the rest of this presentation. Workload-based authorization policy and route-based authorization policy take too long to say. So we tend to talk about workload policy or route policy or route-based policy, things like that, all the same thing. Pod security policies, excellent. Those generally are at a lower level in the Kubernetes cluster than LinkerD is worrying about. So it would be the sort of thing where we're talking about things that the pod security policies already allow and LinkerD allows you to be more refined than that. Does that make sense? If that doesn't make sense, let me know. All right. So an example of workload-based policy. If we throw in a policy that says that only the web service, the web workload gets to talk to the bar workload, then this communication between Foo and Bar will be denied as soon as the request shows up with the policy. Effectively, you end up with this graph where it's just, web gets to talk to Foo, web gets to talk to Bar, but Foo and Bar don't get to talk to each other. Not clear in the docs how LinkerD does egress proxy configuration. Let's come back to that at the end of this talk and go from there. The short answer is, there's not a lot about egress in LinkerD right now and that's an upcoming thing, but let's come back to that a little bit later. Talking about route-based policy which showed up in LinkerD 2.12 and I think I forgot to say that earlier. Sorry. Route-based policy is more like Foo is only allowed to ask Bar to get slash FooRequest slash. So if you install that policy, then if Foo does a get a FooRequest, it will be allowed, but if it does anything else, it will be denied. Not tremendously complex as a concept, but this does get very complex in practice as we sit here and start digging into everything. Route-based policy is actually one of the most complex things, possibly the most complex thing that we've put into LinkerD so far, hence this slide presentation being a little bit longer than normal, but yeah, as you have questions, please do let us know. So let's talk a little bit here about how we actually express policies. The basic idea in policy expression is the same whether you're talking about workload policy or route policy. There's a default that you start with and then you use LinkerD CRDs to specify exceptions to the default. We have the server CRD, the new HTTP route CRD, the new authorization policy CRD, there's a previous server authorization CRD that's actually deprecated in favor of authorization policy. It still works, don't panic. And yes, this does bring the total number of LinkerD CRDs to six, which we feel kind of bad about because we're trying to have really few CRDs. The HTTP route CRD actually comes from the Gateway API. We're kind of moving LinkerD over towards the Gateway API just to reduce the number of new things people have to learn. But yeah, like I said, this is a complex thing for LinkerD. Also worth noting out or worth pointing out, excuse me, only HTTP route is about route based policy. If you're talking about workload based policy, you only need the server and the authorization policy. So default policies, you set the cluster default policy when you install everything, when you install LinkerD by setting proxy default inbound policy. The default is wide open, which we'll talk about in a second. You can override the default, the cluster default policy at the namespace level or at the workload level by using the default inbound policy annotation. A thing that gets a lot of people into trouble, the default policy for a given proxy, the chunk of LinkerD running next to a given workload is fixed at the time the proxy starts. If you want to change the default, you need to restart the pod. We will see this in the demo later, but this is a thing I am not gonna lie. This has burned me personally more times than I can count while working through this demo. The valid default policies, the possibilities. All unauthenticated, this first one allows any traffic from everywhere to everywhere, and this is the default because it mirrors the Kubernetes default. We can then move up to, you have to have traffic from an IP address in the cluster to, you have to have traffic that has a valid LinkerD MTLS identity to it has to be from the cluster and have a valid MTLS identity to no, we're not gonna allow anything at all by default. We're gonna deny everything and we will require you to put in exceptions for the traffic you want to allow. This last one, this is where you wanna be if you're doing proper zero trust is deny everything unless you are explicitly allowing things. So, going back to the CRDs, the server CRD talks about the pods that embody a particular service, a particular workload that we care about, and it also talks about ports that they're bound on. The HTTP route talks about specific requests that a given server might be expecting. The authorization policy ties everything together where it states a policy that can be associated either with a server or with an HTTP route to allow traffic through to that server or via that HTTP route. And again, server authorization is deprecated in favor of authorization policy, but server authorization does still work. You don't have to throw it away yet. Worth pointing out if you're trying to do route-based stuff, you do have to do that with authorization policies. Okay, so for workload-based policy, you associate the authorization policy with a server. For route-based policy, you associate it with an HTTP route. Again, questions so far, am I missing something here? Not from the audience, but if there is any, just pop them into the chat and we'll get to them. Okay, all right. Here's an example server CRD. This is saying that within the EmojiBoto namespace, we're gonna have a server that we're gonna call voting-grpc. And it will comprise all of the pods that have the voting service, the app voting service label and are using the voting GRPC port. We are also telling it, this particular server is using the GRPC protocol that proxy protocol specification is often optional, but it allows you to skip protocol detection, which can speed things up and generally make things a little bit more comfortable for you. So this would be an example server that we might use with the real EmojiBoto application for its voting service, which is a GRPC service. Another thing that servers can do is they can cross workloads. So this is one that says, basically match every pod that's listening on the Linkardee admin port and is in the EmojiBoto namespace. This probably does not look terribly useful, but it's actually a thing that we're gonna use because the Linkardee viz dashboard uses the Linkardee admin port. And so a server like this gives us a very easy way to say, to talk about authorization for Linkardee viz itself. Another thing that often gets people into trouble, the moment you create a server, that server overrides the default policy to deny. With the exception in 2.12, that health probes will still be allowed if they're defined in the workload. This means that as soon as you create a server, you must also create an authorization policy that you associate with that server in order to start allowing traffic. I should modify this slide to say you could also do it by associating an HTTP route and authorization policy, but we'll get to that in a bit. This, like I said, tends to cause people a lot of trouble because it can be a little surprising. You go through, you add a server, and suddenly things break, so be aware of that. All right, on to the HTTP route CRD, which is new in 2.12. We borrowed this from the Gateway API. It's in a different API group though. It's in policy.linkardee.io because Linkardee does not currently implement all of the Gateway API HTTP route, so we decided to just put it into its own API group to make that a little bit more clear. You associate it via this parent refs with one or more servers, so this one would be we're associating this with the author server server. There's too many uses of server, sorry about that. The HTTP route also specifies particular requests that are okay going to the server to which the HTTP route is associated. So this route, this HTTP route rather, will allow gets to slash authors.json or gets to anything with the prefix slash authors slash to the author server, whatever. And then it would look at the server resource to figure out which pods and which ports the author server was. Again, much like servers, the moment you create an HTTP route then the default changes to be denying. And in particular, that means that when you create an HTTP route for a server, the magic default rule that allows health probes to work will go away. And so you'll need to be explicit about allowing the probes to start up again. Typically you just do this by adding another HTTP route rule for the help see endpoint or whatever you need for your service to do for health checking. So it's not a difficult thing to fix, but it is a thing that you have to think about. Finally, we have the authorization policy CRD. You can associate these with a server or an HTTP route and it tells LinkerD who is allowed to make these requests. So this particular one, if we break it down is associated with an HTTP route called authors get route. It requires that you be using mesh TLS, sorry, it requires that the only entities allowed to make requests through this HTTP route are those that match the mesh TLS authentication resource named web app authors auth N, web app authors auth N. In this case says, oh yeah, this is gonna be in the books app namespace and they must be using TLS with a particular identity. Web app actually won't work. There's a much longer thing that won't fit on this slide. So we will show that in more detail in the demo. But this is an example of setting up an authorization policy to allow one particular workload to be the only one that is allowed to make a given request because only one particular workload should have that web app service account. All right, you can also match multiple targets by specifying a namespace in the target ref. In this case, everything else is the same, but rather than associating it with one particular HTTP route, we're gonna associate it with any server or HTTP route in the books app namespace. And okay, again, questions so far. Not so far. Okay. That kind of makes me nervous because we're covering a bunch of material fairly quickly and either it's going really well or it's going really poorly. So if anybody in the chat wants to provide feedback for whether it's well or poorly, I would really appreciate that. To put all this stuff together, when a request arrives on a meshed port that matches the server, Linkerd is then gonna go chase down all the HTTP routes and authorization policies and server authorization CRDs that it can find that match that server. And there must be a path through all of those resources for the traffic to be allowed. Some examples. If you have a server and, oh good, somebody says it's going well, I really appreciate that. If you have a server and there's no authorization policy for that server, that request will be denied because that server will click everything over to default deny. If it can't find an authorization policy to provide an exception, we deny the request. If you have a request that matches an HTTP route for a server and there's no authorization policy with that HTTP route, again, denied. If you have a server that matches an HTTP route and there's an authorization policy that goes through and links all these things up and provides for an identity match, then that will be allowed. This is the good case. And another comment that going well. Thank you. I appreciate that. Suppose though you have a server that matches an HTTP route. The HTTP route matches an authorization policy that is for some identity that the request is not using but the server has an authorization policy that's for the request for the, wow. The server has an authorization policy for the identity that the request is using. So the HTTP route authorization policy does not match but the server's authorization policy does match. That will be allowed. And the reason is, as long as we can find any path through everything, the request is good. Yeah, there is a comment from Dara from Lincoln City. Would be nice to cover some comparison of East New York, for example, maybe they address different problems but would be nice to get your opinion here. That's another one I think we should come back to at the end. I have lots of opinions and yeah, let's make sure we have time to go back and talk a little bit about that at the end. Yeah, let's keep up the suspense though. Well, I work for buoyant. So it might not be all that suspenseful where my opinions are gonna lie, but that's okay. Okay, so an important takeaway here is, yeah, this can be complex. I'm actually gonna put more examples in the GitHub repository to try to explain some of this in more detail. We could spend a lot of time going through and walking through all of these examples for a place that will be denied or a place that it would be allowed. And that'll probably be a little bit easier to do, kind of self-paced. So I'm gonna add some more stuff in the repo for that. All right, let's talk about some sources of much trouble. Don't forget that as soon as you create either a server or an HTTP route, they flip the world over to default deny, no matter what the default would be without the server or the HTTP route. In particular, you create a server, you gotta create an authorization policy. Create an HTTP route, gotta create an authorization policy. Also, generally speaking, if you create one HTTP route, you are usually gonna have to create other HTTP routes to kind of fully specify the exception set for your HTTP traffic. NGRPC is, of course, HTTP traffic. It's also worth pointing out, don't forget if you have a very permissive authorization policy for a server, that can permit traffic around your less permissive HTTP routes. So that's a thing to be aware of as you're working with this. There are places where it makes a lot of sense to mix workload off with server authorization policies and route off with HTTP route authorization policies. I tend to think that it's better to maybe approach those things a little bit more separatedly, if that's a word. What we're gonna do in the demo is show a way where we're using restrictive authorization policies and then opening up a little bit and that ends up working pretty well. But if you're trying to do permissive workload-based authorization policies, that can be really confusing if you then try to mess with HTTP routes afterwards. Okay, we have talked about things getting rejected. The nature of rejection for LinkerD depends on what LinkerD believes the protocol is. GRPC will get a permission-denied GRPC status. HTTP otherwise will just get a 403. And if LinkerD doesn't know that it's one of these protocols, then it will just refuse the TCP connection. Also very important, if you change your policies and restrict traffic that was previously allowed, if there's ongoing traffic that used to be allowed and is now denied, LinkerD will summarily drop the connections. And it won't really do a lot with it because there's usually not a lot it can. It'll just drop the connection and off you go. Okay, another revisiting on sources of much trouble. Number one, pay attention to health probes. If you do not have authorization that allows health probes to work, Kubernetes will not allow your pods to become ready. In LinkerD 2.12, as long as you have not set up HTTP routes and you're using workload off, health probes are just gonna work. But as soon as you set up an HTTP route, you need to explicitly authorize probes to the server for which you set up an HTTP route. Number two, as we said before, default policies are static. They get set on startup. If you change the default, you must restart the pod. There's a single exception to this. You can use LinkerD Update to dynamically change the cluster-wide default because LinkerD Update will restart a bunch of things for you. And of course, all of the CRDs are read dynamically. So if you're using non-default permissions, you can change those on the fly as often as you want. Number three, if you have a server that tries to reference a port that is not in the pod's spec that the server matches, that port will get ignored. And this can easily result in your server being ignored as well. You'll be able to see some feedback about this, I believe, but it's a thing to be aware of. Okay, last chance to ask questions before we get into the demo and find out what breaks and what doesn't. Nothing's so far, so we can- It's so far, all right. Cross your fingers, we'll see what happens. All right. I am using a single-node K3D policy, K3D policy. I'm using a single-node K3D cluster named policy running on my laptop. As usual with LinkerD, it doesn't really matter what kind of cluster you're using for this. It's just, I'm using K3D because it's a convenient way to keep everything while it's a convenient way to not worry so much about my network freaking out or something like that. We have a bunch of stuff installed already. We've got BooksApp for our demo. We've got Emissaries and Ingress. We have, of course, LinkerD and LinkerD viz. I'm not gonna walk through in this particular thing. I'm not gonna walk through actually setting up the cluster. That would take a little bit too much time, but this is the way we did it. The LinkerD install is straight out of the quick start for 2.12. Note that when you are installing LinkerD 2.12, you must install the CRDs first and then the rest of LinkerD. And with 2.12, you must install Grafana separately before you set up LinkerD viz because of changes in some of the licensing around this stuff. BooksApp, again, straight out of the quick start for BooksApp, with the exception of that, I stole my colleague Jason Morgan's service profiles for BooksApp as well, just because it lets viz do some nicer stuff. We're not really gonna use the service profiles in particular for this demo, but they're really nice to have when you're trying to figure out if things are working. This is almost straight out of the emissary Ingress quick start. The only thing I've got here is... Oh, go ahead. Yeah, the support arm 64. LinkerD does indeed support arm 64. Yeah. Great, short and sweet answer. Yeah, it works. The only thing I'm doing differently in this one is I'm forcing emissary down to one replica because it runs more easily in K3D that way. And there's the configuration... The biggest reason I'm using emissary right now is that it permits me to use host names for talking to the various services rather than relying on kubectl port forward. And I don't like kubectl port forward, so yeah. Okay, so everything is set up. And we can start by taking a quick look at the Books app in the browser. We can reload the page and it works. We can go through and take a look at this author. PD James wrote Children of Men. There's, you know, this is the Books app that everybody has probably seen. It just lets you look at authors and books. It also lets you do things like we can edit this author. I don't actually know what PD James stands for, so I'll make him release department James or her. I don't actually, yeah, it's really good to look that up. So we can also come over here and see that LinkerDViz has good information about all this stuff. If anybody has seen a previous demo of the Books app, you will know that it doesn't actually work very well out of the box. We're not gonna worry about that right now. Okay, so I just looked at LinkerDViz in the browser. We can use LinkerDViz, of course, from the command line and you'll see pretty much the same info that we just saw in the browser. We can also use LinkerDViz top rather than VizStat to show the most common calls going into the Books app. And yeah, so there's traffic happening and it seems to be working fine. All right, now we will break everything. We will break everything by changing the Books app to default, to deny, to block all the traffic so nothing will work. So if we look at LinkerDViz stat, this looks kind of suspiciously like it is still working. If we look at it in the browser, we can see that it is still working, which is not what we expected. Anybody have any guesses for why this is still working? We can take a minute or so to see if anybody in the chat can have an idea here. Anybody? They're usually quite a bit of a delay in the answers, but we can see if someone pipes in. If nobody comes in, I'll see if Annie remembers the answer. Let's hope that someone chips in. There are a couple of places where we're going to do this one. And sorry, there are a couple of places where this presentation has questions like this. It's looking like the delay on the chat system might be long enough. Hey, there we go. Ugo got it right. Congratulations. Yeah, Ugo, you should, is there a way we can get contact information for Ugo? Ugo, if you're on the LinkerD Slack ping me, I'll get you a LinkerD hat because you got the right answer. Yeah, we changed the default policy and we didn't restart the pods, which was one of the things that we listed earlier as this is a gotcha that causes lots of trouble. So we're going to go through and restart everything in Bookzapp right now. And this is one of the frustrating bits because there's really no way to speed this up. And usually everything happens really, really fast, except this is the point that I forget or that I realized that I forgot to scale down the web app to one replica instead of three. Oh, well. It doesn't actually take that long. It just feels like it takes a long time. Yeah, when you're doing a demo, any, even like 10 seconds, ages. Yep. And this is going to take something like 90 seconds because of the way the deployment restart works. So, so again, now's a great time. If you have questions or feedback toss that into the chat. And, you know, if not, that's okay. Yeah, no worries. We have the two questions in queue for the end but other than that, no problem. Yep. Come on, come on, web app. Hey, there we go. All right, so we got that going. All right, at this point, things should not work. And if we reload the Bookzapp, we see it does not work. I'm not going to bother going into the JavaScript console to see, but it will be a, you know, permission error. You can also see that LinkerDViz now is no longer showing us the success rate for those things. That's because LinkerDViz itself doesn't get to talk to anything right now. So, we can start by allowing things. And we're like, we're going to start by allowing LinkerDViz and Prometheus so that we can get the dashboard working again. We're going to do this first. We're going to create a server. This is the one that we showed earlier in the slides where everything in the Bookzapp namespace that is on the LinkerDAdmin port. And we're going to go ahead and tell it, yeah, this is HTTP2. So that will define the server that LinkerDViz is talking to. And in this case, we're going to have it span all the workloads in that namespace. We will then define an authorization policy for that server using machine less authentication. Question, yeah, this will probably work while I'm going through and talking about the authorization policy. This authorization policy, I'll tell you in advance, is not going to reference the server we just created by name. So anybody who thinks that they know why we need the server, let me know. Here's the authorization policy. So we're going to target this one to the Bookzapp namespace. We're going to use the vizapps mesh TLS authentication, which we create down here. vizapps says, if you're using the Prometheus service account or the TAP service account, these are the two that viz and Prometheus use, then this will be allowed. An example, you remember I mentioned that this needs a very long fully qualified domain name that wouldn't fit on my slide. Yeah, there's an example. Pretty much everything after the word Prometheus is going to be the same all over the place. Actually, sorry, I got that wrong. This is Prometheus in the linkardviz namespace, the service account.identity.linkardviz.cluster.local is the part that's going to be the same all the time. Also worth noting, the mesh TLS authentication and the authorization policy live in the booksapp namespace, but we are explicitly allowing identities in the linkardviz namespace here, and that's fine. Allowing identities to make requests or cross namespaces is really important. And I'm not seeing anybody answer about why we need the server. The answer is this target reference saying, I want you to associate this auth policy with the whole booksapp namespace actually means with all of these servers and HTTP routes in the booksapp namespace. If there are no servers or HTTP routes in the booksapp namespace, this authorization policy won't do anything. Okay, so we're going to apply these. And at this point, we should now be able to see stuff. I should have done this earlier where we wouldn't have been able to see anything at all. Note that all of these are getting 403s. I've lost my mouse. There we go. So all of these are getting 403 responses because these are all HTTP requests that are being denied. And if we switch over to the browser, we can see that viz has gotten quite a bit happier where we get to see the success rates now. If I reload it, over time the traffic here will come back or sorry, the topology graph will come back if we wait a little while longer. I don't think I'm actually going to wait a little while longer though, so. Okay, we do still need to allow the application traffic, of course. And so we'll start with servers there again. With servers for authors and books and the web app, we're going to take a look at all of these. They're all pretty much the same. It's basically, we're going to create a server in this case named authors in the books app namespace. And we want all of the pods that have the project books app and app authors label on their service port. And this is using HTTP one. If we scroll on down, we see pretty much exactly the same thing for books and for the web app. Really nothing too profound about all of those. But in this case though, we are using pod selectors. We're not just saying every pod that has something that's listening on the service port. That would be a little too broad for this. And we're going to continue that with an authorization policy. In this case, this is going to allow any identity within the books app namespace. So this is basically saying, talking to again, any server or any HTTP route in the books app namespace. It'll be okay if you're using an identity that's also in the books app namespace. Oh, I should ask this question earlier. I think in the interest of having time for questions at the end, I'm going to just answer this question first. We don't have a server for the traffic generator because the traffic generator doesn't take any inbound traffic. All it's doing is producing stuff going outward. Nobody talks to it. So let's go ahead and apply these servers and apply our authorization policy. At this point, we should see actual traffic showing up and succeeding and all that. So far so good. And if we switch back over to the browser, I think we will see real things here. Yeah, so far so good. The topology graph doesn't actually show anything except what has spoken. So we had to reload a couple of times to get this books authors link. We can also see that we're back to getting real information here and all that. So, so far so good, right? Now, again, jump in with questions if anybody has this one. Yeah, we should actually try the books app from the browser. I meant to do that last time. If we reload this, that does not work. So at this point, we have application traffic within the books app namespace is working. Linkerdiviz is working, but we can't actually talk to it from a web browser. And the reason for this is that the web browser is not inside the books app namespace. The web browser on my desktop here is actually talking to emissary, which is in the emissary ingress namespace, the emissary namespace. Anyway, it's not in the books app namespace. So it cannot talk to anything inside the books app namespace. We have locked books app namespace down. So we need to go through and put in some stuff to allow the browser to talk all the way through to us. And this one we're gonna do with route-based policy because we don't really want the browser to just sling anything it wants to and have it make its way all the way into the books app. So the first thing we're gonna do here is we're gonna create an HTTP route that basically says that any traffic going to the server, could the web app server that matches the route path will be allowed. And then we do an authorization policy that's only for the ingress. Here we're binding this to that HTTP route. And we're saying this has to come from our ingress, has to come from emissary ingress in the emissary namespace. The only difference between this and the other authorization policies that you've already seen is that the other ones were bound to namespaces or servers. This one we're explicitly binding to an HTTP route so that we're doing route-based stuff rather than workload-based. If we apply this one, we are again missing something. The thing we're missing is that we just broke probes because we created an HTTP route going to the web app server. And that means that 2.12 will no longer allow health projects to the HTTP, the web app, excuse me. So we're gonna allow those with another route and another authorization policy. The web app, its health check is using the slash ping endpoint. So we're going to create a route that will allow gets to slash ping. We're not gonna use a MSTLS authentication here because the kubelet probes don't come from within linkerty, they come from the kubesystem namespace generally and that's not part of our mesh. So instead, we're creating a network authentication to allow traffic from any network whatsoever whether it's IPv4 or IPv6. And we will allow anything with that network authentication to our web app probe HTTP route. This is basically saying if you can get, if you have a way to get IP traffic to that particular ping endpoint, then we will allow it because health checks are important. We'll apply that too. Now we should see everything working in the browser. And look, we can, that's nice. Interesting thing here is as we click around in this, like if I click on PD James here, oh, you'll notice that this is back to PD and not police department, that's because we restarted the deployment of the books app, doesn't use persistent storage. But come up here, you'll notice this is to slash authors slash nine, which is not in fact, the root path, that's something else. So this is actually working a little bit too well. If we take another look at that HTTP route and we look at the path, we didn't actually specify how to do path matching. And it turns out that if you don't specify that a fault has a prefix match. Since every path has a prefix of root, we're actually allowing literally any HTTP request that's a get from the Ingress, which is probably not something we ought to do. So let's make that an exact match instead. We shall change that to have a type of exact, that's all we need to do. We don't need to change the authorization policy, we don't need to change the server, we just change the HTTP route. So let's go ahead and apply this one. And if we flip back to the browser there, that slash authors slash nine no longer works. If I come back to the root, that does work. Rikimaru kami does not work. Clicking on the cloud ag list does not work. So that's what we told it to do. That's a little too restrictive. So we can go through and loosen it up a little bit more by allowing the root path and we can allow it to grab style sheets and we can allow it to look at authors and we can allow it to look at books. Apply that one. Now let's go back again. So if we come back up here and click on an author, that works. If we click on the book, that works. Let's try editing this book. Yeah, and while we're editing, you have an audience question that comes up from two notes. Oh, actually two questions already. Is OPA supported for workload adaptation? Is this slash spire an alternative? So before I completely lose my train of thought, I'm gonna point out that if we look on the web browser, you can see that editing the title of the book there failed, which is what we expect, cause that's not a get. Now, OPA spiffy spire, the short answer there is not yet. Identity and linkerty has always been based on the service account. And we are pretty actively looking at how to go through and hook in some of these other things. But for right now, we basically rely on the service account to be the root of identity. And then we use empty LS and our own policy stuff on top of it. Those are very, very interesting use cases and we would be very interested in talking to people who have a particular need for OPA or are just interested in it or whatever. Ingress controller, I'm using emissary ingress because I'm very familiar with it. HTTP route and auth manifest, they work with the ingress's configuration. One of the interesting things about ingresses is that actually give me one moment and let me page back to a graphic in the slideshow. Okay, so if we look back at this, interesting thing about the ingress versus the mesh, the ingress only gets to affect traffic coming in from here. So basically the ingress can only make decisions for things that transit the ingress. The ingress cannot make any decisions about traffic between foo and bar, for example. It can't make any decisions about traffic between web and bar because it's simply not there. So one of the really useful things about the combination of an ingress controller and a service mesh is that the ingress gives you the ability to control things at the edge of your cluster in ways that your developers might find simple, but the service mesh gives you the ability to make decisions deeper in the call graph. So I wouldn't say that the stuff we're talking about here replaces the ingresses configurations and policies. They tend to work together, if that makes sense, hopefully. Let's see. And then there was another question, but we can take that again because we have about 10 minutes left. So if you have anything to run in the demo still, we should probably get that done with and then get to the question. Yeah, let's do that. Okay, so actually that is a fairly quick question about Linkerty and Gatekeeper. I don't really expect it to and that would be another great thing to bring up on the Slack. Okay, right. So we just went through and demonstrated that we can view everything. We demonstrated that editing doesn't work. If we come back in here, we're gonna go through and edit the authors and we're gonna do this slightly differently just by instead of changing our previous HTTP route, I'm just gonna add another one because you don't have to use only one HTTP route. Here, the major differences are we're using a regular expression match so that we can be a little bit more, a little bit fancier about what an edit looks like. We're also doing this with a post and we are going to explicitly allow that from the Ingress again, like we did with the last one. So if we apply that, we should be able to edit authors at this point. I don't actually remember what I was. All right, so let's back up a little bit. Okay, so if we wanna edit the author here at worked, if we go through and try to edit the book, then we will find that it does not work because we didn't do anything for posts on the books resource. So we've actually added quite a few different things here, right? We can use LinkerDVisAuthC, and I apologize for the wrapping here, but we can use LinkerDVisAuthC to take a look at all of the authorization policies and such that actually affect what's going on. So in this case, we're saying, show me all of the authorization policies that are affecting the web app deployment in the book's app namespace and we get to see the defaults, we get to see all of the stuff about probes, we can see our four different authorization things that are affecting various stuff going to the web app itself. This can be a very helpful thing for trying to understand what's going on when things don't go the way you expect them to. A very important point here is that you're not gonna see anything in this display that has not actually had an attempt to pass traffic through it. So if you're just trying to look before you try it, if you're trying to look at this before anybody has tried making requests, then you might see less than you expect. All right. Things we did not do that would be great to do on your own. This is why we have the repo. Obviously we didn't allow editing books as well. We just did the authors. Also, when we allowed the authors and book services to talk to each other and have the web app talk to the authors and book services, we just opened those up with workload-based policy. So at this particular moment, the web app can do anything at all to the books app or the authors app. And the books app and the authors app are just kind of trusting that the ingress is going to protect them. There's no need for that. You could go through and do route-based things as well in the mesh to protect those services further. But that, I believe, is it for the demo. Quick point that the buoyant, the creators of Blankety, every month do the service mesh academy where we do further deep dives into things like this. Those are workshops rather than just discussions. The one that we're doing on, I don't know why that says November 11-17. On November 17th, I believe it is. I will find out in just a moment. On November 17th, yes. November 17th, we will be doing a deep dive into LinkerD and init containers and CNI plugins and it'll be a delight. And of course, also worth noting that we also offer buoyant clouds to do fully managed LinkerD on any cluster. And yeah, that is all I have. So if there are any further questions, now would be a great time. Great. So we have those two backup questions, well, not backup, the ones that we queue with them if we wanna go to them, while someone might be typing away too. Okay. What were our two questions there? Egress and Istio and Sillium. Let's talk about Egress first because it's simpler. LinkerD doesn't do a lot with Egress right now. It's another area of active discussion. We would be delighted to talk to people who have particular use cases or strong opinions about how it should work and what they think would be a really, you know, LinkerD-ish way to do Egress. It's an interesting problem. A lot of what LinkerD has focused on in the past is worrying about policy for traffic coming into a given workload. And a lot of what we're worrying about right now is worrying about traffic going out of a given workload. So Egress very much fits into that. And we are very interested in figuring out how to make that work well for people. Okay. Istio, Sillium, things like that. Full disclosure, I work for Boyant. Boyant makes LinkerD. I work for Boyant because I think LinkerD is a really good way to solve a bunch of these problems. Sillium is interesting to me mostly because mostly because I tend to believe pretty strongly that doing IP-based identity in a world like Kubernetes where you don't actually control the network, that worries me a lot. I know that the Sillium folks put a lot of effort into trying to make that safe. And I know some of the people that I survey lent and I think they're really sharp. So, yeah, it leaves me in this interesting place where I have enormous respect for their engineers and the fundamental concept that they're working with still kind of scares me when you think about zero trust. So it's an interesting situation to be in. Istio is a little bit more interesting mostly because, well, okay, so I'm gonna not talk much about Ambient Mesh, their new thing here because there's a lot of stuff that we still need to dig into there. Under the hood, Istio and LinkerD do actually a bunch of things in fairly similar ways when you start talking about identity. I just find that LinkerD tends to be way, way simpler operationally speaking than Istio. And so, especially when you're dealing with security, operational simplicity is a security feature and operational complexity is not. So I tend to opt towards the simplest thing that can get the work done as opposed to the most complex thing that might be able to do things down the road that I don't need right now. And yeah, if there's other follow-up on that, then happy to see it here or hit me up on Slack. Speaking of Slack, sorry, let me paste that as well. Here's the link to our Slack. If you have good ending notes, to take continued discussions there or in the Hub Native Lives Slack as well, obviously if anyone wants to. Which GitHub repo, any or can we paste the GitHub repo link there? Yeah, actually, now that I check it, the link has been only posted to the YouTube side, not to the LinkedIn side. So I'm gonna- All right, so let's just cheat then, shall we? Yeah, that works. And, okay, links again as well. And we are wrapping up soon. Yeah, perfect. Well, this is gonna be a good way for everyone to wrap the link. There we go with that. Yeah, that should be simple there. And yeah, Ugo Calado hit me up on the LinkedIn Slack. You answered the question, we should get you a LinkedIn hat. I hope we have some LinkedIn hats left. But yeah, ping me on Slack, we'll sort it out. The, oh, there we go, that got posted as well again. Thank you. What was the other thing I was gonna say? Right, the repo is up to date with the demo as I actually ran it. Questions, you can always open GitHub issues or GitHub discussions or ping me on Slack. And I will be adding some more examples of various ways that authorization policies can interact for better or for worse. Perfect, but thank you everyone so much. And I think that was a good wrap up for today. But as always, thank you everyone for joining the latest episode of Cloud Native Live. Thank you. It was great to have Flynn here talking about zero trust network policy with LinkedIn. We also really loved the interaction from the audience. Great questions and great answer as well. So I like it that it goes back and forth. And as always, we bring you the latest Cloud Native code every Wednesday. And in the coming weeks, we have more great sessions coming up. So stay tuned for those. So thanks for joining us today and see you next week. Thank you, appreciate it.