
I'm Sergio Garcia, security researcher at Beyond Trust. Before that, I was one of the founding engineers at Prowler. I'm based in Miami, but I'm originally from Spain. And I try to break things in AWS, so you don't have to. You can find me in Twitter, GitHub, or LinkedIn with my alias, Mr. Clausk. So this is the blog post that started it all. On July from last year, AWS announced a new type of long lived credentials called Amazon Bedrock API keys just to accelerate AI development and to uh have a niche authentication for Bedrock. But this was my reaction. Why? Because since AWS launched two decades ago, they were recommending and telling everyone to use short-term keys instead of long-term
keys. And now they go and they ship a brand new type of long lived credentials to interact with AI. And here is the agenda. We are going to uh cover how bedrock API keys work. We are going to decode the keys. We are going to cover some attack vectors, how to detect uh the usage of these keys and potential attacks and how to not get wrecked. So what are bedrock API keys? As I told you before, they were launched on July from last year as an alternative to AWS credentials to interact with Amazon Bedrock. There are three ways to use them as environment variables uh through the AWS CLI or the AWS SDK and you can also use
it as a bird token in the authentication header if you want to directly talk with Bedrock using HTTP requests and they come into flavors as short-term keys and long-term keys which are the riskier ones. And here's the fun part. After just two weeks of being launched, they were appearing in public GitHub repos. Um, so let's go ahead and generate these keys. Uh, as you may know now in Amazon Bedrock, if you use the service, you can find a new API key section. And if we generate first the short-term keys, you will get something like this. uh they are going to be always starting with bedrock API key followed by a B 64 encoded SIG before presign URL as you
may know CB4 is the cryptographic protocol used by AWS to authenticate every single request we will decode it later on so uh for short-term keys no identity is created they use the um your existing session and your permissions but they are only usable in betro they expire with the session up to 12 hours and this is the critical part the creation happens on the browser in the client side so that means that there is no a cloud trail event for the uh for these short-term API keys only when they are used that that we will see later this is a sample of the client side request where you can see how AWS is generating using your session um these
short-term keys And now let's go ahead and generate the launch API keys which are way more interesting. If we go ahead and click that generate button um we can see that AWS is telling us that it's going to create something in IM and attach um that manage policy called Amazon bedrock limited access. Keep that in mind limited. Um there you can find also the API key name and notice the expiration options. You can go from one day to never expires. Yeah, never expires is an option and I chose never expires for security. I mean for research purposes. Um so I went ahead and click generate and there we go. We just created an API key of an expiration date of 100 years.
Cool. Um you can see that the API key name is there and this is a little bit sim a little bit different from the short-term key because we are having a whole base 64 encoded string that we will decode later on. But here is the kicker. If we see here AWS just silently created an IM user without even asking and that was my reaction. I wasn't expecting that. So let's go ahead and click that link to see how that user looks like. This is what I called by the well by the way a phantom user. So the username is going to be um the prefix of the API key. And as you can see now we
have a new section for the IM users called API keys for Amazon Bedrock where we can have up to two long-term Bedrock API keys. And if we go to the permission stuff, we can see the policy that AWS was telling us about before limited. Again, keep that in mind. Um, but first, let's go to cloud trail. And we can see that cloud trail tells us the story. Here we have the fingerprint of all the three events that um, Bedrock did by their own. When we click on the generate button of the long-term API keys, we can see that IM created a an user. They attached um the user policy of Amazon Bedrock limited access and they created
the service specific credential which was the long-term API key. If we zoom into the uh create services specific credential event, we can see all the information relevant to that uh new long-term API key. the expiration date, um the credential alias and the ID of that new long-term API key as well as the phantom user where that new API key is going to be um uh there. So to recap a little bit of we of what we just saw u long-term keys they are they can be generated in the console in the CLI in the SDK and it's a B64 encoded string AWS silently creates an IM user under the hood with that pattern and in cloud
share we have the fingerprint which are those three events and the expiration they can go from one day to never if you see the diagram you can see that uh what happened is that Bedro handled that request um it created a new user with the policy and the long-term API key for in that uh new user. But don't worry, AWS attaches a limited policy by default to the IM user. Sounds safe, right? Let's check what it's actually inside. We can see here the JSON of the bedrock limited access policy and we can see uh get a star list star call with ver token which for your information the call with ver token is the action the only single
action that the API keys use to interact with AWS. So that is kind of expected but delay guard rails delete custom models by default. So basically we are having admin permissions by default for that new API keys. But wait there is more. If we scroll down the policy we find this describe keys for all the keys in your account. List all the rows in your accounts. Describe all the VPCs all the subnets all the security groups. So basically this uh limited access policy contains a reconnaissance toolkit um behind that. So my question for you is do you think this is a bedrock limited access? I don't think so. And here's the problem. So as I told you
before the API keys can only be used within the bedrock service. So AWS scope the keys with those API keys. We could um do all these actions in bedrock which are admin actions. But what happens in someone creates IM access keys for that user. That person could actually use all these reconnaissance permissions and AWS didn't scope the user for that specific use case. So again, AWS created an IM user preposition for exploitation. Every time that you create a long-term API key. So let's go ahead now and decode these API keys. Starting with short-term keys. Um as I told you before, they have this pattern and a B 64 encoded 64 presigned URL. If we decode this um present URL
encoded in B 64 uh we will find some relevant information like desperation the access key ID the region because bedrock API keys are regional and also if we decode the token which is encoded in B 64 we could get the account ID of that short-term key and with long-term keys it's way easier why because if we decode the B 64 encoded string we would get this same pattern which is the API key name which contains the phantom username. So with both um types of API keys the attacker could get the account ID whose infrastructure is attacking. Let's go ahead and show you a demo of everything that I talked you about to prove that this is real.
So here I have a new terminal with no credentials. I'm trying to do a list foundation models in my bedrock um environment. It didn't work. Then I'm exporting a long-term bedrock API key as an environment variable. And it did work. There we go. And then what I'm going to do is decoding this long-term API key. And we can see here that we have the phantom username that contains this API key and the account ID. Then what we are going to do since we have basically admin permissions in bedrock with this new API keys I'm going to create a guard rail here. I'm going to verify now if um that guardrail was created by getting the the ID. There you go. We
have it there. And since I have delete by default for everything, I'm trying to to delete here the guardrail. and it was successfully deleted. So there you go that we have almost admin permissions in bedrock. And here what I did is creating access keys for this phantom user to prove that I was actually able to um list all the roles and um using the rest of the reconnaissance permissions by using those access keys. All right. So now let's see the potential attack scenarios that can happen from these uh new bedrock API keys. I'm going to explain an attack chain that um it's the most common with the long-term API keys. So the step one as we saw the developer creates an API
key. Then AWS silently creates a phantom IM user with that uh limited access policy and the bedrock API key. And then we have two attack paths. The most common one if is that that API key is leaked in a public GitHub repo. So the attacker can use that key to hijack your bedrock environment uh by deleting guard rails by deleting custom models or doing LLM jacking attacks which are quite common nowadays and I will show you later an extended a more extended diagram about LLM jacking attacks. And then we have another second path which is if a if there is a compromised user in your account an attacker can use that user uh to create IM IM access keys in
that phantom IM user and without creating any new identities uh the attacker would be able to do reconnaissance in your account. And here's another problem. The phantom users always stay there. So here you can see a list of all the users that we have in our LAV account every time that we were generating long-term API keys in bedrock by testing it. And just to mention, none of these users have active bedrock API keys. So until you manually delete the users, the Phantom users are going to still be there. So the risk isn't just the key is a permanent attack surface that we are going to have with these phantom IM users. So um the biggest real world impact is
the LLM jacking attack because this is happening a lot nowadays. This basically when an attacker uses the victim's uh bedrock account to direct all the prompt and responses and um making the victim pays for pay for the bill of Amazon bedrock. In this case in bedrock um if the attacker maximize all the quotas in bedrock um they can build the the victim up to 14k dollars per day and per region. So that makes um the the attacker earns like um around 1 million per year of profit. And now let's see how to detect this. Um you can see here the C the cloud trail event that happened when I did the list foundation models using the bedrock API
key before in the demo. And this is the field that matters the most. Why? Every time that in your AWS account someone uses a bedrock API key either a long-term or short-term API key this call with ver token field is going to be true. So I would suggest that if you are not alerting on this field to start as soon as possible and this is a summary of what we are monitoring now in cloud trail first of all every time that a long-term API key is created that means monitoring the create service specific credential action plus um an expiration date because we are also monitoring if the that new long-term API key was created with an expiration date of of more than
90 days. Also, if a phantom user was created by monitoring the create user action and if the username starts with that prefix any key usage as I show you before in the previous slide, every time that that uh field is equals true, uh we are monitoring it to uh make sure that we are detecting every key usage. And the most critical one potential privilege escalation in the phantom users by monitoring the create access key action in the phantom users. Now um in order to prevent and defend this SCPs are your best friend. So if you're not using bedrock API keys yet or your company didn't approve the bedrock API keys yet, I suggest to deploy this
SCP to block every single key creation and new stage of the bedrock API keys. And um recently in September of of 2025, AWS releases uh new conditions for IM related to bedrock because security researchers like me raised concerns. The first one is the B token type where you can scope in the IM policies the type of the bedrock API key. In this case, I'm using it uh to deny and block every type of long-term API key usage. Then um you have here the another new condition that AWS released in September which is the service specific credential age where you can scope um to block API keys depending on their um expiration date. So for example in here we are blocking
every single creation of long-term API keys if their expiration date is more than 90 days. And the second one is the most critical one because we are blocking every single create access key um action in the phantom users for incident response. The fastest way to um to handle a long-term key that was compromised is to attach in that policy to the phantom user that contains um the leaked um long-term API key which basically denies every API key in bedrock um every bedro API key usage. But if you want, you can also as IM access keys to change the status of the API of the long-term API keys to inactive or just delete that leaked long-term API key.
For short-term uh for short-term API keys, it's a a little bit trickier because they can't be deleted. As I told you before, they are generated client side. So that means that it is along with the session. So the fastest way to um to handle um a leaked short-term API key is by attaching the same policy but this time to the identity that generated the short-term API key. And this is another option that I also like it a lot that is using the token issue time condition to revoke any past sessions including the session um that is along with that short-term API key. But please don't wait 12 hours uh for the short-term API key to expire.
And good news I open sourced everything. Um, here you can find the QR for the repo. With one single command in this repo, you are going to be able to scan and to find every single Phantom user in your account. That means that um if you have Phantom users that are orphaned, which means that they don't have active petro API keys, you can find them and as well you can automatically clean them up with this toolkit. Um with this toolkit you can also uh decode the keys that both type of keys the short-term and long-term keys and you can do incident response. This toolkit allows you um to do the the emergency key revocation which basically attaches those deny
policies that I showed you before. um it can get the cloud trail timeline for you from uh the leaked uh bedrock API keys and do forensic reports for that um phantom users. And also in that repo I included the four ready to deploy SCPs that I just showed you. So to finalize um some takeaways here, AWS creates phantom users silently without even asking for it. They are buried in cloud trail unless you monitor those type of phantom users. Limited is marketing. So keep that in mind that every time that someone in your organization uh creates and uses a bedrock API key, they are going to have um admin bedrock permissions or reconnaissance permissions by default
and the keys were leaked in two weeks. So make sure that you are um safely creating those keys and store them uh safely because there are attackers that are um making the victim pay up to 14K per day and earning around 1 million per year of revenue and the phantom users are always at at risk if you don't clean them up and manually delete them. um they are going to be there always um with potential credential leakage inside the threads and privilege escalation. These are some additional resources that I used for um both the research and the presentation and that was all. Thank you very much for attending. Um and here you have the QR. Thank you.
Any questions? Any thoughts? That's a great question. So, um these API keys can only be used in bedrock because um they are they are not seek before uh credential let's say but for example if you with those API keys if you create an agent you could actually um associate a role to that agent. So I haven't tried that but that that could be a a good point. Thank you. Um, so you mean if there are users that they don't appear in cloud trail? >> Yeah. Do the phantom users activities show up in cloud trail? >> Yeah. Yeah. Yeah. Um, so AWS silently creates those IM users, but the create IM user event, it's actually recorded in
in cloud trail, but Bedrock does it without even asking for it. And this only happens this creation when you generate the long-term API key in the console. Expect the behavior. Cool.