 So, thanks for having me here today. My name is Ash Narkar. I am a software engineer at Styra, and I'm one of the maintainers of the Open Policy Agent. And I care about developing secure software systems that can be very de-deployed, scaled, and managed. And we also have with us Madhu. Hey, folks. I'm Madhu Keswali. I've been part of Spiffy Inspire Open Source Project, almost since its inception. Today, I kind of like helped out Ash with this demo, so that's the reason I'm here. Thanks, Madhu. So the agenda for the talk is I'll quickly do an overview of the OPAP project, talk about its features, then Madhu is going to talk about propagating user identity through Jod S-Wits, and finally, we'll see a demo of how Spire and OPAP are going to work together for OIDC Federation. So let's get started. So just a quick intro of the OPAP community. The project started in 2016 at Styra, where I work, and the goal of the project has been to unify policy enforcement across the stack. OPAP has been used in production by many companies for cases like admission control, authorization, RBAC, payback, and so on. This is a CNCF project currently at the incubation level. Hopefully, we'll graduate soon. And it has more than 150 contributors on Git, a healthy Slack community of more than 3,000 members, more than 4,000 stars on Git. And it's integrated with more than 20 of the most popular open source projects out there, including Spire, Istio, Envoy, Kubernetes, and so on. So what is OPAP? OPAP, which is the open policy agent, is an open source general purpose policy engine. When you use OPAP, you are decoupling the policy decision making from the policy enforcement. So your services can now offload queries to OPAP for a policy decision. So the way this typically works is that imagine you have a service. And this can be any service at all. It can be a Kubernetes API server. It can be your own custom service Kafka, Envoy, whatever. Whenever your service gets a request, it's going to ask OPAP for a policy decision by executing a query. OPAP is then going to evaluate that query based on the policy and data it has access to and send a decision back to your service where it gets enforced. So you can see the decoupling happening here between the decision making and the enforcement. The policy query itself can be any JSON value. So you can give OPAP like the HTTP request method path, the user. If you're doing HTTP authorization, if you're doing admission control, you can give OPAP the entire pod manifest. So give it some kind of structured data. And OPAP returns a policy decision, which is, again, a JSON value back to you, your service for enforcement. Few of OPAP's features real quick. At the core of OPAP is a high-level decorative language called Rego, which allows you to write policy decisions that are more than a bullion, basically any JSON value, arrays, objects, and so on. OPAP is written in Go, and you can deploy it as a sidecar, host-level demon. It's designed to be as lightweight as possible. So all the policies and data needs for evaluation are stored in memory. It provides some management APIs, which allow you to fetch policy and data from remote services. It can upload decision logs to remote services and also its status. And finally, along with the core policy engine, OPAP provides a RIT set of tooling to build, test, and debug your policies. It provides a unit test framework, as well as integrations with IDEs like VS Code, IntelliJ, and a Rego Playground. So now, we'll transition to the demo part of the talk, which we'll talk about, in which we'll see how policy decisions are based on the user and service identity. And Madhu is going to do that demo for us live. But before we do that, I wanted to set up the demo for you. So what we have, we have ACME Healthcare, which provides its members a platform to view invoices. And this platform is composed of three services, the front-end service, which allows members to log in and see their invoices, an invoice service, which holds the actual invoices, and finally, we have a claims service, which holds the claims, which are part of the invoice. So the way the demo is going to work is that you're going to have a user. When the user logs in with the front-end service, the front-end service is going to authenticate the user via an IDP. The IDP returns are tokened back to the front-end service, which it then forwards to the invoice service. The invoice service then asks the claims service for the claims that will be part of those invoices. So the claims are basically like a simple object which contains the status of the claim, the provider, the procedure, and so on. And the invoice service will simply take that claims object and embed it in the invoice object, which looks simply like this and send it back to the front-end service, which will present it in a beautiful way for the user to consume. So this is how the flow of the demo is and how this demo is going to work. So next, the policy that we want to demo says that users with the role building manager can view claims in the invoices. Again, the policy, the OPPA policy that we will see in the demo says that users with the role building manager can view claims in these invoices. And so to demo this policy, we are going to have a couple of users. One is Alice and one is John, where Alice is a building manager and while John is an enrollee. And we will see later how this information is being decoded from the JotS widths later on in the stock. But again, so we have a couple of users to help us with our demo. And so what you're going to see is that when Alice logs in to the front-end service to see her invoices, when the invoice service asks the claim service for the invoices, the claim service will ask OPPA for a decision. And so the claim service is going to send OPPA all the Jot tokens and all the JotS widths that it needs to make this decision. OPPA is going to validate, verify, decode those tokens and based on the claims, it's going to make a decision on whether Alice should see her claims or not. And since Alice is a building manager, OPPA is going to allow this request to go through. And so Alice will be able to see her invoices with the claims in them. On the other hand, if John, who's an enrollee, tries to see the claims, OPPA is going to block this because John is an enrollee and therefore OPPA will deny the decision and what y'all will see is that although John can see the invoices, the claims will be empty. So now I'm going to hand it over to Madhu who's going to do a live demo real soon. And before that he's going to talk about propagating user identity through JotS widths. Madhu, take it over. Yeah, thanks Ash. So essentially what can interest me in this particular demo here is every time I talk to folks about identity, the first thing that comes to mind is user identity, right? So, but really, Spire is not about that. Spire is about service authentication, providing identities to services. Earlier today, Andrew Jessup mentioned about having a working group which deals about delegated authentication which talks about transitive identity. We're still trying to frame that. And I kind of see this as one of the use cases why we need that, why we need a delegated authentication or why we really need a transitive identity. Kind of like a more generic use case for this demo is you want to have like a cascaded or a chaining of your identities starting right from where the user authentication happened. Think of the front end here as an edge service that is running elsewhere, perhaps outside your infrastructure in this demo, this is going to be my laptop. And you're trying to authenticate the user using one of your IDPs, whether it's Ping or Octa or something like that. That also gives you a Jot token and you propagate this Jot token as part of your claim request that you're doing to your Spire. And you can think of right now, the only available claim that is supported with Inspire is the audience claim. So I'm using, so we are using the Jot Esprit to be part of that audience claim, make that request and propagate all of this through. Why we are doing that is because at the OPPA, so this is the application part, why do we need delegated authentication? So at the application, at the authorization server that OPPA is, you are able to integrate with the Jocs URI and not only validate all of those Jot Espits that are part of that chain, but also extract the actual claims of all of this chain that happened right from the user to the service one to service end. And at each individual level, you can possibly validate those from the issuer itself. So that's kind of the use case here. Let me share my screen here real quick. So in this demo, we have, this is kind of kind of the UI that is showing the actual deployment. So this is a Kubernetes setup. We have individual namespaces, Inspire is deployed as, Spire agents are deployed as daemon set, Spire is deployed as a stateful set. And along with Spire itself, we also have, if you look at this, pretty good one. We also have the container, the OADC provider, right? Like so the OADC discoverer is running alongside with the Spire server itself. And we have deployed both the backend service and which has the actual data that is consumed and the invoice service is kind of like the ingress service. If I may call that, which the front end is consuming, right? So here on this terminal here, I have Alice who is trying to log in to that application. And I have been open this for quite some time here. So we'll log in as Alice who has a particular profile. So as we see here, we have this billing manager is the actual, one of the properties, one of the claims within the JotaSpit that was provided by Okta. And that particular user is validated and this is the actual JotaSpit that was coming. So we are seeing that OPA is allowing this particular request. So we are able to see the claims information here. But if I log in as the other user, John here, we should not be able to see that. So this is John, he has a different particular role. And if we go to his particular dashboard and try to see the invoices, you see that the claims information, again, it's kind of like a overloaded term here, claims in the application, this is kind of like the insurance claims, not necessarily to do anything with the Jota claims, but the Jota token itself, you can see that OPA denied information. So this data, the claims insurance claims data is coming from the backend service and OPA is denying access to that particular user there. So if we actually take a look at this Jota token here, open this up and do, so you see that in the audience itself. So that was the information that is coming from the Jota SVID that was issued to the invoice service. And this particular information audience itself is kind of like the chaining that I was mentioning. So itself is the Jota that was issued by the identity provider, right? So here we have the information. So at the authorization OPA layer, wherein we are making authorization decision, we are validating both the Jota SVID and also which is part of the audience claim and also the actual Jota SVID of the service itself. And even though the service has allowed, we have a policy which ratifies both the service claim and also the user claim itself. So as you can see here, we have this embedded as a claim within that Jota SVID. And because we have the OIDC federation that is done between the OPA authorization server and the SPIR server, we are able to validate this. And also similarly, we can also write a policy, the Rego policy, which also can validate the octet Jota itself. And we have this particular policy here and we are verifying both the token and also the actual claims within the user itself and making a decision based on both. So yeah, that's the short demo there. Open to take any questions. Back to you, Ash. Great, thanks, Madhu. So we do have a question. So how granular can OPA control access? For example, in this demo, what if Billings Manager should be allowed to view certain claims and enroll you to view certain different claims? So Jigar, that's a great question. We can definitely do granular access with OPA. Like I said, you give it any kind of JSON value. Your policies can be as granular as you want to. And you can, like it can decode your tokens, like the Jota SVID or any other token that we give it. It can verify it using the Jocs URI. And then you can write pretty fine-grained policies with that. So it's totally possible to do that. One more question here by Najeeb. Can OPA perform the static analysis of YAML manifest? So yeah, so there is a separate project in the OPA namespace called Contest, which is for validation of Kubernetes manifests and other kinds of different files like Docker files. So yeah, check that project out and it can probably sort your use case. One more question by Dennis. We've created OPA policies for resources on the record level, definitely possible. Okay, thanks for validating that, Dennis. I appreciate it. Yeah, so again, thanks to you all for inviting us for this talk, for giving us the opportunity. If you have any questions, we'll be here. And thanks to Meran team and this entire SPIFI inspired team. Thank you so much.