Skip to content

Allowlist

Progress checklist

demo.sh allowlist rewrites package bucket policies from .lab-state.json. The public catalog UI bucket is not touched — it stays a public website.

Same shape on primary and replica; only the gateway ID list changes.

Who can read packages from the replica (…-pkgs-…-akl):

  1. Auckland S3 gateway VPCE (aws:SourceVpce): GetObject / ListBucket for the Akl probes
  2. SSO admin, CRR, publisher, rebuild Lambda: bypass principals
  3. Everyone else (internet, wrong Region gateway): denied on Get

The Sydney gateway is not on the replica allowlist.

Policy SIDs (package buckets):

  • AllowAdminAndRoles: full s3:* for admin + CRR + publisher + Lambda
  • AllowSSLRequestsOnly: deny non-TLS
  • DenyGetUnlessVpce: deny GetObject unless aws:SourceVpce matches (bypass ARNs exempt)
  • AllowVpceRead: allow GetObject / ListBucket via that VPCE

If a Region has no consumer yet, that package bucket only gets the bypass + TLS statements (no VPCE lock). Run up-consumer in both Regions first, then allowlist once.

Allowlist who can access package buckets Each package bucket allows SSO admin, CRR, publisher, and rebuild Lambda as bypass, plus GetObject/ListBucket through that Region gateway VPCE. Internet and unsigned callers are denied. The UI bucket stays public. allowlist: who may access package buckets Internet unsigned curl DENY pkgs primary (Sydney) …-pkgs-…-syd ALLOWED 1. Syd gateway VPCE Get/List via probes 2. Bypass roles admin / CRR / pub / λ 3. DenyGetUnlessVpce locks Get to listed VPCE pkgs replica (Auckland) …-pkgs-…-akl ALLOWED 1. Akl gateway VPCE Get/List via probes 2. Bypass roles admin / CRR / pub / λ 3. Syd gateway not on this allowlist Syd probes AL2023 + Ubuntu SSO admin both buckets CRR role both buckets Akl probes AL2023 + Ubuntu pkgs only — UI bucket stays PublicReadWebsite; replica SourceVpce = Akl gateway
  1. Apply policies from state (needs Syd and Akl gateway VPCE IDs):

    Terminal window
    export AWS_PROFILE=sandbox
    ./scripts/demo.sh allowlist
    allowlist applied to package buckets only (syd=["vpce-<id>"] akl=["vpce-<id>"]); UI bucket unchanged
Terminal window
PRIMARY="$(jq -r .primary_bucket .lab-state.json)"
REPLICA="$(jq -r .replica_bucket .lab-state.json)"
UI="$(jq -r .ui_bucket .lab-state.json)"
KEY=repos/_lab/allowlist-verify.txt
SYD_AL="$(jq -r .consumers.syd.al2023.instance_id .lab-state.json)"
Terminal window
echo "allowlist verify" | aws s3 cp - "s3://${PRIMARY}/${KEY}" --region ap-southeast-2
upload: - to s3://ps3p-pkgs-**ACCOUNT**-syd/repos/_lab/allowlist-verify.txt
Terminal window
aws s3api get-bucket-policy --bucket "$PRIMARY" --region ap-southeast-2 \
--query Policy --output text | jq '.Statement[] | {Sid, Effect}'
{ "Sid": "AllowAdminAndRoles", "Effect": "Allow" }
{ "Sid": "AllowSSLRequestsOnly", "Effect": "Deny" }
{ "Sid": "DenyGetUnlessVpce", "Effect": "Deny" }
{ "Sid": "AllowVpceRead", "Effect": "Allow" }
Terminal window
aws s3api get-bucket-policy --bucket "$PRIMARY" --region ap-southeast-2 \
--query Policy --output text \
| jq -r '.Statement[] | select(.Sid=="DenyGetUnlessVpce")
| .Condition.StringNotEquals["aws:SourceVpce"]'
vpce-<id>

(With a single gateway ID, IAM stores aws:SourceVpce as a string; multiple IDs would be an array.)

Terminal window
aws s3api get-bucket-policy --bucket "$REPLICA" --region ap-southeast-6 \
--query Policy --output text | jq '.Statement[] | {Sid, Effect}'
{ "Sid": "AllowAdminAndRoles", "Effect": "Allow" }
{ "Sid": "AllowSSLRequestsOnly", "Effect": "Deny" }
{ "Sid": "DenyGetUnlessVpce", "Effect": "Deny" }
{ "Sid": "AllowVpceRead", "Effect": "Allow" }
Terminal window
aws s3api get-bucket-policy --bucket "$REPLICA" --region ap-southeast-6 \
--query Policy --output text \
| jq -r '.Statement[] | select(.Sid=="DenyGetUnlessVpce")
| .Condition.StringNotEquals["aws:SourceVpce"]'
vpce-<id>
Terminal window
aws s3api get-bucket-policy --bucket "$UI" --region ap-southeast-2 \
--query Policy --output text | jq '.Statement[] | {Sid, Effect}'
{ "Sid": "PublicReadWebsite", "Effect": "Allow" }
Terminal window
curl -sS -o /dev/null -w "ui_index %{http_code}\n" \
"http://${UI}.s3-website-ap-southeast-2.amazonaws.com/"
ui_index 200
Terminal window
curl -sS -o /tmp/allowlist-curl.body -w 'http_code=%{http_code}\n' \
"https://${PRIMARY}.s3.ap-southeast-2.amazonaws.com/${KEY}"
head -c 160 /tmp/allowlist-curl.body; echo
http_code=403
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message>...
Terminal window
aws s3api head-object --bucket "$PRIMARY" --key "$KEY" \
--region ap-southeast-2 --no-sign-request
aws: [ERROR]: An error occurred (403) when calling the HeadObject operation: Forbidden
Terminal window
aws s3api head-object --bucket "$PRIMARY" --key "$KEY" \
--region ap-southeast-2 --query ContentLength --output text
17
Terminal window
CMD_ID=$(aws ssm send-command \
--instance-ids "$SYD_AL" \
--document-name AWS-RunShellScript \
--parameters "commands=[\"aws s3api head-object --bucket $PRIMARY --key $KEY --region ap-southeast-2 --query ContentLength --output text\"]" \
--region ap-southeast-2 \
--query 'Command.CommandId' --output text)
aws ssm get-command-invocation --command-id "$CMD_ID" --instance-id "$SYD_AL" \
--region ap-southeast-2 \
--query '{Status:Status,StdOut:StandardOutputContent}' --output json
{
"Status": "Success",
"StdOut": "17\n"
}

Publish