Zum Inhalt springen

Recovering Locked S3 Buckets in AWS Organizations using AssumeRoot

📍 Scenario

Imagine you’re the one managing all AWS accounts under your organization. One day, a developer while trying to tighten security, applies a policy so restrictive that the he blocks out everyone including himself in the process. The policy? Something like the one below

{
  "Sid": "DenyAllExceptPipeline",
  "Effect": "Deny",
  "Principal": "*",
  "Action": "s3:*",
  "Resource": [
    "arn:aws:s3:::project-prod-1",
    "arn:aws:s3:::project-prod-1/*"
  ],
  "Condition": {
    "StringNotEquals": {
      "aws:PrincipalArn": "arn:aws:iam::150641481443:role/PipelineAccessS3"
    }
  }
}

The intent?
The developer wanted to allow only the pipeline to update or upload to the bucket. No manual changes allowed.

What Went Wrong?
Mistakes like these often happen in fast-paced environments with multiple contributors. In this case:

  • No administrator or even the developers own arn was included in the policy

  • IAM users, even with full admin permissions can’t access the bucket to update configurations

  • The pipeline can access the bucket, but you can’t invoke it to delete/fix the policy

In standalone accounts, someone with root credentials would have to log in and fix it.

But this account was created under your organization using secure defaults. That means there is no root login profile. And now, you’re locked out of the critical bucket, and IAM can’t help.

This is where AssumeRoot comes to the fore.

How will the journey look like?

Journey

Understanding Assume Root

Specifically designed for AWS Organizations, AssumeRoot provides a set of temporary credentials that help perform certain privileged tasks on a member account, such as removing a bucket policy.

While it may look similar to AssumeRole, but it’s different. AssumeRoot doesn’t rely on trust policies or IAM delegation and is much more limited in scope. It’s intended for specific and critical tasks.

Importantly, it isn’t a substitute for root access; instead, it supports a limited set of critical operations, such as:

Can We Use Custom Policies? The short answer is No. But there’s more to it, and the details are just a scroll ahead! Before we dive in, make sure your setup meets the prerequisites below. These are essential to ensure everything runs smoothly.

Prerequisites

  • AWS Organizations is enabled

  • You have access to the Management account

  • A misconfigured S3 bucket policy in the member account.

Testing What Doesn’t Work

Before we look at how AssumeRoot helps, let’s first explore what might seem like valid approaches but fall short.

Let’s looks at the key parameters required for making an AssumeRoot request:

  • Action: This is the operation to perform

  • Version: STS API version

  • TargetPrincipal: Account ID of the member account

  • TaskPolicyArn.arn: ARN of the policy

  • DurationSeconds: Session duration (up to 900 seconds)(Optional)

Now, let’s look at some of the attempts.

API Request via cURL

Can we hit the endpoint like a REST API using a custom policy?

curl "https://sts.amazonaws.com/?Version=2011-06-15&Action=AssumeRoot&TargetPrincipal=156041421443&TaskPolicyArn.arn=arn:aws:iam::aws:policy/root-task/MyPolicy"

What response do we get?

curl via cli

We get “Request is missing Authentication Token”. This indicates that the requests must be signed using AWS Signature Version 4 (SigV4).

Signed Request with Custom Policies

To sign the request, let’s use Postman

request-via-postman

Once request parameters are set, head over to authorization tab and set the Auth Type as AWS Signature.

Fill in the following details:

  1. AccessKey and SecretKey: Use credentials from an IAM user in the management account (Do not use root credentials).

  2. AWS Region: e.g., eu-north-1, ap-south-1

  3. Service Name: sts

Let’s test it now! What do we see in the request body?

Custom Policies Not Allowed

use-aws-managed-policy

We receive a response stating that only AWS Managed Policies are allowed! So let’s correct it by replacing the custom policy with an AWS Managed Policy

Let’s resent the call, and see what happens

Root Credentials Management not enabled

root-cred-mgmt

This time, we get error code 403 as Root credentials management feature wasn’t enabled. To fix it, let’s make some changes in the management account.

Navigate to Account settings under IAM. We’ll enable Root credentials management. And enable Privileged root actions in member accounts, as well. This will help us to take actions in the member account.

enable-root-cred-mgmt

Making a Signed AssumeRoot Request

After making the necessary changes, let’s send the request

received-creds

And it was successful !! We get a response that has the AccessKey, SecretKey and thenSessionToken.

🔑Using The Temporary Credentials

Next, we’ll set the AccessKey, SecretKey and the SessionToken in our AWS CLI.

We can temporarily set them via:

export AWS_ACCESS_KEY_ID=<Your access key>
export AWS_SECRET_ACCESS_KEY=<Your secret key>
export AWS_SESSION_TOKEN=<Your token>

To verify that we have successfully accessed the account, run

aws sts get-caller-identity

Deleting the Misconfigured Bucket Policy

Now that you’ve configured the temporary credentials in your terminal, let’s proceed to delete the misconfigured bucket policy.

Run the following command to delete the bucket policy:

aws s3api delete-bucket-policy --bucket project-prod-1

Done

And that’s it we’ve successfully assumed root and taken action.

References: AssumeRoot

Thank you
Aarush Luthra

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert