S3周辺ポリシーの事例をAWSセキュリティモデルと比べたら、想像以上に『データ境界』だった

# はじめに

2021年11月11日に [Security JAWS【第23回】](https://s-jaws.doorkeeper.jp/events/127684)で「閉域要件におけるS3周辺ポリシーの組み合わせ方」を発表しました。  

発表当時は資料未公開でしたが、2022年8月にSpeaker Deckで資料を公開したため、発表内容の要約を本記事で紹介します。記事の後半では、AWS環境のセキュリティモデル『データ境界』を紹介し、当社のポリシー事例と比較します。

1年以上前の発表内容ではありますが、直近で関わっている閉域要件の案件でも本思想をベースにしているため、お役になれば幸いです。

## 資料

資料の全量は以下から参照可能です。

<script async class="speakerdeck-embed" data-id="bad94bfe9f464d4283ce1739b1831a8e" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

https://speakerdeck.com/mhrtech/bi-yu-yao-jian-niokerus3zhou-bian-porisifalsezu-mihe-wasefang

## 動画

YouTubeに発表当時の動画が掲載されています。当社の発表は1:37:40～です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/Q-dKRmVgpRA?start=5860" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

https://youtu.be/Q-dKRmVgpRA?t=5860

# 当社事例の要約

発表スライドの総枚数は88枚もあるため、ダイジェストとして3枚のスライドをピックアップします。

## ① まとめ

[![まとめ](https://files.speakerdeck.com/presentations/bad94bfe9f464d4283ce1739b1831a8e/slide_87.jpg)](https://speakerdeck.com/mhrtech/bi-yu-yao-jian-niokerus3zhou-bian-porisifalsezu-mihe-wasefang?slide=88)

本発表では、S3周りで気を付けたい点を3つ紹介しました。上記のデータ流出リスクについては、以下スライドをご覧ください。

## ② データ流出のリスク

[![データ流出のリスク](https://files.speakerdeck.com/presentations/bad94bfe9f464d4283ce1739b1831a8e/slide_14.jpg)](https://speakerdeck.com/mhrtech/bi-yu-yao-jian-niokerus3zhou-bian-porisifalsezu-mihe-wasefang?slide=15)

悪意を持った内部犯行により、VPCエンドポイントを経由して、社外へデータ流出するリスクがあります。[動画](#動画)では、アカウントC（社外）のクレデンシャルが運用者に持ち込まれるパターンを解説しています。

上記のデータ流出リスクをどのように対策するかは、以下でまとめています。

## ③ S3周辺ポリシーの組み合わせ方

[![S3周辺ポリシーの組み合わせ方](https://files.speakerdeck.com/presentations/bad94bfe9f464d4283ce1739b1831a8e/slide_84.jpg
)](https://speakerdeck.com/mhrtech/bi-yu-yao-jian-niokerus3zhou-bian-porisifalsezu-mihe-wasefang?slide=85)

データ流出のリスクについては、IAMのグローバル条件キーを組み合わせることで、対策可能な旨を示しました。具体的なポリシー例については、[本記事の後半](#ポリシーの比較)で紹介します。

# データ境界

[AWS Security Roadshow Japan 2021](https://aws.amazon.com/jp/about-aws/events/2021/securityroadshow/)のラストセッションで、以下講演がありました。  
[AWS 環境で重要データを保護するセキュリティモデル：データ境界 (DATA PERIMETER) を学ぶ](https://www.awssecevents.com/ja/ondemandtracks/tech_track_5/)

恥ずかしながら、私は以下ツイートのやりとりで本講演を知りました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">(私も昨日、松尾さんのセッション聞いていてそう思っていました)</p>&mdash; hkiriyam (@hkiriyam1) <a href="https://twitter.com/hkiriyam1/status/1458987743015411713?ref_src=twsrc%5Etfw">November 12, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

後日アーカイブを視聴したところ、確かに同様の考え方が紹介されており、驚きました。

以下では、上記講演のスライドを引用して、データ境界の概要を紹介します。

## 概要

[![データ境界の概要](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989026/833ed54e-e50e-ef38-2e44-830dbffe37fe.jpeg)](https://dxjsvn24c4x1f.cloudfront.net/OnDemandTracks/tech_track_5.pdf#page=14)
データ境界というガードレールの紹介が、本講演のメインテーマでした。上記のキーワードレベルでも、当社事例と近しい雰囲気を感じます。  

次に、データ境界を適用したいシナリオを確認してみます。

## データ境界を適用したいシナリオ

[![データ境界を適用したいシナリオ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989026/ff7c9f04-4ec5-d26c-ff7e-b6a6b3472f26.jpeg)](https://dxjsvn24c4x1f.cloudfront.net/OnDemandTracks/tech_track_5.pdf#page=15)
当社が[データ流出のリスク](#-データ流出のリスク)で紹介した内容と同じく、社外アカウントへの流出リスクを想定しています。

本リスクに対するデータ境界の設定観点は以下の通りです。

## データ境界の設定観点

[![データ境界の対策観点](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989026/954fefca-7c54-d37b-c3a1-58c080e6c432.jpeg)](https://dxjsvn24c4x1f.cloudfront.net/OnDemandTracks/tech_track_5.pdf#page=17)
列挙されている設定場所が、[S3周辺ポリシーの組み合わせ方](#-s3周辺ポリシーの組み合わせ方)で紹介した当社例と一致しています。図らずも当社ではデータ境界を取り入れていました。

上記スライドの後に、具体的なポリシーの設定内容も解説されているため、一部を以下で紹介します。

# ポリシーの比較

ここからは、以下3種のポリシー例を比較します。細かな差異はありますが、基本的な考え方は同じです。

- [IAMポリシー](#iamポリシー)
- [VPCエンドポイントポリシー](#vpcエンドポイントポリシー)
- [バケットポリシー](#バケットポリシー)

:::note warn
データ境界では、S3とSQSの例が紹介されていますが、当社例ではS3関連のポリシーのみを紹介しています。Action句やResource句など細かい差はありますが、比較する上であまり影響がないため、各例は講演スライドから転記しています。
:::

## IAMポリシー

IAMポリシーの具体例は以下です。

- データ境界のIAMポリシー例
[![リソース境界 on アイデンティティポリシー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989026/3be68293-3bbb-f6ff-dd71-b78eded62b73.jpeg)](https://dxjsvn24c4x1f.cloudfront.net/OnDemandTracks/tech_track_5.pdf#page=23)
- 当社のIAMポリシー例

```json
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": "arn:aws:s3:::bucket-*"
    },
    {
      "Effect": "Deny",
      "Action": "s3:*",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "s3:ResourceAccount": "{アカウントA-ID}"
        }
      }
    }
  ]
}
```

<details><summary>当社例の補足スライド</summary>

[![IAMポリシー例](https://files.speakerdeck.com/presentations/bad94bfe9f464d4283ce1739b1831a8e/slide_47.jpg)](https://speakerdeck.com/mhrtech/bi-yu-yao-jian-niokerus3zhou-bian-porisifalsezu-mihe-wasefang?slide=48)

</details>

SQSとS3のリソース差異により、ポリシー記載方法が異なっていますが、本質的には殆ど同じです。S3バケットではARNにアカウントIDを含まないため、当社例では"s3:ResourceAccount"を使用して、アクセス先のアカウントを制限しています。

:::note
[S3アクセスポイント](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/using-access-points.html)を使用する場合は、ARNにアカウントIDを含むため、データ境界例と同様にResource句でアカウント制限が可能です。アクセスポイント利用時のIAMポリシー例は、以下をご参照ください。  
[VPC に制限された S3 アクセスポイントを使用して、別のアカウントのバケットにアクセスする方法を教えてください。](https://repost.aws/ja/knowledge-center/s3-access-bucket-restricted-to-vpc)
:::

## VPCエンドポイントポリシー

VPCエンドポイントポリシーの具体例は以下です。

- データ境界のVPCエンドポイントポリシー例  
[![アイデンティティ境界 on ネットワークポリシー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989026/03e4dcd7-bdae-a16c-c908-1a7568fe56c8.jpeg)](https://dxjsvn24c4x1f.cloudfront.net/OnDemandTracks/tech_track_5.pdf#page=19)
- 当社のVPCエンドポイントポリシー例  

```json
{
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": {
        "AWS": "*"
      },
      "Action": "*",
      "NotResource": "arn:aws:s3:::amazonlinux.{region}.amazonaws.com/*",
      "Condition": {
        "StringNotEquals": {
          "aws:PrincipalAccount": "{アカウントA-ID}"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "*",
      "Resource": "*"
    }
  ]
}
```

<details><summary>当社例の補足スライド</summary>

[![VPCエンドポイントポリシー例](https://files.speakerdeck.com/presentations/bad94bfe9f464d4283ce1739b1831a8e/slide_61.jpg)](https://speakerdeck.com/mhrtech/bi-yu-yao-jian-niokerus3zhou-bian-porisifalsezu-mihe-wasefang?slide=62)

</details>

- ポリシーの主な差異

|比較観点|データ境界例|当社例|
|---|---|---|
|アクセス元Identityの制限|"aws:PrincipalOrgID"で**組織単位**の制限|"aws:PrincipalAccount"で**アカウント単位**の制限|
|アクセス制限の例外|なし|NotResource句で**例外のS3バケット**を指定|

VPCエンドポイントポリシーもほぼ同じ方針です。当時、諸事情により[AWS Organizations](https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/orgs_introduction.html)を導入していなかったため、当社では"aws:PrincipalAccount"でアクセス元のアカウントを制限しています。

:::note
S3のVPCエンドポイントでは、自社アカウント外のAmazonLinuxリポジトリ（S3バケット）にアクセスしたいケースもあるため、NotResource句で例外指定しています。
:::

### VPCeでリソースレベルの制限

データ境界では、VPCエンドポイントでアクセス先リソースを制限する例として、以下も紹介されています。  
[![リソース境界 on ネットワークポリシー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989026/a5d68e20-f5bd-2d29-9d19-fa4226081882.jpeg)](https://dxjsvn24c4x1f.cloudfront.net/OnDemandTracks/tech_track_5.pdf#page=24)
上記では、Resource句でアカウントIDを指定することにより、アクセス先のアカウントを制限しています。一方、S3バケットではARNにアカウントIDを含まないため、Resource句のみでアクセス先のアカウントを制限することはできません。

バケット名をグローバルで一意にしなければならないS3において、Resoruce句のみで社外流出の対策をするには、ARNを完全一致で指定する必要があります[^1]。アクセス先のS3バケットが増減しない状況であれば、シンプルにResource句でARNをフル指定するパターンも良いと思います。

[^1]: Condition句なし、且つResource句でS3バケットのARNを完全一致で指定していない場合、社外アカウントへのデータ流出リスクがあります。詳細は、[発表スライド](#資料)の[p.34](https://speakerdeck.com/mhrtech/bi-yu-yao-jian-niokerus3zhou-bian-porisifalsezu-mihe-wasefang?slide=34)～[p.38](https://speakerdeck.com/mhrtech/bi-yu-yao-jian-niokerus3zhou-bian-porisifalsezu-mihe-wasefang?slide=38)をご参照ください。

:::note
IAMポリシー例と同様に、[S3アクセスポイント](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/using-access-points.html)を使用する場合はアカウント制限が可能です。アクセスポイント利用時のVPCエンドポイントポリシー例は以下をご参照ください。  
[Managing Amazon S3 access with VPC endpoints and S3 Access Points](https://aws.amazon.com/jp/blogs/storage/managing-amazon-s3-access-with-vpc-endpoints-and-s3-access-points/)
:::

## バケットポリシー

バケットポリシーの具体例は以下です。

- データ境界のバケットポリシー例  
[![ネットワーク境界 on リソースポリシー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989026/bd7e44fb-b564-fac8-9e53-c0c9b351072e.jpeg)](https://dxjsvn24c4x1f.cloudfront.net/OnDemandTracks/tech_track_5.pdf#page=22)
- 当社のバケットポリシー例

```json 
{
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::bucket-a",
        "arn:aws:s3:::bucket-a/*"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:sourceVpce": [
            "{S3VPCe(I/F型)のID}",
            "{S3VPCe(G/W型)のID}"
          ]
        },
        "StringNotLike": {
          "aws:userId": [
            "{ReadOnlyRoleID}:*",
            "{CFnRoleID}:*",
            "{S3ReplicationRoleID}:*"
          ]
        }
      }
    }
  ]
}
```

<details><summary>当社例の補足スライド</summary>

[![アクセス経路](https://files.speakerdeck.com/presentations/bad94bfe9f464d4283ce1739b1831a8e/slide_64.jpg)](https://speakerdeck.com/mhrtech/bi-yu-yao-jian-niokerus3zhou-bian-porisifalsezu-mihe-wasefang?slide=65)

</details>

- ポリシーの主な差異

|比較観点|データ境界例|当社例|
|---|---|---|
|アクセス元N/Wの制限|"aws:SourceVpc"で**VPC単位**の制限|"aws:sourceVpce"で**VPCエンドポイント単位**の制限|
|アクセス制限の例外[^2]|"aws:CalledVia"で**例外サービス**を指定|"aws:userId"で**例外のIAMロールID**を指定|

バケットポリシーについては、当社例の方が厳しく制限している印象です。当社例では、Condition句でVPCエンドポイントやIAMロールを指定することにより、**事前に承認・作成されたAWSリソースのみ**アクセスを許可しています。

データ境界例の方が、ロール変更などの影響を受けにくいため、保守・運用しやすいイメージがあります。細かな差異はありますが、基本の考え方はやはり同じだと感じました。

[^2]: ポリシーのCondition句では、"aws:CalledVia"と"aws:userId"がVPC関連のN/W制限キーと同列で定義されているため、例外という表現は不適切かもしれません。しかし、比較対象のデータ境界では「ネットワーク境界 on リソースポリシー」として本ポリシーが紹介されているため、ここでは"aws:CalledVia"と"aws:userId"をN/W制限の例外として位置づけました。

# おわりに

閉域要件におけるS3周辺ポリシーの当社設計事例を、AWSの『データ境界』と比較しました。細かな差異はありますが、基本的な考え方は同じでした。

AWSのポリシーは種類が多く複雑ですが、その分自由度も高いです。本記事がどなたかのお役に立てれば幸いです。

# 付録

当社事例には続きがあり、[Security JAWS【第25回】](https://s-jaws.doorkeeper.jp/events/137234)で発表しています。本発表でも「データ境界」に近い設計事例を紹介しているので、ご参考下さい。

<script async class="speakerdeck-embed" data-id="a1eb8261942a4016ba8d83a93b3881ad" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>

https://speakerdeck.com/mhrtech/bi-yu-yao-jian-niokeruec2falseakusesuzhi-yu-saasprivatelinkfalsemin-tonetwork-firewallfalsehuo-yong

<details><summary>Security JAWS【第25回】の動画</summary>
YouTubeに発表当時の動画が掲載されています。当社の発表は2:06:36～です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/QFIadED_R_o?start=7596" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

[Security-JAWS【第25回】 勉強会](https://youtu.be/QFIadED_R_o?t=7596)

</details>