Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions multi-account-multi-region-s3-access/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Enforce IAM to test cross-account cross-region access
export ENFORCE_IAM=1
export DEBUG=1

SHELL := /bin/bash

usage: ## Show this help
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'

install: ## Install dependencies
@which localstack || pip install localstack
@which awslocal || pip install awscli-local

run: ## Run the cross-account cross-region experiment of copying data from one S3 bucket to another
./run.sh

start: ## Start LocalStack
localstack start -d

stop: ## Stop LocalStack
@echo
localstack stop

ready: ## Wait for LocalStack to be ready
@echo Waiting on the LocalStack container...
@localstack wait -t 30 && echo Localstack is ready to use! || (echo Gave up waiting on LocalStack, exiting. && exit 1)

logs: ## Retrieve logs from LocalStack
@localstack logs > logs.txt

test-ci: ## Run CI test
make start install ready run; return_code=`echo $$?`;\
make logs; make stop; exit $$return_code;

.PHONY: usage install start run stop ready logs test-ci
48 changes: 48 additions & 0 deletions multi-account-multi-region-s3-access/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Localstack Demo: Access S3 resources from different account and different region

Simple demo script to showcase the accessing of S3 resources from a different AWS account using bucket policies and IAM users with specific IAM policies attached to their identities.
The script uses a couple of AWS profiles to achieve that:

* Admin user of account A with account ID `000000000001`.

* Admin user of account B with account ID `000000000002`.

* Account A user that creates the S3 bucket and subsequent resources inside the bucket.

* Account B user that copies the resources from account A user's S3 bucket `source` into a bucket `target` it owns.

## Prerequisites

* LocalStack
* Docker
* Python 3.6+ / Python Pip
* `make`

## Installing

To install the dependencies:

```shell
make install
```

## Starting LocalStack

Make sure that LocalStack is started:

```shell
LOCALSTACK_AUTH_TOKEN=... make start
```

## Running

Run the sample demo script:

```shell
make run
```

## License

This code is available under the Apache 2.0 license.

11 changes: 11 additions & 0 deletions multi-account-multi-region-s3-access/bucket/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import "fmt"

func helloworld() string {
return "Hello World!!"
}

func main() {
fmt.Println(helloworld())
}
10 changes: 10 additions & 0 deletions multi-account-multi-region-s3-access/bucket/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

import "testing"

func TestHelloWorld(t *testing.T) {
if helloworld() != "Hello World!!" {
t.Fatal("Test fail")
}
}

47 changes: 47 additions & 0 deletions multi-account-multi-region-s3-access/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash
set -euxo pipefail
export AWS_SECRET_ACCESS_KEY=test

# Create `ls-a` and `ls-b` IAM users using the root accounts of each user
AWS_ACCESS_KEY_ID=000000000001 awslocal iam create-user --user-name ls-a
AWS_ACCESS_KEY_ID=000000000002 awslocal iam create-user --user-name ls-b

# Create IAM policies for each of the IAM users using the root accounts of each user
AWS_ACCESS_KEY_ID=000000000001 awslocal iam create-policy --policy-name pa --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:*","Resource":"*"}]}'
AWS_ACCESS_KEY_ID=000000000002 awslocal iam create-policy --policy-name pb --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:*","Resource":"*"}]}'

# Attach the IAM policies to each IAM user using the root accounts of each user
AWS_ACCESS_KEY_ID=000000000001 awslocal iam attach-user-policy --user-name ls-a --policy-arn arn:aws:iam::000000000001:policy/pa
AWS_ACCESS_KEY_ID=000000000002 awslocal iam attach-user-policy --user-name ls-b --policy-arn arn:aws:iam::000000000002:policy/pb

# Create access keys for each user using the root accounts of each user
CREDENTIALS_A=$(AWS_ACCESS_KEY_ID=000000000001 awslocal iam create-access-key --user-name ls-a)
CREDENTIALS_B=$(AWS_ACCESS_KEY_ID=000000000002 awslocal iam create-access-key --user-name ls-b)

# Retrieve the access key id of each user
# In LocalStack, the secret access key is not strictly enforced
# But the access key id is
USER_ACCESS_KEY_ID_A=`jq -r .AccessKey.AccessKeyId <<< $CREDENTIALS_A`
USER_ACCESS_KEY_ID_B=`jq -r .AccessKey.AccessKeyId <<< $CREDENTIALS_B`

# Create `source` bucket in `ls-a` user's account
AWS_ACCESS_KEY_ID=$USER_ACCESS_KEY_ID_A awslocal s3 mb s3://source
AWS_ACCESS_KEY_ID=$USER_ACCESS_KEY_ID_A awslocal s3 sync ./bucket s3://source

# Attach a bucket policy so that user `ls-b` can access it
AWS_ACCESS_KEY_ID=$USER_ACCESS_KEY_ID_A awslocal s3api put-bucket-policy --bucket source --policy file://source_bucket_policy.json

# Attempt to access bucket `source` using `ls-a` user
AWS_ACCESS_KEY_ID=$USER_ACCESS_KEY_ID_B awslocal s3 ls s3://source
AWS_ACCESS_KEY_ID=$USER_ACCESS_KEY_ID_B awslocal s3api list-object-versions --bucket source --prefix main.go

# Sync buckets `source` and `target` using `ls-b` user
AWS_ACCESS_KEY_ID=$USER_ACCESS_KEY_ID_B awslocal s3 mb s3://target
AWS_ACCESS_KEY_ID=$USER_ACCESS_KEY_ID_B awslocal s3 sync s3://source s3://target
AWS_ACCESS_KEY_ID=$USER_ACCESS_KEY_ID_B awslocal s3api list-object-versions --bucket target --prefix main.go

# Fail the script if somehow user A can access the resources of bucket `target`
echo "Check if s3api list-object-versions commnands fails as expected"
if AWS_ACCESS_KEY_ID=$USER_ACCESS_KEY_ID_A awslocal s3api list-object-versions --bucket target --prefix main.go; then
exit 1
fi
21 changes: 21 additions & 0 deletions multi-account-multi-region-s3-access/source_bucket_policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*"
],
"Principal": { "AWS": "arn:aws:iam::000000000002:user/ls-b" },
"Resource": "arn:aws:s3:::source/*"
},
{
"Effect": "Allow",
"Action": [
"s3:List*"
],
"Principal": { "AWS": "arn:aws:iam::000000000002:user/ls-b" },
"Resource": "arn:aws:s3:::source"
}
]
}