From be952f7162295d7086209e0d0a121f6da1488da6 Mon Sep 17 00:00:00 2001 From: mattisonchao Date: Thu, 13 Aug 2026 13:01:38 +0800 Subject: [PATCH 1/7] fix: grant AWS SQLWorkspace vendor permissions --- modules/aws/vendor-access/README.md | 2 +- .../permission_boundary_iam_policy.json.tpl | 69 ++++++++++++ .../files/provision_preserve.json.tpl | 101 +++++++++++++++++- modules/aws/vendor-access/main.tf | 11 +- 4 files changed, 176 insertions(+), 7 deletions(-) diff --git a/modules/aws/vendor-access/README.md b/modules/aws/vendor-access/README.md index 1220a33..7f42ebf 100644 --- a/modules/aws/vendor-access/README.md +++ b/modules/aws/vendor-access/README.md @@ -32,7 +32,7 @@ This module creates the following resources within your AWS account: - Authorized to fully manage StreamNative owned EKS cluster, worker nodes, and load balancers - `role/StreamNativeCloudBootstrapRole` & `policy/StreamNativeCloudBootstrapPolicy`: These IAM resources are used for provisioning, deprovisioning, and regular or emergency maintenance. This role and policy have the following characteristics: - - Have the ability to create, delete, manage, and read (within the limits of the permission boundary) EC2, EKS, IAM, DynamoDB, Route53, and KMS resources + - Have the ability to create, delete, manage, and read (within the limits of the permission boundary) EC2, EKS, IAM, DynamoDB, Route53, RDS, S3, and KMS resources - Cannot create or modify IAM policies (but are allowed to work with IAM policies specified by this module) - Can only work with resources that have specific tags associated or certain expected patterns in the resource's friendly name. diff --git a/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl b/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl index 6214666..304a0ce 100644 --- a/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl +++ b/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl @@ -19,6 +19,10 @@ "kms:*", "logs:*", "pricing:*", + "rds:DescribeDBInstances", + "rds:DescribeDBSnapshots", + "rds:DescribeDBSubnetGroups", + "rds:ListTagsForResource", "route53:*", "route53domains:*", "s3:*", @@ -35,6 +39,71 @@ ], "Resource": "*" }, + { + "Sid": "SQLWorkspaceRDSCreateInstance", + "Effect": "Allow", + "Action": "rds:CreateDBInstance", + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", + "arn:${partition}:rds:${region}:${account_id}:og:default*", + "arn:${partition}:rds:${region}:${account_id}:pg:default*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" + ], + "Condition": { + "StringEquals": { + "aws:RequestTag/Vendor": "StreamNative", + "rds:DatabaseEngine": "postgres" + }, + "Bool": { + "rds:PubliclyAccessible": "false", + "rds:StorageEncrypted": "true" + } + } + }, + { + "Sid": "SQLWorkspaceRDSCreateSubnetGroup", + "Effect": "Allow", + "Action": "rds:CreateDBSubnetGroup", + "Resource": "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*", + "Condition": { + "StringEquals": { + "aws:RequestTag/Vendor": "StreamNative" + } + } + }, + { + "Sid": "SQLWorkspaceRDSManage", + "Effect": "Allow", + "Action": [ + "rds:DeleteDBInstance", + "rds:DeleteDBSubnetGroup", + "rds:ModifyDBInstance", + "rds:ModifyDBSubnetGroup", + "rds:RemoveTagsFromResource" + ], + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" + ], + "Condition": { + "StringEquals": { + "aws:ResourceTag/Vendor": "StreamNative" + } + } + }, + { + "Sid": "SQLWorkspaceRDSFinalSnapshot", + "Effect": "Allow", + "Action": [ + "rds:AddTagsToResource", + "rds:CreateDBSnapshot" + ], + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", + "arn:${partition}:rds:${region}:${account_id}:snapshot:rw-*-sqlworkspace-*-final-*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" + ] + }, { "Sid": "IamRestrictions", "Effect": "Allow", diff --git a/modules/aws/vendor-access/files/provision_preserve.json.tpl b/modules/aws/vendor-access/files/provision_preserve.json.tpl index acc2f2a..a299aa3 100644 --- a/modules/aws/vendor-access/files/provision_preserve.json.tpl +++ b/modules/aws/vendor-access/files/provision_preserve.json.tpl @@ -35,6 +35,10 @@ "logs:List*", "route53:Get*", "route53:List*", + "rds:DescribeDBInstances", + "rds:DescribeDBSnapshots", + "rds:DescribeDBSubnetGroups", + "rds:ListTagsForResource", "s3:ListAllMyBuckets", "s3:ListBucket" ], @@ -97,6 +101,71 @@ ], "Resource": ["arn:aws:ssm:*:*:session/$${aws:username}-*"] }, + { + "Sid": "SQLWorkspaceRDSCreateInstance", + "Effect": "Allow", + "Action": "rds:CreateDBInstance", + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", + "arn:${partition}:rds:${region}:${account_id}:og:default*", + "arn:${partition}:rds:${region}:${account_id}:pg:default*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" + ], + "Condition": { + "StringEquals": { + "aws:RequestTag/Vendor": "StreamNative", + "rds:DatabaseEngine": "postgres" + }, + "Bool": { + "rds:PubliclyAccessible": "false", + "rds:StorageEncrypted": "true" + } + } + }, + { + "Sid": "SQLWorkspaceRDSCreateSubnetGroup", + "Effect": "Allow", + "Action": "rds:CreateDBSubnetGroup", + "Resource": "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*", + "Condition": { + "StringEquals": { + "aws:RequestTag/Vendor": "StreamNative" + } + } + }, + { + "Sid": "SQLWorkspaceRDSManage", + "Effect": "Allow", + "Action": [ + "rds:DeleteDBInstance", + "rds:DeleteDBSubnetGroup", + "rds:ModifyDBInstance", + "rds:ModifyDBSubnetGroup", + "rds:RemoveTagsFromResource" + ], + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" + ], + "Condition": { + "StringEquals": { + "aws:ResourceTag/Vendor": "StreamNative" + } + } + }, + { + "Sid": "SQLWorkspaceRDSFinalSnapshot", + "Effect": "Allow", + "Action": [ + "rds:AddTagsToResource", + "rds:CreateDBSnapshot" + ], + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", + "arn:${partition}:rds:${region}:${account_id}:snapshot:rw-*-sqlworkspace-*-final-*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" + ] + }, { "Sid": "ResS3", "Effect": "Allow", @@ -118,6 +187,36 @@ "arn:${partition}:s3:::${bucket_pattern}" ] }, + { + "Sid": "SQLWorkspaceS3Bucket", + "Effect": "Allow", + "Action": [ + "s3:CreateBucket", + "s3:DeleteBucket", + "s3:GetAccelerateConfiguration", + "s3:GetBucket*", + "s3:GetEncryptionConfiguration", + "s3:GetLifecycleConfiguration", + "s3:GetReplicationConfiguration", + "s3:ListBucket", + "s3:ListBucketVersions", + "s3:PutBucketAcl", + "s3:PutBucketPublicAccessBlock", + "s3:PutBucketTagging", + "s3:PutBucketVersioning", + "s3:PutEncryptionConfiguration" + ], + "Resource": "arn:${partition}:s3:::rw-*-${account_id}-${region}-*" + }, + { + "Sid": "SQLWorkspaceS3Objects", + "Effect": "Allow", + "Action": [ + "s3:DeleteObject", + "s3:DeleteObjectVersion" + ], + "Resource": "arn:${partition}:s3:::rw-*-${account_id}-${region}-*/*" + }, { "Sid": "SvcLnkRl", "Effect": "Allow", @@ -125,4 +224,4 @@ "Resource": "arn:${partition}:iam::${account_id}:role/aws-service-role/*" } ] -} \ No newline at end of file +} diff --git a/modules/aws/vendor-access/main.tf b/modules/aws/vendor-access/main.tf index 2e526fa..14fc169 100644 --- a/modules/aws/vendor-access/main.tf +++ b/modules/aws/vendor-access/main.tf @@ -199,10 +199,11 @@ resource "aws_iam_policy" "provision_preserve_policy" { path = "/StreamNative/" policy = templatefile("${path.module}/files/provision_preserve.json.tpl", { - account_id = local.account_id - bucket_pattern = var.s3_bucket_pattern - partition = local.aws_partition - r53_zone_arns = local.r53_zone_arns + account_id = local.account_id + bucket_pattern = var.s3_bucket_pattern + partition = local.aws_partition + r53_zone_arns = local.r53_zone_arns + region = var.region }) tags = local.tag_set } @@ -214,7 +215,7 @@ resource "aws_iam_policy" "provision_1_policy" { path = "/StreamNative/" policy = templatefile("${path.module}/files/provision1.json.tpl", { - vpc_ids = local.arn_like_vpcs_str + vpc_ids = local.arn_like_vpcs_str }) tags = local.tag_set } From 5a437fc3f872e6c711d707e7bd1ad715b0e88740 Mon Sep 17 00:00:00 2001 From: mattisonchao Date: Thu, 13 Aug 2026 13:24:03 +0800 Subject: [PATCH 2/7] fix: manage SQLWorkspace S3 lifecycle Co-authored-by: Codex --- .../files/permission_boundary_iam_policy.json.tpl | 1 - modules/aws/vendor-access/files/provision_preserve.json.tpl | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl b/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl index 304a0ce..df753d5 100644 --- a/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl +++ b/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl @@ -20,7 +20,6 @@ "logs:*", "pricing:*", "rds:DescribeDBInstances", - "rds:DescribeDBSnapshots", "rds:DescribeDBSubnetGroups", "rds:ListTagsForResource", "route53:*", diff --git a/modules/aws/vendor-access/files/provision_preserve.json.tpl b/modules/aws/vendor-access/files/provision_preserve.json.tpl index a299aa3..33f8bde 100644 --- a/modules/aws/vendor-access/files/provision_preserve.json.tpl +++ b/modules/aws/vendor-access/files/provision_preserve.json.tpl @@ -36,7 +36,6 @@ "route53:Get*", "route53:List*", "rds:DescribeDBInstances", - "rds:DescribeDBSnapshots", "rds:DescribeDBSubnetGroups", "rds:ListTagsForResource", "s3:ListAllMyBuckets", @@ -204,7 +203,8 @@ "s3:PutBucketPublicAccessBlock", "s3:PutBucketTagging", "s3:PutBucketVersioning", - "s3:PutEncryptionConfiguration" + "s3:PutEncryptionConfiguration", + "s3:PutLifecycleConfiguration" ], "Resource": "arn:${partition}:s3:::rw-*-${account_id}-${region}-*" }, From d3f8053a1c3b10b2013a74d858110aadfa8da881 Mon Sep 17 00:00:00 2001 From: mattisonchao Date: Thu, 13 Aug 2026 20:15:03 +0800 Subject: [PATCH 3/7] fix: scope SQLWorkspace vendor access to S3 --- modules/aws/vendor-access/README.md | 2 +- .../permission_boundary_iam_policy.json.tpl | 68 ---------------- .../files/provision_preserve.json.tpl | 81 +------------------ 3 files changed, 3 insertions(+), 148 deletions(-) diff --git a/modules/aws/vendor-access/README.md b/modules/aws/vendor-access/README.md index 7f42ebf..731a9c2 100644 --- a/modules/aws/vendor-access/README.md +++ b/modules/aws/vendor-access/README.md @@ -32,7 +32,7 @@ This module creates the following resources within your AWS account: - Authorized to fully manage StreamNative owned EKS cluster, worker nodes, and load balancers - `role/StreamNativeCloudBootstrapRole` & `policy/StreamNativeCloudBootstrapPolicy`: These IAM resources are used for provisioning, deprovisioning, and regular or emergency maintenance. This role and policy have the following characteristics: - - Have the ability to create, delete, manage, and read (within the limits of the permission boundary) EC2, EKS, IAM, DynamoDB, Route53, RDS, S3, and KMS resources + - Have the ability to create, delete, manage, and read (within the limits of the permission boundary) EC2, EKS, IAM, DynamoDB, Route53, S3, and KMS resources - Cannot create or modify IAM policies (but are allowed to work with IAM policies specified by this module) - Can only work with resources that have specific tags associated or certain expected patterns in the resource's friendly name. diff --git a/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl b/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl index df753d5..6214666 100644 --- a/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl +++ b/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl @@ -19,9 +19,6 @@ "kms:*", "logs:*", "pricing:*", - "rds:DescribeDBInstances", - "rds:DescribeDBSubnetGroups", - "rds:ListTagsForResource", "route53:*", "route53domains:*", "s3:*", @@ -38,71 +35,6 @@ ], "Resource": "*" }, - { - "Sid": "SQLWorkspaceRDSCreateInstance", - "Effect": "Allow", - "Action": "rds:CreateDBInstance", - "Resource": [ - "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", - "arn:${partition}:rds:${region}:${account_id}:og:default*", - "arn:${partition}:rds:${region}:${account_id}:pg:default*", - "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" - ], - "Condition": { - "StringEquals": { - "aws:RequestTag/Vendor": "StreamNative", - "rds:DatabaseEngine": "postgres" - }, - "Bool": { - "rds:PubliclyAccessible": "false", - "rds:StorageEncrypted": "true" - } - } - }, - { - "Sid": "SQLWorkspaceRDSCreateSubnetGroup", - "Effect": "Allow", - "Action": "rds:CreateDBSubnetGroup", - "Resource": "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*", - "Condition": { - "StringEquals": { - "aws:RequestTag/Vendor": "StreamNative" - } - } - }, - { - "Sid": "SQLWorkspaceRDSManage", - "Effect": "Allow", - "Action": [ - "rds:DeleteDBInstance", - "rds:DeleteDBSubnetGroup", - "rds:ModifyDBInstance", - "rds:ModifyDBSubnetGroup", - "rds:RemoveTagsFromResource" - ], - "Resource": [ - "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", - "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" - ], - "Condition": { - "StringEquals": { - "aws:ResourceTag/Vendor": "StreamNative" - } - } - }, - { - "Sid": "SQLWorkspaceRDSFinalSnapshot", - "Effect": "Allow", - "Action": [ - "rds:AddTagsToResource", - "rds:CreateDBSnapshot" - ], - "Resource": [ - "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", - "arn:${partition}:rds:${region}:${account_id}:snapshot:rw-*-sqlworkspace-*-final-*", - "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" - ] - }, { "Sid": "IamRestrictions", "Effect": "Allow", diff --git a/modules/aws/vendor-access/files/provision_preserve.json.tpl b/modules/aws/vendor-access/files/provision_preserve.json.tpl index 33f8bde..2ca7cc3 100644 --- a/modules/aws/vendor-access/files/provision_preserve.json.tpl +++ b/modules/aws/vendor-access/files/provision_preserve.json.tpl @@ -35,9 +35,6 @@ "logs:List*", "route53:Get*", "route53:List*", - "rds:DescribeDBInstances", - "rds:DescribeDBSubnetGroups", - "rds:ListTagsForResource", "s3:ListAllMyBuckets", "s3:ListBucket" ], @@ -100,71 +97,6 @@ ], "Resource": ["arn:aws:ssm:*:*:session/$${aws:username}-*"] }, - { - "Sid": "SQLWorkspaceRDSCreateInstance", - "Effect": "Allow", - "Action": "rds:CreateDBInstance", - "Resource": [ - "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", - "arn:${partition}:rds:${region}:${account_id}:og:default*", - "arn:${partition}:rds:${region}:${account_id}:pg:default*", - "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" - ], - "Condition": { - "StringEquals": { - "aws:RequestTag/Vendor": "StreamNative", - "rds:DatabaseEngine": "postgres" - }, - "Bool": { - "rds:PubliclyAccessible": "false", - "rds:StorageEncrypted": "true" - } - } - }, - { - "Sid": "SQLWorkspaceRDSCreateSubnetGroup", - "Effect": "Allow", - "Action": "rds:CreateDBSubnetGroup", - "Resource": "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*", - "Condition": { - "StringEquals": { - "aws:RequestTag/Vendor": "StreamNative" - } - } - }, - { - "Sid": "SQLWorkspaceRDSManage", - "Effect": "Allow", - "Action": [ - "rds:DeleteDBInstance", - "rds:DeleteDBSubnetGroup", - "rds:ModifyDBInstance", - "rds:ModifyDBSubnetGroup", - "rds:RemoveTagsFromResource" - ], - "Resource": [ - "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", - "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" - ], - "Condition": { - "StringEquals": { - "aws:ResourceTag/Vendor": "StreamNative" - } - } - }, - { - "Sid": "SQLWorkspaceRDSFinalSnapshot", - "Effect": "Allow", - "Action": [ - "rds:AddTagsToResource", - "rds:CreateDBSnapshot" - ], - "Resource": [ - "arn:${partition}:rds:${region}:${account_id}:db:rw-*-sqlworkspace-*", - "arn:${partition}:rds:${region}:${account_id}:snapshot:rw-*-sqlworkspace-*-final-*", - "arn:${partition}:rds:${region}:${account_id}:subgrp:rw-*-sqlworkspace-*" - ] - }, { "Sid": "ResS3", "Effect": "Allow", @@ -192,31 +124,22 @@ "Action": [ "s3:CreateBucket", "s3:DeleteBucket", + "s3:DeleteBucketPolicy", "s3:GetAccelerateConfiguration", "s3:GetBucket*", "s3:GetEncryptionConfiguration", "s3:GetLifecycleConfiguration", "s3:GetReplicationConfiguration", "s3:ListBucket", - "s3:ListBucketVersions", "s3:PutBucketAcl", + "s3:PutBucketPolicy", "s3:PutBucketPublicAccessBlock", "s3:PutBucketTagging", - "s3:PutBucketVersioning", "s3:PutEncryptionConfiguration", "s3:PutLifecycleConfiguration" ], "Resource": "arn:${partition}:s3:::rw-*-${account_id}-${region}-*" }, - { - "Sid": "SQLWorkspaceS3Objects", - "Effect": "Allow", - "Action": [ - "s3:DeleteObject", - "s3:DeleteObjectVersion" - ], - "Resource": "arn:${partition}:s3:::rw-*-${account_id}-${region}-*/*" - }, { "Sid": "SvcLnkRl", "Effect": "Allow", From 9e86aefdab101c51f8f7919683b31309021e75f4 Mon Sep 17 00:00:00 2001 From: mattisonchao Date: Fri, 14 Aug 2026 23:02:55 +0800 Subject: [PATCH 4/7] fix: grant RDS permissions for SQLWorkspace meta store The argo AWS v2 workflow provisions an RDS instance as the RisingWave meta store (sqlworkspace-rds-* resources tagged Vendor=StreamNative). Add scoped RDS create/manage/final-snapshot permissions to the StreamNativeCloudProvisionPreservePolicy and the permission boundary, mirroring the existing least-privilege SQLWorkspace S3 statements. --- .../permission_boundary_iam_policy.json.tpl | 69 +++++++++++++++++++ .../files/provision_preserve.json.tpl | 69 +++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl b/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl index 6214666..d12cf3a 100644 --- a/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl +++ b/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl @@ -19,6 +19,10 @@ "kms:*", "logs:*", "pricing:*", + "rds:DescribeDBInstances", + "rds:DescribeDBSnapshots", + "rds:DescribeDBSubnetGroups", + "rds:ListTagsForResource", "route53:*", "route53domains:*", "s3:*", @@ -35,6 +39,71 @@ ], "Resource": "*" }, + { + "Sid": "SQLWorkspaceRDSCreateInstance", + "Effect": "Allow", + "Action": "rds:CreateDBInstance", + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:sqlworkspace-rds-*", + "arn:${partition}:rds:${region}:${account_id}:og:default*", + "arn:${partition}:rds:${region}:${account_id}:pg:default*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:sqlworkspace-rds-*" + ], + "Condition": { + "StringEquals": { + "aws:RequestTag/Vendor": "StreamNative", + "rds:DatabaseEngine": "postgres" + }, + "Bool": { + "rds:PubliclyAccessible": "false", + "rds:StorageEncrypted": "true" + } + } + }, + { + "Sid": "SQLWorkspaceRDSCreateSubnetGroup", + "Effect": "Allow", + "Action": "rds:CreateDBSubnetGroup", + "Resource": "arn:${partition}:rds:${region}:${account_id}:subgrp:sqlworkspace-rds-*", + "Condition": { + "StringEquals": { + "aws:RequestTag/Vendor": "StreamNative" + } + } + }, + { + "Sid": "SQLWorkspaceRDSManage", + "Effect": "Allow", + "Action": [ + "rds:DeleteDBInstance", + "rds:DeleteDBSubnetGroup", + "rds:ModifyDBInstance", + "rds:ModifyDBSubnetGroup", + "rds:RemoveTagsFromResource" + ], + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:sqlworkspace-rds-*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:sqlworkspace-rds-*" + ], + "Condition": { + "StringEquals": { + "aws:ResourceTag/Vendor": "StreamNative" + } + } + }, + { + "Sid": "SQLWorkspaceRDSFinalSnapshot", + "Effect": "Allow", + "Action": [ + "rds:AddTagsToResource", + "rds:CreateDBSnapshot" + ], + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:sqlworkspace-rds-*", + "arn:${partition}:rds:${region}:${account_id}:snapshot:sqlworkspace-rds-*-final-*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:sqlworkspace-rds-*" + ] + }, { "Sid": "IamRestrictions", "Effect": "Allow", diff --git a/modules/aws/vendor-access/files/provision_preserve.json.tpl b/modules/aws/vendor-access/files/provision_preserve.json.tpl index 2ca7cc3..613dff0 100644 --- a/modules/aws/vendor-access/files/provision_preserve.json.tpl +++ b/modules/aws/vendor-access/files/provision_preserve.json.tpl @@ -33,6 +33,10 @@ "kms:ListResourceTags", "logs:Describe*", "logs:List*", + "rds:DescribeDBInstances", + "rds:DescribeDBSnapshots", + "rds:DescribeDBSubnetGroups", + "rds:ListTagsForResource", "route53:Get*", "route53:List*", "s3:ListAllMyBuckets", @@ -97,6 +101,71 @@ ], "Resource": ["arn:aws:ssm:*:*:session/$${aws:username}-*"] }, + { + "Sid": "SQLWorkspaceRDSCreateInstance", + "Effect": "Allow", + "Action": "rds:CreateDBInstance", + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:sqlworkspace-rds-*", + "arn:${partition}:rds:${region}:${account_id}:og:default*", + "arn:${partition}:rds:${region}:${account_id}:pg:default*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:sqlworkspace-rds-*" + ], + "Condition": { + "StringEquals": { + "aws:RequestTag/Vendor": "StreamNative", + "rds:DatabaseEngine": "postgres" + }, + "Bool": { + "rds:PubliclyAccessible": "false", + "rds:StorageEncrypted": "true" + } + } + }, + { + "Sid": "SQLWorkspaceRDSCreateSubnetGroup", + "Effect": "Allow", + "Action": "rds:CreateDBSubnetGroup", + "Resource": "arn:${partition}:rds:${region}:${account_id}:subgrp:sqlworkspace-rds-*", + "Condition": { + "StringEquals": { + "aws:RequestTag/Vendor": "StreamNative" + } + } + }, + { + "Sid": "SQLWorkspaceRDSManage", + "Effect": "Allow", + "Action": [ + "rds:DeleteDBInstance", + "rds:DeleteDBSubnetGroup", + "rds:ModifyDBInstance", + "rds:ModifyDBSubnetGroup", + "rds:RemoveTagsFromResource" + ], + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:sqlworkspace-rds-*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:sqlworkspace-rds-*" + ], + "Condition": { + "StringEquals": { + "aws:ResourceTag/Vendor": "StreamNative" + } + } + }, + { + "Sid": "SQLWorkspaceRDSFinalSnapshot", + "Effect": "Allow", + "Action": [ + "rds:AddTagsToResource", + "rds:CreateDBSnapshot" + ], + "Resource": [ + "arn:${partition}:rds:${region}:${account_id}:db:sqlworkspace-rds-*", + "arn:${partition}:rds:${region}:${account_id}:snapshot:sqlworkspace-rds-*-final-*", + "arn:${partition}:rds:${region}:${account_id}:subgrp:sqlworkspace-rds-*" + ] + }, { "Sid": "ResS3", "Effect": "Allow", From 963b9c5bfb7622381a5857f88e06ddaece64c42a Mon Sep 17 00:00:00 2001 From: mattisonchao Date: Fri, 14 Aug 2026 23:32:19 +0800 Subject: [PATCH 5/7] fix: allow RDS Describe actions for SQLWorkspace meta store The upbound terraform provider queries engine versions and instance state while provisioning; broaden the RDS grant from specific Describe actions to rds:Describe* in the bootstrap policy and permission boundary. --- .../files/permission_boundary_iam_policy.json.tpl | 4 +--- modules/aws/vendor-access/files/provision_preserve.json.tpl | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl b/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl index d12cf3a..f48c12d 100644 --- a/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl +++ b/modules/aws/vendor-access/files/permission_boundary_iam_policy.json.tpl @@ -19,9 +19,7 @@ "kms:*", "logs:*", "pricing:*", - "rds:DescribeDBInstances", - "rds:DescribeDBSnapshots", - "rds:DescribeDBSubnetGroups", + "rds:Describe*", "rds:ListTagsForResource", "route53:*", "route53domains:*", diff --git a/modules/aws/vendor-access/files/provision_preserve.json.tpl b/modules/aws/vendor-access/files/provision_preserve.json.tpl index 613dff0..3b86952 100644 --- a/modules/aws/vendor-access/files/provision_preserve.json.tpl +++ b/modules/aws/vendor-access/files/provision_preserve.json.tpl @@ -33,9 +33,7 @@ "kms:ListResourceTags", "logs:Describe*", "logs:List*", - "rds:DescribeDBInstances", - "rds:DescribeDBSnapshots", - "rds:DescribeDBSubnetGroups", + "rds:Describe*", "rds:ListTagsForResource", "route53:Get*", "route53:List*", From 7bddc8d078f5f2fd11289c99ebe56b047b30d623 Mon Sep 17 00:00:00 2001 From: mattisonchao Date: Sat, 15 Aug 2026 07:03:01 +0800 Subject: [PATCH 6/7] docs: mention RDS in bootstrap role capability list --- modules/aws/vendor-access/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/aws/vendor-access/README.md b/modules/aws/vendor-access/README.md index 731a9c2..57a1ea3 100644 --- a/modules/aws/vendor-access/README.md +++ b/modules/aws/vendor-access/README.md @@ -32,7 +32,7 @@ This module creates the following resources within your AWS account: - Authorized to fully manage StreamNative owned EKS cluster, worker nodes, and load balancers - `role/StreamNativeCloudBootstrapRole` & `policy/StreamNativeCloudBootstrapPolicy`: These IAM resources are used for provisioning, deprovisioning, and regular or emergency maintenance. This role and policy have the following characteristics: - - Have the ability to create, delete, manage, and read (within the limits of the permission boundary) EC2, EKS, IAM, DynamoDB, Route53, S3, and KMS resources + - Have the ability to create, delete, manage, and read (within the limits of the permission boundary) EC2, EKS, IAM, DynamoDB, Route53, S3, RDS, and KMS resources - Cannot create or modify IAM policies (but are allowed to work with IAM policies specified by this module) - Can only work with resources that have specific tags associated or certain expected patterns in the resource's friendly name. From e6eb08ff98d300c3c7ecab89dce25563046fce10 Mon Sep 17 00:00:00 2001 From: mattisonchao Date: Mon, 17 Aug 2026 15:55:52 +0800 Subject: [PATCH 7/7] fix: allow bootstrap and runtime roles to manage tiered-storage buckets The vendor-access S3 scope (s3_bucket_pattern, typically "snc-*") does not match the per-poolmember tiered-storage bucket names produced by terraform-aws-cloud's dns-bucket module (-tiered-storage-snc). Creating a new poolmember therefore fails at provision1 with s3:CreateBucket AccessDenied, before SQLWorkspace provisioning even starts. - provision_preserve: allow s3:CreateBucket and bucket management on *-tiered-storage-snc alongside the configured bucket pattern - runtime_iam_policy: allow ListBucket and object access on *-tiered-storage-snc alongside the configured bucket pattern --- .../vendor-access/files/provision_preserve.json.tpl | 3 ++- .../vendor-access/files/runtime_iam_policy.json.tpl | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/modules/aws/vendor-access/files/provision_preserve.json.tpl b/modules/aws/vendor-access/files/provision_preserve.json.tpl index 3b86952..7b92f79 100644 --- a/modules/aws/vendor-access/files/provision_preserve.json.tpl +++ b/modules/aws/vendor-access/files/provision_preserve.json.tpl @@ -182,7 +182,8 @@ "s3:PutEncryptionConfiguration" ], "Resource": [ - "arn:${partition}:s3:::${bucket_pattern}" + "arn:${partition}:s3:::${bucket_pattern}", + "arn:${partition}:s3:::*-tiered-storage-snc" ] }, { diff --git a/modules/aws/vendor-access/files/runtime_iam_policy.json.tpl b/modules/aws/vendor-access/files/runtime_iam_policy.json.tpl index 7da2f1b..93adc12 100644 --- a/modules/aws/vendor-access/files/runtime_iam_policy.json.tpl +++ b/modules/aws/vendor-access/files/runtime_iam_policy.json.tpl @@ -82,7 +82,10 @@ "s3:ListMultipart*", "s3:ListBucket" ], - "Resource": "arn:aws:s3:::${bucket_pattern}" + "Resource": [ + "arn:aws:s3:::${bucket_pattern}", + "arn:aws:s3:::*-tiered-storage-snc" + ] }, { "Sid": "s3o", @@ -93,7 +96,10 @@ "s3:*Object", "s3:*Multipart*" ], - "Resource": "arn:aws:s3:::${bucket_pattern}" + "Resource": [ + "arn:aws:s3:::${bucket_pattern}", + "arn:aws:s3:::*-tiered-storage-snc" + ] }, { "Sid": "vbc",