 So my name is Jonathan Whitaker. I am a staff software engineer at Okta and on zero And I'm also a core maintainer of the open FGA project Today I'm going to be talking with you all about Federated identity and access management for Kubernetes with open FGA And we will use key cloak in this example as well to represent an identity provider as we demonstrate this federation So to kick things off, let's just start with some simple definitions. It's often overlooked. What is federation? So the web services federation spec defines federation as the allowance of security principal identities and attributes to be shared across trust boundaries According to established policies. So what does that really mean? We have this stack, we have infrastructure, we have applications You know, we have identity providers We have a lot of security context and it's spread across various applications and infrastructure in our ecosystem And in order to ask, you know, access control decisions and to answer, you know, certain policies We need to be able to share that context across these boundaries And we need to be able to do so so that we can evaluate these policies across these different contexts Now in industry today, we have focused a lot in the last 10 to 15 years on identity federation and directory services So some of the existing standards and protocols for the federation of identities specifically These include things like OpenID Connect, OAuth2, SAML2 and the web services federation spec I'm sure all of you are probably aware with some of these, you probably use them in your day to day job, right? Now, this is where we've largely been focused in the industry again over the last 10 to 15 years We've been focused on the identity management piece of the identity and access management pie And I would argue that as an industry, we have yet to cohesively stitch together the access management side of the identity access and access management puzzle So I'd like to see more development, you know, as a community and as an industry in this space Stitching these two things together more cohesively So I'm going to pose a question to the community, for all of us today What if identity and access management was actually identity and, you know, underscore the and part access management If only we could start to establish some standards or protocols Maybe, you know, APIs for enforcing access controls across trust boundaries, right? This federation that we're talking about I think that OpenFGA is a project which can really start to bridge this gap Between, you know, identity providers, applications, infrastructure and in general our whole stack Authorization and access controls are everywhere So if you're not familiar with OpenFGA, if you haven't heard about it before Kind of give a quick overview of what it is OpenFGA, FGA stands for Fine Grain Authorization And OpenFGA is a flexible and performant authorization engine built to solve fine grain authorization What do I mean by fine grain authorization? Well, historically speaking, lots of applications implement ad hoc and custom access control policies These are oftentimes implemented in code as database queries You know, custom logic embedded in applications across your whole platform You can't go to one person in your org and say how does access control work across your whole platform Because that's custom logic that only certain people know OpenFGA was built to solve this problem And it's inspired by a system called Zanzibar that Google described in a white paper called Google Zanzibar And in this paper they described how they solved authorization at massive scale for all of Google services Now you can imagine how profound that is because Google is a huge company with lots of infrastructure Lots of applications and those applications have their own unique authorization models Their own entities, their own access patterns So to build a system that's flexible enough to enforce authorization across the Google ecosystem It's a pretty profound statement That's why it's such a powerful model OpenFGA was built from inspiration from that It's currently a CNCF sandbox project and we actually just submitted for incubation I think last week So hopefully sometime this year we'll graduate from sandbox to incubation And continue our journey in the cloud native computing foundation ecosystem It's actively maintained today by Okta and Ozzero The project actually originally started in Ozzero Labs which is an R&D division of Ozzero And we have a growing community and various project integrations So if you haven't joined the community and you need to solve some complex authorization problems Please reach out, join the community and find ways to get involved As a developer using OpenFGA I can kind of break down your interaction with our platform with our service Into three primary categories As a developer you first start by defining an FGA authorization model The authorization model is a declarative policy that defines how authorization works in your application So for example you can say users can view folders and folders contain documents That is the policy statement in plain English And you can actually translate that to a declarative model in the FGA modeling language We actually even have projects that have popped up in the community where you can take plain English And actually derive an actual FGA model from plain English too So there's a lot of really cool integrations and features that the community is rallying on with OpenFGA The second thing you do after you've defined a model is you write or you import relationship data This is the data that governs access control decisions in your applications These might be relationships, for example maybe a user has a role Or maybe a user has been shared access to a document Depending on what kinds of model and policies your application defines That will govern what kinds of data you write into OpenFGA OpenFGA becomes an extension of your application databases specifically for permissioned data To optimize to answer those permission questions The third thing you do is then query OpenFGA You ask OpenFGA for an authorization decision And there's different kinds of queries that you can ask OpenFGA For example you can ask OpenFGA the very specific question Can this specific user perform this specific action on an individual object We call that check and it returns a permitted and denied decision We also have other kinds of queries that allow you to query authorization related information In the inverse form so you can say what resources or what objects can a user view for example And this returns kind of list based semantics So what documents can user look as view We provide these APIs and allow you to query these questions from different angles So let's focus in for a little bit on what an FGA model looks like And how OpenFGA in general kind of models permissions So FGA models are modeled as a graph And if you're familiar with graphs you know that graphs are composed of nodes And in FGA we call these types and relations which are analogous to edges in a graph So in this example we have two different kinds of nodes We have user nodes and we have document nodes or types And in particular we have user Lucas and document secret We can define relations which define relationships between related types In this example the user type can be related to document types through read relations And through delete relations Now I use a dotted line in this diagram here because these relations represent possible relations In this graph of relationships And when I use the term relation you can think about that as just a permission Read is a relation here but that would be the thing that you're enforcing your permission check on So there's a possibility that a user might be related to a document through a read relation Or through a delete relation Those don't become concrete in this graph of relationships This graph of permissions until you establish a relationship tuple And this establishes a concrete path in the graph or an edge in the graph And it's formally defined as a triplet where you have some source subject A relation and some destination object So for example if you were to write the tuple User Lucas can read document secret Then that establishes this concrete edge in this graph of relationships represented by the solid line here And that now becomes a permission in this graph based model We have other features of our modeling language too which allow you to go beyond just basic relationship based access control policies We have what are called conditional relationship tuples So these allow you to express complex policies involving geobased policies, IP addresses, IP ranges, temporal access Quota based policies In this example you can see that we've defined different kinds of entities in our FGA model That's an example of an FGA model here We have users and we have groups of users And a user can be assigned as a member of a group That's what these type restrictions in the brackets represent here There's two cases that are represented in this model You can assign a user to a group unconditionally No condition is involved in that But the other option is you can assign a user to a member of a group With a condition on a temporal grant for example So this is an example of a temporal access policy Where you can give a user access to a group Or assign them to a group for a window of time In this case if the current time stamp is less than or equal to some grant time The time at which you add the user to the group Plus some grant duration Then that user will be considered part of that group If you're evaluating that relationship In a way such that that expression is not met or fulfilled Then we will consider that relationship as not present in the graph essentially So with this mechanism you can express very complex policies And these expressions here that we've defined use Google's common expression language Which is an extremely powerful expression language Allowing you to express a lot of different kinds of conditional expressions Here's another example of an FGA model That we will kind of use throughout the rest of this presentation In this case we have users, we have role bindings, roles and resources This is kind of analogous to how you might implement role based access control With open FGA and this relational based model You have resources and you have actions that you can perform on a resource such as GET And anyone who is assigned to a particular role can get a specific resource And you can assign people that have a particular role binding can be assigned to that role And then you can assign individual users to a role binding So you can bind a user to a role through a role binding and then grant access to a resource through that role So let's take an example with Kubernetes role based access control Which many of you might be familiar with If we wanted to see if some user Lucas could perform the GET action or verb on resource pods We can actually use that model that I just showed you in the previous slide Here's how we can do that We can first say anyone who has assigned the GETR role can get resource pods And anyone who is part of the subjects that have the GETR's role binding Automatically has the GETR role And in this case user Lucas is assigned to that role binding So user Lucas has the GETR's role binding which gives them the GETR's role Which therefore allows them to get resource pods So by following the edges in this graph We can implement role based access control policies with this relational based model In this case you see user Lucas allowed is true because there was a path in this graph We can extend that So that was a very simple example But you can imagine how that can be extended more generally to Kubernetes based access control policies So here's an example of two Kubernetes resources, RBAC resources A cluster role and a cluster role binding And I've color coded this specifically so that you can kind of understand how this would map to this relational model In this case we have the cluster role called reconcile deployments allows GET list and watch verbs on deployments in the apps API group And it also allows the update verb for deployment status in the apps API group On the right hand side we have the cluster role binding called deployment users And user Lucas is bound to that reconcile deployments cluster role So in this graph based model you can see user Lucas is assigned that cluster role binding deployment users Anyone who's assigned to that cluster role binding can therefore is a reconciler of deployments And by being a reconciler of deployments having that cluster role You can list and watch and get and update these different resources in Kubernetes So using this relational model we can express very fine-grained access control Beyond just standard Kubernetes RBAC We could even add more features that are not implemented in Kubernetes access control policies today By leveraging and exploiting this graph based relational model On the identity side of things Let's pretend that you're using key cloak as your identity provider Now this can also apply to any other general identity provider Maybe you're using ping, maybe you're using octa, zero, whatever it might be You can manage users and groups from your identity provider side of the story So in this case there's been an awesome community contribution by Martin Busozzi called Key Cloak OpenFGA Event Publisher It's an extension for Key Cloak that listens to user groups, changes or events And it pushes relationship tuples into OpenFGA So the idea is when a user is added to a group we can write relationship tuples like this The one on the bottom is the primary one that would be written by Key Cloak today It's just a direct user-to-group membership User John is a member of the FGA group But you can imagine in the future too OpenFGA can go beyond that We can do nested groups and we can do hierarchies and complex relational structures Anyone who's a member of the FGA group is also a member of the engineering group And user John is a member of the FGA group So therefore user John is both a member of the FGA group and the engineering group And we can express this complex inheritance hierarchy by leveraging this relational model So in the future, and this is a call out to the community and to Key Cloakers out there Maybe Key Cloak could use OpenFGA to natively store group and user relationships And be able to get features such as these complex temporal policies, geobase policies And these nested group structures natively with that integration We don't have that today, but that would be really cool, really powerful So let's take a sample use case Let's look at Kubernetes access management We described earlier how we can map this model But let's describe maybe how we can improve upon what we have today So today developers can map OpenID connect group claims to roles in Kubernetes So the idea is you can authenticate against your Kubernetes cluster using OpenID connect And your OIDC provider can return a token that embeds the groups that you're a part of In that identity provider So in this case maybe you're part of the Kube admins group On the Kubernetes side of the house you can create a role binding Where you say anyone who's part of the Kube admins group of that OIDC provided claim They can read deployments in this case Now this works great, it's really powerful But it's static, right? If you have different kinds of policies that you want to enforce in your identity mappings For example, maybe you want to add temporal access Maybe you want to revoke users relationship to some group more dynamically We can do better than this because in this scenario the information is provided statically in the token And so you would have to force a re-authentication event or somehow revoke the token that's been previously crafted So I think we can do better than this as a community, long term With that in mind, what I'm going to be demoing is kind of a proof of concept with Kubernetes federated access And the idea here is we're going to use key cloak as the OpenID connect provider for Kubernetes authentication So we'll authenticate against our Kubernetes cluster using key cloak Key cloak will manage the identity based policies such as groups and group memberships that users have And then we'll have a Kubernetes controller which reconciles RBAC policies that you are applying to your Kubernetes cluster And it will synchronize those, this controller will synchronize those into OpenFGA in real time So I have a single centralized OpenFGA instance that has policy information and data being managed by two different parties Key cloak, Kubernetes in this case Kubernetes can then delegate authorization decisions to OpenFGA And those decisions will be influenced not only by the policies that are being governed by Kubernetes, the RBAC policies But also the policies that are being managed by the identity provider, the user and group policies And so the way we're going to do this is with a web hook, the web hook authorizer in Kubernetes It's very powerful, very extendable Here's an overview of what that architecture looks like, what I just described So over here on the Kubernetes side of the house we have our authorization web hook And that calls out to OpenFGA and uses our various APIs that I described earlier You can make authorization checks, you can look up resources that the user has So you can use that for resource lists or collections and filtering And then we also have this controller that watches for changes to policies in Kubernetes, our RBAC policies And when changes happen with our RBAC rules, we can write those into OpenFGA In addition to that, Kubernetes is using OpenID Connect authentication with our identity providers On the identity provider side of the house, this could be any IDP that supports OIDC For example, as well as a common standard for synchronizing information And there's a standard out there called skim, outbound skim, which would allow us to synchronize user and group-related information Maybe identity-based roles, and we could use that mechanism across any IDP that supports skim To push this information into OpenFGA So that's the high-level architecture Now let's go ahead and jump into the demo And we hope the demo gods bless us, right? So the first thing we'll do is we will bring up an instance of OpenFGA We're just going to use Docker in this example You can deploy OpenFGA as a service, we have a Helm chart You can deploy it as a sidecar model, and it's written in Go So if you want to integrate it into your Go app, you can actually integrate it natively as a library So there we go, we have an instance of OpenFGA up and running And I'm going to run a little command here, which uses our CLI, the FGA CLI We are going to create a store called kubedemo So what is a store? A store is a way for OpenFGA to scope relationship data So when you create a store, all of the relationship tuple data All the permission data that you're writing into OpenFGA will be scoped under that context So you can use this for managing different environments Maybe you have a store for a dev, staging in a prod environment Maybe you use a store to provide a tenant isolation mechanism There's a lot of varieties you can use for stores We'll go ahead and create that store And I have a little helpful command here that I'm just using To set our webhook authorizer config to use that store ID So you can kind of ignore that, but that's our store We go over here to postman, and we can look at the stores in our OpenFGA instance You can see that we have this new store, has this identifier, and its name is kubedemo We'll go ahead and use the read API to read these relationship tuples that exist in this service There are none yet We haven't added any users to any groups on the key cloak side of the house We haven't applied any RBAC policies to our Kubernetes cluster yet So we wouldn't expect anything at this time Let's go ahead and bootstrap key cloak So we'll bring up key cloak And the key cloak import job here is just bootstrapping some resources So we're creating a client application so that we can authenticate our Kubernetes CLI against the client app And then we're also creating some groups and users that we'll use in the demo So let's go ahead and switch over here to key cloak And we can log in with our just default credentials here It's going to warn me to change my password You can see that we have a kubed gatekeeper client application That's what we will authenticate our kubed CLI against And then we have a john.wittaker at octa.com user here That user is not part of any groups yet And we do have this FGA backend group So I'm a backend developer, maybe I want access to a specific namespace in Kubernetes, for example We'll go back over here and let's bring up our kub API server I missed it Let's see here There we go We'll bring up the kub API server, which is called API in this case The webhook authorizer, which is that open FGA controller and authorizer that Kubernetes is using And then etcd, which we need to run kub API server Okay, that's up and running That's great Down here in this terminal, and I should ask, can you guys see this okay? You're good? Awesome, thank you I'm going to bring up a terminal down here that just shows activity in our reconciler and our webhook authorizer Like I mentioned, we don't have any tuple data here yet So let's go ahead and let's apply an RBAC policy to our Kubernetes cluster Here's an example manifest for some RBAC resources We're going to create a namespace called FGA backend And in that namespace, we will create a role called deployment reader that will allow the get and list verbs on deployments And we'll create a role binding that gives the FGA, anyone who's a member of the FGA backend group The ability to read deployments in that FGA backend namespace So that's what our manifest looks like We will go ahead over here and we will apply that manifest And you can see we created those And you might have noticed a lot of activity in this bottom terminal That's our reconciler recognizing that there are changes to our back policies in Kubernetes And you can notice here that we see activity of writing those tuples to FGA So if we go back over to postman and we do a read, there's now a bunch of tuples in here The ones that are kind of most notable to point out is this tuple here It says that there is this K8 resource And it refers to deployments in this FGA backend namespace And anyone who's assigned the deployment reader role in that FGA backend namespace Can perform that list operation, the list verb I won't bore you but there's no other tuples in this set that you establish user-to-group relationships yet Because we haven't added a user-to-group in key Cloak yet So let's go back to the terminal And we're going to act like we're a user, john.wittaker at octa.com in our identity provider So we're going to try to get deployments in that FGA backend namespace with this user This is going to ask me to authenticate by following a redirect URL here So I'm just going to open that up in an incognito browser so we get a fresh session and everything And I'll log in with john.wittaker at octa.com That's my password, we've authenticated now against our Kubernetes cluster If we go back to our terminal, we can see that we got an unauthorized response from the Kube API server This user with this ID cannot list the deployments resource in the FGA backend namespace That was forbidden So let's go back into our Kubernetes administration console And we will go to users, go here, and we will add john to that FGA backend group If we go back to our CLI now and we run that same operation Notice we got a different response this time Now I haven't applied any deployment resources to the Kube API server So we don't get any resources back, but we don't get a forbidden response So this request has been authorized So we just added, you know, we just changed the policy if you will A user group mapping in our identity provider And we actually saw a policy enforcement change in our Kube API server Because it's all federated through this central authorization engine called OpenFGA, right? So we can go back, I'm going to remove this user from that group And you know, we can come here and we can show it's forbidden again I wanted to demonstrate something that we could do in the future If we have more native integrations in our CNCF ecosystem with OpenFGA I mentioned earlier how we can model temporal access policies, you know, geo-based policies and IP-based policies So I wanted to show what that could look like If, for example, KeyCloak allowed you to say that I want to add a user to a group But only for a certain window of time, right? Maybe only for 10 seconds or 30 seconds Maybe it's a support engineer that needs access to administer certain portions of your Kubernetes cluster There's a lot of scenarios you could imagine here This is the example that I wanted to just demonstrate So we have this model here, users can be related to groups And those users can be conditionally related to groups with this temporal grant Which is similar policy that I showed you all earlier That temporal grant says that if the current time is less than or equal to the time that I granted that access to that group Plus some grant duration, right? If that current time is less than that, then we will consider that user to be part of that group Otherwise we will not So I'm going to simulate what that might look like KeyCloak would be writing that information into OpenFGA Since KeyCloak doesn't have that support today I'm going to simulate that using the FGA CLI So I'm going to go back here and I'm going to grab this user's identifier And I'm just going to put it right there Copy and paste this And hopefully I get my time conversion right Speak up if you see something wrong So it is the 21st and we are plus one UTC So it's really 451, right? So 1651 here And we will grant this access for maybe let's say 70 seconds Right? So we wrote that tuple and if we go back here and we use this Notice I didn't change anything over in KeyCloak I removed that user from that group in KeyCloak If we go back here That user is not part of any group in KeyCloak But I'm simulating as though that user had been added in KeyCloak With a temporal policy Now that policy should expire at the top of the minute Plus 10 seconds So hopefully here in 10 seconds or so We should see that that access has been revoked We got an authorized response prior And now if I run that command one more time I get it forbidden response So we just enforce the temporal access based policy So that's my demo That's what I've got for you guys And I just want to pose the opportunity to you guys The community Our team is only so large And we need help integrating open FGA into your applications So that you can enforce these kinds of complex policies You can imagine if KeyCloak could have done that out of the box I would have had to simulate it That would have been really powerful and really cool So getting back to concluding thoughts I believe that federating identity and access policies Across systems is extremely plausible with open FGA In fact, open FGA was exactly built for this For the same reason Google built Zanzibar They wanted to be able to enforce access control policies Across every application in their whole company Cross application Cross infrastructure access management I believe that native integrations with open FGA Offer unique features such as temporal access policies And other policies that we mentioned earlier And I'd like to see the community adding more of this Native integration so that you can benefit from these things I learned in this whole process Which was a really fun learning opportunity That Kubernetes webhook authorization Is extremely powerful and extensible And it was quite easy to get that up and running pretty quickly And I think it provides a really powerful mechanism To extend it There's more work to be done on the open FGA authorizer Webhook authorizer for Kubernetes It doesn't have 100% fidelity with the existing Access control policies and models that exist in Kubernetes We need to continue extending that more But in theory, in the future it could And I just also want to say special thanks To some people from the community in particular Lucas Kaltstrom He helped on the Kubernetes side of the house He was huge and instrumental in helping do the mapping And enforcing the access control policies From the Kubernetes side And then Martin Bazzosi did the key cloak integration That you saw that secretised the user and group information So thank you very much for the hard work and help there And I'd love to see more contributions like this From you guys on whatever cool projects You were all working on Take the time for some questions If you have any Yeah, and thank you Hi The actual graph How does open FGA How does open FGA secure That skim provisioning object Or call and then how does FGA actually secure The data that's stored in the graph Yeah, so the question is How does open FGA basically enforce access Over who can write the data And how the data is enforced over the graph There's kind of two components to that So the data itself is stored in open FGA As a flat triplet just like I described And we actually apply an iterative graph traversal That's defined by the FGA model Over that normalized triplet structure So that's kind of how the mechanics work there There isn't necessarily any access controls Directly over the storage data You know, we store that Scoped by store ID in the database To answer your other question though What we had was we had multiple parties We had Kubernetes and we had key cloak Managing different resources In a centralized store, open FGA And so what we can do in the future I will say we don't have this yet But we plan on adding fine-grained access control To FGA ironically, FGA on FGA is what we call it So the idea is that you could have certain Service accounts or client applications That have the authority to write Relationship tuples for certain object types So key cloak could be the authority That has the rights to write group And user relationships And Kubernetes is the authority That has the right to write Those K8 resource types So we can enforce access controls Of the data that's being written Into the access control system To the appropriate authorities Does that make sense? No, that was an example Of an integration that we could provide We don't yet have open FGA itself Doesn't provide the skim That would be provided by Like an external party Maybe an IDP, something like that Yep, thank you Any other questions? Cool, well if you do You can all be around Feel free to stop by and ask questions Love to hear from you And as always check us out We're on openfga.dev And we have some other Community facing repositories We have a Helm chart So if you're in the Kubernetes ecosystem You can install us pretty quick Feel free to get involved And reach out on cncfslack The open FGA channel We appreciate it