Accessing an S3 Bucket from Another AWS Account using Node.js

Amazon S3 (Simple Storage Service) is a highly scalable and reliable object storage service provided by Amazon Web Services (AWS). In a complex AWS environment, it's common to have multiple AWS accounts, and there may be a need to access an S3 bucket in one account from another account. Node.js, a popular JavaScript runtime, can be used to interact with AWS services, including S3. This blog post will guide you through the process of accessing an S3 bucket from another AWS account using Node.js, covering core concepts, typical usage scenarios, common practices, and best practices.

Table of Contents#

  1. Core Concepts
  2. Typical Usage Scenarios
  3. Common Practice
    • Prerequisites
    • Setting up Bucket Policy
    • Setting up IAM Role in the Destination Account
    • Assume the IAM Role in Node.js
    • Access the S3 Bucket
  4. Best Practices
  5. Conclusion
  6. FAQ
  7. References

Article#

Core Concepts#

  • AWS S3 Buckets: An S3 bucket is a container for objects stored in Amazon S3. Each bucket has a unique name globally and can store an unlimited number of objects.
  • AWS IAM (Identity and Access Management): IAM is a web service that helps you securely control access to AWS resources. You can use IAM to create and manage AWS users and groups, and use permissions to allow or deny their access to AWS resources.
  • Bucket Policy: A bucket policy is a JSON document that you can attach to an S3 bucket to control access to the bucket and its objects. It can be used to grant cross - account access to an S3 bucket.
  • IAM Role: An IAM role is an AWS identity with permissions policies that determine what the identity can and cannot do in AWS. You can assume an IAM role to access resources in another AWS account.

Typical Usage Scenarios#

  • Data Sharing: A data - owning account may want to share specific S3 buckets with other accounts for analytics, reporting, or development purposes.
  • Multi - Account Architecture: In a large organization, different AWS accounts may be used for different business units or environments. One account may need to access data stored in an S3 bucket in another account for integration or testing.

Common Practice#

Prerequisites#

  • You need to have two AWS accounts: the source account (from which you want to access the S3 bucket) and the destination account (where the S3 bucket is located).
  • Node.js installed on your local machine.
  • AWS SDK for JavaScript installed in your Node.js project. You can install it using npm install aws - sdk.

Setting up Bucket Policy#

In the destination account, you need to create a bucket policy that allows the source account to access the S3 bucket. Here is an example of a bucket policy:

{
    "Version": "2012 - 10 - 17",
    "Statement": [
        {
            "Sid": "AllowCrossAccountAccess",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::SOURCE_ACCOUNT_ID:root"
            },
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::YOUR_BUCKET_NAME",
                "arn:aws:s3:::YOUR_BUCKET_NAME/*"
            ]
        }
    ]
}

Replace SOURCE_ACCOUNT_ID with the ID of the source account and YOUR_BUCKET_NAME with the name of the S3 bucket.

Setting up IAM Role in the Destination Account#

Create an IAM role in the destination account that the source account can assume.

  1. Go to the IAM console in the destination account.
  2. Create a new role and select "Another AWS account" as the trusted entity type. Enter the source account ID.
  3. Attach a permissions policy that allows access to the S3 bucket. For example:
{
    "Version": "2012 - 10 - 17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::YOUR_BUCKET_NAME",
                "arn:aws:s3:::YOUR_BUCKET_NAME/*"
            ]
        }
    ]
}
  1. Note down the ARN (Amazon Resource Name) of the IAM role.

Assume the IAM Role in Node.js#

In your Node.js code, you can use the AWS SDK to assume the IAM role in the destination account. Here is an example:

const AWS = require('aws - sdk');
 
const sts = new AWS.STS();
const roleToAssume = {
    RoleArn: 'arn:aws:iam::DESTINATION_ACCOUNT_ID:role/YOUR_ROLE_NAME',
    RoleSessionName: 'Session1'
};
 
sts.assumeRole(roleToAssume, (err, data) => {
    if (err) {
        console.log(err, err.stack);
    } else {
        const s3 = new AWS.S3({
            accessKeyId: data.Credentials.AccessKeyId,
            secretAccessKey: data.Credentials.SecretAccessKey,
            sessionToken: data.Credentials.SessionToken
        });
        // Now you can use the s3 object to access the bucket
    }
});

Replace DESTINATION_ACCOUNT_ID with the ID of the destination account and YOUR_ROLE_NAME with the name of the IAM role.

Access the S3 Bucket#

Once you have assumed the role and created the S3 client, you can use it to access the S3 bucket. For example, to list objects in the bucket:

const params = {
    Bucket: 'YOUR_BUCKET_NAME'
};
 
s3.listObjectsV2(params, (err, data) => {
    if (err) {
        console.log(err, err.stack);
    } else {
        console.log(data.Contents);
    }
});

Best Practices#

  • Least Privilege Principle: Only grant the minimum permissions necessary for the source account to access the S3 bucket. For example, if the source account only needs to read objects, only grant s3:GetObject permission.
  • Use Temporary Credentials: When assuming an IAM role, use temporary credentials provided by the AWS Security Token Service (STS). Temporary credentials have a limited lifespan, reducing the risk of credential leakage.
  • Monitor and Audit: Use AWS CloudTrail to monitor and audit all access to the S3 bucket. This helps you detect and respond to any unauthorized access attempts.

Conclusion#

Accessing an S3 bucket from another AWS account using Node.js involves setting up a bucket policy, creating an IAM role, and assuming the role using the AWS SDK. By following the common practices and best practices outlined in this blog post, you can securely and efficiently access S3 buckets across different AWS accounts.

FAQ#

Q: Can I access an S3 bucket in another account without using an IAM role? A: While it's possible to use bucket policies alone to grant cross - account access, using an IAM role provides more flexibility and security. It allows you to manage access at a more granular level and use temporary credentials.

Q: How long do the temporary credentials obtained by assuming an IAM role last? A: The default maximum duration for temporary credentials is 1 hour, but you can configure it to be between 15 minutes and 12 hours.

Q: What if I get an "Access Denied" error when trying to access the S3 bucket? A: Check the bucket policy and IAM role permissions to ensure that the source account has the necessary permissions. Also, make sure that the IAM role has the correct trust relationship with the source account.

References#