I am using S3 VPC endpoint (type: gateway). I've wanted to restrict access to S3 resources from my private subnet only to my resources that belong to my account. I've used below IAM:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:PrincipalAccount": ["myAccountId"]
}
}
}
]
}
this works fine for S3, however it breaks the access to ECR from the node itself, so it no longer can pull the docker images.
This is what happens when I use docker pull
:
error pulling image configuration: error parsing HTTP 403 response body: invalid character '<' looking for beginning of value: "<Error>...Access Denied...</Error>"
This is the message from the Kubernetes node that tries to fetch the image:
Failed to pull image "<accountId>.dkr.ecr.eu-west-1.amazonaws.com/<repoName>:<tag>": failed to copy: httpReaderSeeker: failed open: unexpected status code https://<accountId>.dkr.ecr.eu-west-1.amazonaws.com/v2/<repoName/blobs/sha256:<hash>: 403 Forbidden
If I remove the principal account condition:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket"
],
"Resource": "*"
}
]
}
things are working OK.
It seem to me that ECR endpoint creates pre-signed URL to S3, which then gets blocked by my above policy.
Is there any way to allow ECR pre-signed URL, whilst still restricting access to only AWS resources that belong to my account?
CodePudding user response:
After displaying Docker daemon logs I've noticed that it tries to fetch the resource from: prod-eu-west1-starport-layer-bucket.s3.eu-west-1.amazonaws.com
.
I've then found AWS specific documentation which describes minimal permissions required: https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html#ecr-setting-up-s3-gateway
I've then added this block to my S3 VPC endpoint IAM:
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::prod-eu-west-1-starport-layer-bucket/*"
}
and things started to work fine.