All right, welcome everyone. My name is Puria Izady. I'm a solution architect at AWS. With me is also my colleague Manuel Heinkel. We work with software vendors in Germany and today we want to look at how we can actually build secure generative AI applications. And one of the very first things that we see is there is actually no doubt about that we will need to use data to improve our overall GenAI applications. So good data in, good data out. So this is what we need to be really successful.
And one of the challenges that we have here is that the systems that we are working with are actually not deterministic. And I think one thing we all can rely on is that if you're already working with non-deterministic systems, one thing we don't want to have is to have also an authorization mechanism which is also non-deterministic. So what can we do here to actually avoid that? So we really need to think about how we can have fine-grained control over how we define our authorization rules.
And this is something that we can also scale out because we want to leverage as much data as possible and we want also to have certain complexity. But this shouldn't become a risk to us. So this shouldn't become a big challenge. And so we want to keep this in control. And for that we will look into what are like the basic architectures that we nowadays look at when we build our own GenAI applications and what are the moving parts that we want to secure. And then finally as these systems are growing and growing we have more and more interactions.
So thinking back one or two years we started with building for example retrieval augmented generation pipelines, bringing data into a semantic format and leveraging this during runtime. But now we are also starting to assign APIs to large language models and even start connecting so-called agents to collaborate with each other. And this increases the complexity. But there are also certain trends. So for example we see now MCP becoming more and more a standard.
And this is really something where we need to start to think about how we can leverage mechanisms which actually help us to reduce the complexity and not like having additional to-dos which might become a big problem in the future. So let's start simple. Let's look at what is a typical architecture that we have when we start building first. So we have on the right side in the box our GenAI application and then we have always a user interface thinking of natural language interfaces or for example also voice interfaces becoming now more and more popular.
Now in the middle is a core business logic. So this is like the door between our UX to the backend system where we typically have one or more large language models that we are leveraging. And then we also have data sources. So these data sources might be a vector storage but these can be also simple as an object storage where we just upload our PDFs or nowadays also videos or images or even a data warehouse. So the options are increasing. And this also increases actually the to-do set we have thinking of authorization.
So the orchestration layer goes to our data sources, fetches the data based on the current user request coming in and then serves this data back to our large language model. We combine this with the current request from the user and the data we fetched and then we can get the result from the LLM and then bring this to our user. So simple as that. Now let's go a little bit back and understand in terms of data, who owns the data, who uses the data and how are we actually using the data to customize and gen.ai experience. So the very first thing is that someone needs to build these models, right?
So we have foundation model provider, we actually invest the effort to gather a lot of training data, mostly describing like a global knowledge. So in most cases nothing which is like enterprise content or private knowledge. And then during this pre-training process create these large language models. So this is what we have here on your right side. Now as a big enterprise you also might think to integrate your own data during a fine-tuning process. And there are companies that are doing this.
But now thinking about security and how we can actually make sure that only those folks who should have access to certain pieces of information are also the only ones who are accessing it. Filtering information in fine-tuned models is actually very hard because then again we are in the field of probabilistic access management. So if we just hand over the decision over to the large language model. So even if the information is there and now we want to revert it, again this is a hard process. So here we see like for at scale permission management fine-tuning is nothing we can leverage here.
So we need to be careful. Or we can go further. So what else we have here is the data source section here. Now this gives us much more flexibility. Thinking of a vector storage. So with our vector database we have much more options. We can for example leverage metadata or we can create multiple indexes and then use these types of fine-grained differences to really look at who can access what. Now what's important is that you're actually aware of when to do these types of checks. So now let's take a look on where it really is useful to do these checks.
But quite obvious already at the user entrance. So we have systems in front. So it might be a API gateway where we want to make these types of checks. So leveraging the metadata coming in from the front end to already not only authenticate but also authorize if this user is allowed to access our downstream systems. Nothing new but it's important that we don't lose these best practices when building our GenAI applications. And the second part is also when we do the access to our data sources.
So again here we should know who is the user, to which user group is this user assigned to and use this information tailored for our data source to filter the documents and information the user is retrieving. What we shouldn't do is actually at this late point to verify if the data is flowing into the LLM. So we completely should avoid this. And another thing that comes on top here is also a topic called guardrails where we also filter for prompt injections, PII data. But this is something we won't focus on for today.
Now another thing comes into this picture when we think about also assigning APIs into our architecture. And this is where we talk about AI agents. So two things are peculiar about AI agents. The first one is that they are breaking down complex tasks into a set of steps. So we call this reasoning. And the second one is also that they have access to APIs. So they don't really have access to APIs. So what happens is we tell them hey this is our API spec and this is what is a typical input we're expecting in the output. And then they can simulate which information needs to be filled in.
And we are actually in the background mapping the information and doing the call. But nevertheless this is somehow automated process. So again here we need to make sure that we are taking care of for the current user context if the access to the API should be allowed or not. How can we actually bake this into our overall architecture? So we have our application. We have the user.
And when a user request comes in typically what we want to do is we want to leverage our identity provider to first authenticate the user but also get information back in terms of the user identity so that we can in our downstream systems leverage this to control the access rights. Now one of the very next steps is we hand over a token to our agentic layer or our AI layer. So here for example we're looking at a service which helps us to work with LLMs. Now one thing which we can use here is the token information that we get already from our front-end system. We should always keep it with us.
So with every call that we do infer the downstream systems, talking to LLMs, data sources, another LLM and more agents, we should always keep this information. Especially with a JWT if we look further we have everything we need. So we have a session ID, we know who exactly the user is and also for example to which groups a user belongs to. Now you might be asking yourself well that sounds promising but how can I actually turn this now into actionable items and this is exactly what Manuel will show you next. Thank you Puria.
All right so we now have this information when we call our agentic layer but what do we do with this? Let's say we want to access some kind of database, some kind of data source and want to leverage this information in order to authorize what they can or cannot do.
So we have a compute environment, could be containers, could be serverless, could be whatever you want to use and what we want to do is we will pass the session information so the JWT and also the context of the information and what we want to do to this layer here because our agent in this point and in this example wants to access some kind of data. The compute layer would then go ahead and access the information in the database but one step is missing here. So how do we authorize with this information that we have here?
One thing that we could do we could of course bake it into our containers in our lambda application in our serverless inference layer and use it there, build our own authorization service. If you were at the OSEN presentation this morning in the room below you would know that this is maybe not such a good idea because if you have lots of if-else statements, nested statements, this can get very messy and very complex very fast and also maybe downgrade your security posture overall. What is a good idea is you can externalize it into a policy decision point.
So what you would do is you would say okay this is the user they want to do this action on such a resource, send this information to the policy decision point as we see here and the policy decision point would go get back with you and say allowed or denied. And in our compute layer we would then enforce this decision so either if it's allowed get the data from the database or if it's not allowed return back to the agent and say not allowed to access these resources.
So this has several benefits so the compute layer is independent of the policy decision point layer so there are different teams that can manage the different solutions here and you can have it independent of the development lifecycle of your application. Also in the policy decision points you would define the policies that make up this decision in a human readable way in policies that we will also have a look at in some slides and it's also great for monitoring and for auditing the system so which requests did you send, what was the decision and how was it evaluated.
So let's have a look at some of the authorization technologies at play here and how you can actually build this. So a policy decision point, we at AWS have a service that you can use, there are multiple out there. Verified permission is such a policy decision points authorization as a service mechanism. You send your requests and your context to this and you will get a yes or no allow or forbid statement. Of course we also need policies within our policy decision points in order to define what you can or cannot access. There are different also languages out there.
We use CDER, an open source policy language. Also if you have been to the Austen presentation there are multiple out there. We will go into CDER and have a look at how such a policy looks like and how you can use it. And I also want to highlight the Austen working group so we are also part of this working group in order to standardize the mechanisms and the protocols, how policy decision points and policy enforcement points work and how they connect to each other and how the protocols look like. So let's have a look at some of those.
So verified permission, as I said, policy decision point, you send your request, your application basically asks, can I access this resource? Can this user do this action to this resource? And what you will get back is an allow or deny statement. So this enables you to have fine-grained access control within your application and to bake it in with an API call so to say. We need those policies so there is someone that administers the policies and that creates the policies and the verified permission or the policy decision points takes these policies in order to evaluate the outcome in the end.
We have the CDER policy language and on the time when we had a look at the environment and when we decided to create the CDER policy language we had a look at all the existing language that we had and we found that they have two buckets that they mainly fall into. So the one bucket are the dots in the top here. Those policy languages are very expressive so you can express arbitrary logic in there but this also comes with a trade-off because this also means that they are maybe less performant and also less analyzable in terms of what they do.
The second bucket you see here on the right side are policy languages which are very performant and also reasonable good to analyze but also come with a drawback of expressiveness and understandiveness of this policy language. And that's why we set out to create CDER, a policy language that balances those characteristics and allows for human readability. So if you see a policy you would understand it as well.
It allows for automated reasoning so we can use mathematics in order to prove the correctness of the systems and of the output that you get and also get a good performance because it's built for scale and for speed. You can also have a look at this paper here for CDER performance. We also have a landing zone at the end where you can have all of the links that we talked about in one page and where you can access those.
All right this is a CDER policy and how it's defined and I bet if you had a look at this policy and don't know anything about CDER you could still tell me what this policy does because it's designed to be understandable by humans. So let's dissect this and have a look at how this works. So first every policy has an effect so we either have a permit or a forbid statement. So policy and the deny statement or the forbid statement is always stronger than the permit statement. Then we have a scope so this is where we can define role-based access control mechanisms.
So in this case it says if the principal is in the group doctor so if it's a doctor they can read files but only if the resource is in the restricted folder. So this is what what we have here in the scope. And as a second part of the policy we have an optional conditions so this is where you can define ABAC policies so where you can say but this only applies when the principal is not locked out of their account and when the principal is also locked in using MFA. So the second part is optional but you can use it in order to really get creative with your policies.
And also here we have a CDER playground where you can define policies where you can test policies and have a look at how they work and how they evaluate in the end. I mentioned the off-line working group. There was a presentation by David and Alex this morning who dove deep into those. So we are also part of this working group that works on standardizing the protocols and the mechanisms how policy decision points policy enforcement points for example work and how they not how they work but how they interact with each other.
And we also provide a github repository and a blog post where you can have a look at making verified permissions the specification and how you can deploy a solution in order to make the access to verified permissions according to the off-send protocol as it's currently in place. So let's have a look at the conclusion of this talk and what we want to convey here. So generative AI and data go hand in hand together. So you can build great value for your applications for your users when you also include the data into your applications.
But this also means that you have to have correct access control in your environment and make it deterministic. As Purya said the last thing we want to do is probabilistic or non-deterministic access control. And this also comes if agents collaborate with each other. We want to make sure that only the right data has access to the right agents for the right users. So we need this deterministic access control and as we also saw access control everywhere.
So you can have access control in the beginning of your application when the request comes in where it's maybe more coarse-grained or mid-grained. And as the request travels through your application you can make it even more fine-grained with more context that you have in your application. With that we are at the end of the presentation. As I said we have prepared a landing zone for you so or landing page for you. You can scan the QR code here to get a link to the presentation to some links that we shared and also our contact information. And we would like to ask a small favor.
There's also a feedback survey. If you could click into this take five seconds and give us some feedback and how you like the session. This would help us tremendously to improve. Thank you so much and we're here for questions. Thank you. So you know the drill. If you have a question please raise your hand. Otherwise I actually have a question submitted online through our app. The question is basically how is it different from other existing policy languages? Is it better, faster, more compatible and so on? So this is on the policy slide that I showed.
So we try to strike the balance of making it performant, making it also human understandable as I showed on the slide. So striking this right balance and yeah making it performant and good to integrate within. Will it actually work outside of the AWS cloud? So Cedar is open source. You could deploy your own policy engine and use Cedar there and deploy it there as well. So verified permission is a managed service that you could use but you could also do it, run it on your own. That's also possible. Okay thank you very much and again thank you if there are no further questions. Thank you.
Thanks a lot.