2025年11月19日に、AWS Identity and Access Management(IAM)は、AWS PrivateLink 経由でアクセスするリソースに対してリージョンベースのアクセス制御を適用できる新しいグローバル条件キー"aws:SourceVpcArn"の提供が開始されました。
似たような条件キー"aws:SourceVpc"がありましたが、"aws:SourceVpc"はVPC IDを指定するもので、"aws:SourceVpcArn"はARNで指定できるため、リージョンベースでアクセス制御が可能になりました。
ARNで指定できるようになったことで、ARN用の演算子"ArnEquals/ArnLike/ArnNotEquals"も利用できます。
今回の記事では、AWS IAMで新しく利用できるようになった条件キー"aws:SourceVpcArn"を利用してみた内容を紹介します。
条件キー"aws:SourceVpcArn"使ってみた
AWSのWhat’s Newで以下の発表がありました。
投稿日: 2025年11月19日
AWS Identity and Access Management (IAM) は、AWS PrivateLink 経由でアクセスするリソースに対してリージョンベースのアクセス制御を適用できる新しいグローバル条件キー aws:SourceVpcArn のサポートを開始しました。この条件キーは、VPC エンドポイントがアタッチされている VPC の ARN を返します。これにより、お客様はリクエストが特定の VPC を経由しているかどうかを確認し、同じリージョン内またはクロスリージョンのシナリオでリソースへのプライベートアクセスを制御できます。ポリシーで aws:SourceVpcArn を使用することで、リソースへのアクセスが特定のリージョンの VPC エンドポイントからのみに制限され、データレジデンシー要件の適用が容易になります。例えば、Amazon S3 バケットにポリシーをアタッチし、指定したリージョンの VPC エンドポイント経由のリクエストのみにアクセスを制限することができます。
aws:SourceVpcArn 条件キーは、すべての商用 AWS リージョンでご利用いただけます。サポートされている AWS のサービスの完全なリストと詳細については、「IAM ユーザーガイド」を参照してください。(AWS の最新情報より)
便利そうですが、例で出ているAmazon S3へのアクセス制御方法は複数ありますよね。
条件キー"aws:SourceVpcArn"を使ってみて、利用シーンを考えてみます。
ハンズオン
実際に使ってみたほうがわかりやすいので、2つのVPCを用意し、EC2インスタンスをそれぞれ配置してからS3バケットへのアクセス制御を試してみます。
[ 構成図掲載予定 ]
■前提
- VPCを2つ作成済み
- 各VPCにそれぞれEC2インスタンスを起動済み
- EC2インスタンスにawscliインストール済み
■ルート確認
Amazon S3のゲートウェイエンドポイントを作成し、サーバーを配置するサブネットのルートテーブルにルートを追加済みであることを確認しましょう。
■IAMポリシー作成
EC2からS3への操作を許可および拒否するポリシーを作成します。
IAMポリシーでは、
- 許可用VPCに配置されているサーバーからは参照および書き込みを許可し、
- 拒否用VPCに配置されているサーバーからは参照のみ許可
するように定義します。
以下のポリシーについて、<S3バケット名>と<VPC ID>を自身の環境に合わせ修正し、IAMポリシーを作成してください。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowReadFromAnywhere",
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetObjectTagging",
"s3:GetObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::<S3バケット名>",
"arn:aws:s3:::<S3バケット名>/*"
]
},
{
"Sid": "DenyWriteUnlessFromSpecificVpcArn",
"Effect": "Deny",
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload",
"s3:PutObjectTagging",
"s3:DeleteObjectTagging",
"s3:PutObjectVersionTagging",
"s3:DeleteObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::<S3バケット名>",
"arn:aws:s3:::<S3バケット名>/*"
],
"Condition": {
"ArnNotLike": {
"aws:SourceVpcArn": "arn:aws:ec2:ap-southeast-1:*:vpc/<VPC ID>"
}
}
},
{
"Sid": "AllowWriteOnlyFromSpecificVpcArn",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload",
"s3:PutObjectTagging",
"s3:DeleteObjectTagging",
"s3:PutObjectVersionTagging",
"s3:DeleteObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::<S3バケット名>",
"arn:aws:s3:::<S3バケット名>/*"
],
"Condition": {
"ArnLike": {
"aws:SourceVpcArn": "arn:aws:ec2:ap-southeast-1:*:vpc/<VPC ID>"
}
}
}
]
}
【例】
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowReadFromAnywhere",
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetObjectTagging",
"s3:GetObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::saito-test-s3bucket",
"arn:aws:s3:::saito-test-s3bucket/*"
]
},
{
"Sid": "DenyWriteUnlessFromSpecificVpcArn",
"Effect": "Deny",
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload",
"s3:PutObjectTagging",
"s3:DeleteObjectTagging",
"s3:PutObjectVersionTagging",
"s3:DeleteObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::saito-test-s3bucket",
"arn:aws:s3:::saito-test-s3bucket/*"
],
"Condition": {
"ArnNotLike": {
"aws:SourceVpcArn": "arn:aws:ec2:ap-southeast-1:*:vpc/vpc-0e583585f700dc21e"
}
}
},
{
"Sid": "AllowWriteOnlyFromSpecificVpcArn",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload",
"s3:PutObjectTagging",
"s3:DeleteObjectTagging",
"s3:PutObjectVersionTagging",
"s3:DeleteObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::saito-test-s3bucket",
"arn:aws:s3:::saito-test-s3bucket/*"
],
"Condition": {
"ArnLike": {
"aws:SourceVpcArn": "arn:aws:ec2:ap-southeast-1:*:vpc/vpc-0e583585f700dc21e"
}
}
}
]
}
作成が完了しましたら、それぞれのEC2インスタンスにアタッチされているIAMロールに作成したポリシーを追加してください。
■動作確認
1. 参照
想定では、許可用VPCに配置されているサーバーおよび拒否用VPCに配置されているサーバー両方ともS3バケットにあるファイルが確認できるはずです。
●許可用VPCに配置されているサーバー
aws s3 ls <S3バケット名>
【実施コマンド】
[ec2-user@ip-10-0-13-116 ~]$ aws s3 ls saito-test-s3bucket
2025-12-13 03:55:31 0 test.txt
●拒否用VPCに配置されているサーバー
aws s3 ls <S3バケット名>
【実施コマンド】
[ec2-user@ip-10-0-15-182 ~]$ aws s3 ls saito-test-s3bucket
2025-12-13 03:55:31 0 test.txt
2. 書き込み
想定では、許可用VPCに配置されているサーバーはS3バケットにファイルをアップロードでき、拒否用VPCに配置されているサーバーは拒否されるはずです。
●許可用VPCに配置されているサーバー
touch test-ec2-allow.txt
aws s3 cp test-ec2-allow.txt s3://<S3バケット名>
【実施コマンド】
[ec2-user@ip-10-0-13-116 ~]$ touch test-ec2-allow.txt
[ec2-user@ip-10-0-13-116 ~]$ ls
test-ec2-allow.txt
[ec2-user@ip-10-0-13-116 ~]$ aws s3 cp test-ec2-allow.txt s3://saito-test-s3bucket
upload: ./test-ec2-allow.txt to s3://saito-test-s3bucket/test-ec2-allow.txt
●拒否用VPCに配置されているサーバー
touch test-ec2-deny.txt
aws s3 cp test-ec2-deny.txt s3://<S3バケット名>
【実施コマンド】
[ec2-user@ip-10-0-15-182 ~]$ touch test-ec2-deny.txt
[ec2-user@ip-10-0-15-182 ~]$ ls
test-ec2-deny.txt
[ec2-user@ip-10-0-15-182 ~]$ aws s3 cp test-ec2-deny.txt s3://saito-test-s3bucket
upload failed: ./test-ec2-deny.txt to s3://saito-test-s3bucket/test-ec2-deny.txt An error occurred (AccessDenied) when calling the PutObject operation: User: arn:aws:sts::498133496915:assumed-role/saito-test-iamrole/i-04ec4ced2b5caf7ec is not authorized to perform: s3:PutObject on resource: "arn:aws:s3:::saito-test-s3bucket/test-ec2-deny.txt" with an explicit deny in an identity-based policy
■補足
今回追加された条件キーはAWS PrivateLink経由でアクセスするリソースに対してのみ制御できます。
AWS PrivateLink 経由でアクセスするリソースに対してリージョンベースのアクセス制御を適用できる
Amazon S3へのアクセス制御を今回追加された条件キーで実施する場合、インターネット経由ではなく、VPCエンドポイント経由でアクセスしなければいけません。
わたしは今回Amazon S3のゲートウェイエンドポイントを利用しました。
AWSにはReachability Analyzerという機能があり、リソース間のネットワーク到達可能性と経路を確認することができます。
許可用VPCに配置されているサーバーからS3にアップロードできない方は、通信経路を確認してみてください。
まとめ
今回"aws:SourceVpcArn"を触ってみて感じたのは、“厳しく制御する”方法がひとつ増えたアップデートだな、です。特に、VPCをARN(リージョン込み)で扱えるようになったことで、可読性が上がったように感じました。
参考リンク:AWS の最新情報
↓ほかの協栄情報メンバーのAWS IAMについての記事を公開しています。ぜひ参考にしてみてください。
■IAM DB認証のログエクスポートとメトリクスあれこれ(齊藤弘樹)
■IAMポリシーは最小限でいい:ABAC×セッションタグで劇的に減らすアクセス制御(齊藤弘樹)

