【小ネタ】暗号化していない RDS DBの作成を拒否するポリシー

ストレージ暗号化が未設定な DB(RDS DBインスタンス、Auroraクラスター)の作成を拒否するポリシーを作成してみます。AWS環境の予防的ガードレールとして、AWS Organizations のサービスコントロールポリシー(SCP)等で活用できると思います。
2021.11.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

暗号化していない RDS DBの作成を拒否するポリシー

以下ポリシーを作成しました。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyCreatingNonEncryptedDBCluster",
      "Effect": "Deny",
      "Action": [
        "rds:CreateDBCluster"
      ],
      "Resource": "*",
      "Condition": {
        "Null": {
          "rds:StorageEncrypted": false
        },
        "Bool": {
          "rds:StorageEncrypted": false
        }
      }
    },
    {
      "Sid": "DenyCreatingNonEncryptedDBInstance",
      "Effect": "Deny",
      "Action": [
        "rds:CreateDBInstance"
      ],
      "Resource": "*",
      "Condition": {
        "Null": {
          "rds:DatabaseEngine": false,
          "rds:StorageEncrypted": false
        },
        "StringEquals": {
          "rds:DatabaseEngine": [
            "custom-oracle-ee",
            "mariadb",
            "mysql",
            "oracle-ee",
            "oracle-ee-cdb",
            "oracle-se2",
            "oracle-se2-cdb",
            "postgres",
            "sqlserver-ee",
            "sqlserver-se",
            "sqlserver-ex",
            "sqlserver-web"
          ]
        },
        "Bool": {
          "rds:StorageEncrypted": false
        }
      }
    }
  ]
}

各ステートメント(DenyCreatingNonEncryptedDBInstance, DenyCreatingNonEncryptedDBCluster) を順番に解説します。

ステートメント 1つめ( DenyCreatingNonEncryptedDBCluster )

"Sid": "DenyCreatingNonEncryptedDBCluster",
"Effect": "Deny",
"Action": [
  "rds:CreateDBCluster"
],
"Resource": "*",
"Condition": {
  (略)
}

Aurora DBクラスターの作成を制限しています。

Condition部分の説明は以下のとおりです。

img

  • ストレージ暗号化有無の条件キー (rds:StorageEncrypted) が存在すること
  • ストレージ暗号化有無の条件キー (rds:StorageEncrypted) の値が false であること

上記 2つが満たされたときにステートメントが適用、つまりDBクラスターの作成が拒否されます。

ステートメント 2つめ( DenyCreatingNonEncryptedDBInstance )

"Sid": "DenyCreatingNonEncryptedDBInstance",
"Effect": "Deny",
"Action": [
  "rds:CreateDBInstance"
],
"Resource": "*",
"Condition": {
  (略)
}

RDS DBインスタンスの作成を制限しています。

Condition部分の説明は以下のとおりです。

img

  • ストレージ暗号化有無の条件キー (rds:StorageEncrypted) が存在すること
  • データベースエンジンの条件キー (rds:DatabaseEngine) の値が Aurora系 以外 であること ※
  • ストレージ暗号化有無の条件キー (rds:StorageEncrypted) の値が false であること

上記 3つが満たされたときにステートメントが適用、つまりDBインスタンスの作成が拒否されます。

※ データベースエンジンの条件キー周りの判定について

  • Aurora系 以外 のDBエンジン名は CreateDBInstance APIリファレンスから拾っています
  • そもそもこの判定いるの? については補足で説明します

試してみる

AdministratorAccess + 上述ポリシー をアタッチしているIAMロール上で試行します。

適当に 暗号化なし Auroraクラスターを作成しようと試みます。

img

結果、以下のように作成が拒否されました。

img

暗号化あり Aurora クラスターは問題なく作成できました。

img

img

おわりに

暗号化していない RDS DBの作成を拒否するポリシーを作成してみました。 AWS環境の予防的ガードレールとして、AWS Organizations のサービスコントロールポリシー(SCP)等で活用できると思います。

参考

補足

ステートメントまとめちゃダメなの?

※ これは 2021/11/03時点で、公式ドキュメントには見つからなかったトピックです

ポリシー設計にあたって、はじめは以下のように 1ステートメントにまとめるポリシー を作っていました。 が、これは Auroraクラスター作成時に正しく動作しません

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyCreatingNonEncryptedDB",
      "Effect": "Deny",
      "Action": [
        "rds:CreateDBInstance",
        "rds:CreateDBCluster"
      ],
      "Resource": "*",
      "Condition": {
        "Null": {
          "rds:StorageEncrypted": false
        },
        "Bool": {
          "rds:StorageEncrypted": false
        }
      }
    }
  ]
}

マネコンから Auroraクラスター作成( CreateDBCluster ) を実行すると、 RDSは自動的にクラスターのプライマリインスタンスも作成 ( CreateDBInstance ) します。 この動作は CloudTrail からも確認できました。

img

しかし、この CreateDBInstance のリクエストのパラメータに StorageEncrypted=false が必ず付くようです

そのため前述したポリシーでは、暗号化有り StorageEncrypted=true でクラスターを作成したとしても、 後続の CreateDBInstance で拒否されてしまいます。

img

そのため CreateDBInstance の制限に DBエンジンのフィルタを追加して、明示的に Aurora以外とする必要があったのです。

※ 「 StorageEncrypted=false が付くのであれば Aurora クラスターのインスタンスはストレージ暗号化されてないのでは?」という 懸念が出てくると思いますが問題ないです。 Auroraエンジンの CreateDBInstance リクエストは StorageEncryptedパラメータを無視します。 クラスターの StorageEncryptedパラメータを継承します。

–storage-encrypted | –no-storage-encrypted (boolean)

A value that indicates whether the DB instance is encrypted. By default, it isn't encrypted.

Amazon Aurora

Not applicable. The encryption for DB instances is managed by the DB cluster.

aws rds create-db-instance help コマンドより