tests/test.sh exit code (0 → resolved); the classification below is post-hoc and cannot change it.{
"command": "echo \"AWS_ENDPOINT_URL=$AWS_ENDPOINT_URL\"; echo \"ENFORCE_IAM=$ENFORCE_IAM\"; aws --version 2>&1 | head -1",
"description": "Check environment variables"
}AWS_ENDPOINT_URL=http://localstack:4566 ENFORCE_IAM= aws-cli/2.34.48 Python/3.14.4 Linux/6.12.76-linuxkit exe/aarch64.ubuntu.24 [stdout] AWS_ENDPOINT_URL=http://localstack:4566 ENFORCE_IAM= aws-cli/2.34.48 Python/3.14.4 Linux/6.12.76-linuxkit exe/aarch64.ubuntu.24
{
"command": "aws ssm get-parameters-by-path --path /harbor/boundary/ --recursive --region us-east-1 --output json",
"description": "Read SSM manifest"
}{
"Parameters": [
{
"Name": "/harbor/boundary/policy-arn",
"Type": "String",
"Value": "arn:aws:iam::000000000000:policy/AnalystBoundaryPolicy",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:48.339000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/policy-arn",
"DataType": "text"
},
{
"Name": "/harbor/boundary/identity-arn",
"Type": "String",
"Value": "arn:aws:iam::000000000000:policy/AnalystIdentityPolicy",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:48.710000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/identity-arn",
"DataType": "text"
},
{
"Name": "/harbor/boundary/user-arn",
"Type": "String",
"Value": "arn:aws:iam::000000000000:user/analyst-user",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:49.080000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/user-arn",
"DataType": "text"
},
{
"Name": "/harbor/boundary/kms-key-arn",
"Type": "String",
"Value": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:49.451000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/kms-key-arn",
"DataType": "text"
},
{
"Name": "/harbor/boundary/bucket-name",
"Type": "String",
"Value": "vault-bucket",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:49.819000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/bucket-name",
"DataType": "text"
},
{
"Name": "/harbor/boundary/analyst-access-key-id",
"Type": "String",
"Value": "LKIAQAAAAAAAK2DMYCTZ",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:50.170000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/analyst-access-key-id",
"DataType": "text"
},
{
"Name": "/harbor/boundary/analyst-secret-key",
"Type": "SecureString",
"Value": "kms:alias/aws/ssm:zdjywKuaKE/nPC2ZlXsLFi9CX5kqc5+wnp7BmEem",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:50.613000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/analyst-secret-key",
"DataType": "text"
}
]
}
[stdout]
{
"Parameters": [
{
"Name": "/harbor/boundary/policy-arn",
"Type": "String",
"Value": "arn:aws:iam::000000000000:policy/AnalystBoundaryPolicy",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:48.339000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/policy-arn",
"DataType": "text"
},
{
"Name": "/harbor/boundary/identity-arn",
"Type": "String",
"Value": "arn:aws:iam::000000000000:policy/AnalystIdentityPolicy",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:48.710000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/identity-arn",
"DataType": "text"
},
{
"Name": "/harbor/boundary/user-arn",
"Type": "String",
"Value": "arn:aws:iam::000000000000:user/analyst-user",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:49.080000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/user-arn",
…[truncated]{
"command": "aws iam get-user --user-name analyst-user --region us-east-1 --output json",
"description": "Get analyst-user details"
}{
"User": {
"Path": "/",
"UserName": "analyst-user",
"UserId": "AIDAQAAAAAAAOJTRUPH4H",
"Arn": "arn:aws:iam::000000000000:user/analyst-user",
"CreateDate": "2026-05-17T07:48:45.697060+00:00"
}
}
[stdout]
{
"User": {
"Path": "/",
"UserName": "analyst-user",
"UserId": "AIDAQAAAAAAAOJTRUPH4H",
"Arn": "arn:aws:iam::000000000000:user/analyst-user",
"CreateDate": "2026-05-17T07:48:45.697060+00:00"
}
}{
"command": "aws iam list-policies --scope Local --region us-east-1 --output json",
"description": "List customer-managed policies"
}{
"Policies": [
{
"PolicyName": "AnalystBoundary",
"PolicyId": "A93YTW6AFENLDTSASSBUT",
"Arn": "arn:aws:iam::000000000000:policy/AnalystBoundary",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2026-05-17T07:48:44.950981+00:00",
"UpdateDate": "2026-05-17T07:48:44.950981+00:00"
},
{
"PolicyName": "AnalystIdentityPolicy",
"PolicyId": "ACTEYAPPANL65CILPZ8M2",
"Arn": "arn:aws:iam::000000000000:policy/AnalystIdentityPolicy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 1,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2026-05-17T07:48:44.533531+00:00",
"UpdateDate": "2026-05-17T07:48:44.533531+00:00"
}
]
}
[stdout]
{
"Policies": [
{
"PolicyName": "AnalystBoundary",
"PolicyId": "A93YTW6AFENLDTSASSBUT",
"Arn": "arn:aws:iam::000000000000:policy/AnalystBoundary",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2026-05-17T07:48:44.950981+00:00",
"UpdateDate": "2026-05-17T07:48:44.950981+00:00"
},
{
"PolicyName": "AnalystIdentityPolicy",
"PolicyId": "ACTEYAPPANL65CILPZ8M2",
"Arn": "arn:aws:iam::000000000000:policy/AnalystIdentityPolicy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 1,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2026-05-17T07:48:44.533531+00:00",
"UpdateDate": "2026-05-17T07:48:44.533531+00:00"
}
]
}{
"command": "aws iam list-attached-user-policies --user-name analyst-user --region us-east-1 --output json",
"description": "List policies attached to analyst-user"
}{
"AttachedPolicies": [
{
"PolicyName": "AnalystIdentityPolicy",
"PolicyArn": "arn:aws:iam::000000000000:policy/AnalystIdentityPolicy"
}
]
}
[stdout]
{
"AttachedPolicies": [
{
"PolicyName": "AnalystIdentityPolicy",
"PolicyArn": "arn:aws:iam::000000000000:policy/AnalystIdentityPolicy"
}
]
}{
"command": "aws iam list-user-policies --user-name analyst-user --region us-east-1 --output json",
"description": "List inline policies for analyst-user"
}{
"PolicyNames": []
}
[stdout]
{
"PolicyNames": []
}{
"command": "aws iam get-policy-version --policy-arn arn:aws:iam::000000000000:policy/AnalystBoundary --version-id v1 --region us-east-1 --output json",
"description": "Get AnalystBoundary document"
}{
"PolicyVersion": {
"Document": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BucketListing",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"NotResource": "arn:aws:s3:::vault-bucket/public/*"
},
{
"Sid": "ObjectOps",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::vault-bucket/Confidential/*"
},
{
"Sid": "PublicGuard",
"Effect": "Deny",
"Action": "s3:*",
"Resource": "arn:aws:s3:::vault-bucket/public/*"
},
{
"Sid": "KmsForVault",
"Effect": "Allow",
"Action": "kms:*",
"Resource": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95"
}
]
},
"VersionId": "v1",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:48:44.950981+00:00"
}
}
[stdout]
{
"PolicyVersion": {
"Document": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BucketListing",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"NotResource": "arn:aws:s3:::vault-bucket/public/*"
},
{
"Sid": "ObjectOps",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::vault-bucket/Confidential/*"
},
{
"Sid": "PublicGuard",
"Effect": "Deny",
"Action": "s3:*",
"Resource": "arn:aws:s3:::vault-bucket/public/*"
},
{
"Sid": "KmsForVault",
"Effect": "Allow",
"Action": "kms:*",
"Resource": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95"
}
]
},
"VersionId": "v1",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:48:44.950981+00:00"
}
}{
"command": "aws iam get-policy-version --policy-arn arn:aws:iam::000000000000:policy/AnalystIdentityPolicy --version-id v1 --region us-east-1 --output json",
"description": "Get AnalystIdentityPolicy document"
}{
"PolicyVersion": {
"Document": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AnalystS3",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
},
{
"Sid": "AnalystKms",
"Effect": "Allow",
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "AnalystGuard",
"Effect": "Deny",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::vault-bucket/public/*"
}
]
},
"VersionId": "v1",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:48:44.533531+00:00"
}
}
[stdout]
{
"PolicyVersion": {
"Document": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AnalystS3",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
},
{
"Sid": "AnalystKms",
"Effect": "Allow",
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "AnalystGuard",
"Effect": "Deny",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::vault-bucket/public/*"
}
]
},
"VersionId": "v1",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:48:44.533531+00:00"
}
}{
"command": "aws kms list-aliases --region us-east-1 --output json | head -50",
"description": "List KMS aliases"
}{
"Aliases": [
{
"AliasName": "alias/vault-kms",
"AliasArn": "arn:aws:kms:us-east-1:000000000000:alias/vault-kms",
"TargetKeyId": "20cf2089-fec1-442e-9449-30e3a6eeee95",
"CreationDate": "2026-05-17T07:48:42.104833+00:00"
}
]
}
[stdout]
{
"Aliases": [
{
"AliasName": "alias/vault-kms",
"AliasArn": "arn:aws:kms:us-east-1:000000000000:alias/vault-kms",
"TargetKeyId": "20cf2089-fec1-442e-9449-30e3a6eeee95",
"CreationDate": "2026-05-17T07:48:42.104833+00:00"
}
]
}{
"command": "aws s3api list-buckets --region us-east-1 --output json",
"description": "List buckets"
}{
"Buckets": [
{
"Name": "vault-bucket",
"CreationDate": "2026-05-17T07:48:42+00:00",
"BucketRegion": "us-east-1",
"BucketArn": "arn:aws:s3:::vault-bucket"
}
],
"Owner": {
"ID": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"
},
"Prefix": null
}
[stdout]
{
"Buckets": [
{
"Name": "vault-bucket",
"CreationDate": "2026-05-17T07:48:42+00:00",
"BucketRegion": "us-east-1",
"BucketArn": "arn:aws:s3:::vault-bucket"
}
],
"Owner": {
"ID": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"
},
"Prefix": null
}{
"command": "aws iam list-access-keys --user-name analyst-user --region us-east-1 --output json",
"description": "List analyst's access keys"
}{
"AccessKeyMetadata": [
{
"UserName": "analyst-user",
"AccessKeyId": "LKIAQAAAAAAAK2DMYCTZ",
"Status": "Active",
"CreateDate": "2026-05-17T07:48:46.476934+00:00"
}
]
}
[stdout]
{
"AccessKeyMetadata": [
{
"UserName": "analyst-user",
"AccessKeyId": "LKIAQAAAAAAAK2DMYCTZ",
"Status": "Active",
"CreateDate": "2026-05-17T07:48:46.476934+00:00"
}
]
}{
"command": "aws ssm get-parameter --name /harbor/boundary/analyst-secret-key --with-decryption --region us-east-1 --output json",
"description": "Get decrypted analyst secret key"
}{
"Parameter": {
"Name": "/harbor/boundary/analyst-secret-key",
"Type": "SecureString",
"Value": "zdjywKuaKE/nPC2ZlXsLFi9CX5kqc5+wnp7BmEem",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:50.613000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/analyst-secret-key",
"DataType": "text"
}
}
[stdout]
{
"Parameter": {
"Name": "/harbor/boundary/analyst-secret-key",
"Type": "SecureString",
"Value": "zdjywKuaKE/nPC2ZlXsLFi9CX5kqc5+wnp7BmEem",
"Version": 1,
"LastModifiedDate": "2026-05-17T07:48:50.613000+00:00",
"ARN": "arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/analyst-secret-key",
"DataType": "text"
}
}{
"file_path": "/tmp/identity.json",
"content": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"AnalystS3\",\n \"Effect\": \"Allow\",\n \"Action\": \"s3:*\",\n \"Resource\": \"*\"\n },\n {\n \"Sid\": \"AnalystKms\",\n \"Effect\": \"Allow\",\n \"Action\": \"kms:*\",\n \"Resource\": \"*\"\n }\n ]\n}\n"
}File created successfully at: /tmp/identity.json (file state is current in your context , no need to Read it back)
{
"file_path": "/tmp/boundary.json",
"content": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3ConfidentialObjectsOnly\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\",\n \"s3:PutObject\"\n ],\n \"Resource\": \"arn:aws:s3:::vault-bucket/confidential/*\"\n },\n {\n \"Sid\": \"KmsOnVaultCmkOnly\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"kms:Decrypt\",\n \"kms:GenerateDataKey\"\n ],\n \"Resource\": \"arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95\"\n }\n ]\n}\n"
}File created successfully at: /tmp/boundary.json (file state is current in your context , no need to Read it back)
{
"command": "aws iam create-policy-version --policy-arn arn:aws:iam::000000000000:policy/AnalystIdentityPolicy --policy-document file:///tmp/identity.json --set-as-default --region us-east-1 --output json",
"description": "Update AnalystIdentityPolicy document in place"
}{
"PolicyVersion": {
"VersionId": "v2",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:53:45.472033+00:00"
}
}
[stdout]
{
"PolicyVersion": {
"VersionId": "v2",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:53:45.472033+00:00"
}
}{
"command": "aws iam create-policy-version --policy-arn arn:aws:iam::000000000000:policy/AnalystBoundary --policy-document file:///tmp/boundary.json --set-as-default --region us-east-1 --output json",
"description": "Update AnalystBoundary document in place"
}{
"PolicyVersion": {
"VersionId": "v3",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:53:45.849536+00:00"
}
}
[stdout]
{
"PolicyVersion": {
"VersionId": "v3",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:53:45.849536+00:00"
}
}{
"command": "aws iam put-user-permissions-boundary --user-name analyst-user --permissions-boundary arn:aws:iam::000000000000:policy/AnalystBoundary --region us-east-1 --output json",
"description": "Attach boundary to analyst-user"
}(Bash completed with no output)
{
"command": "aws ssm put-parameter --name /harbor/boundary/policy-arn --value arn:aws:iam::000000000000:policy/AnalystBoundary --type String --overwrite --region us-east-1 --output json",
"description": "Fix SSM boundary policy ARN pointer"
}{
"Version": 2,
"Tier": "Standard"
}
[stdout]
{
"Version": 2,
"Tier": "Standard"
}{
"command": "aws iam get-user --user-name analyst-user --region us-east-1 --output json",
"description": "Confirm PermissionsBoundary on analyst-user"
}{
"User": {
"Path": "/",
"UserName": "analyst-user",
"UserId": "AIDAQAAAAAAAOJTRUPH4H",
"Arn": "arn:aws:iam::000000000000:user/analyst-user",
"CreateDate": "2026-05-17T07:48:45.697060+00:00",
"PermissionsBoundary": {
"PermissionsBoundaryType": "Policy",
"PermissionsBoundaryArn": "arn:aws:iam::000000000000:policy/AnalystBoundary"
}
}
}
[stdout]
{
"User": {
"Path": "/",
"UserName": "analyst-user",
"UserId": "AIDAQAAAAAAAOJTRUPH4H",
"Arn": "arn:aws:iam::000000000000:user/analyst-user",
"CreateDate": "2026-05-17T07:48:45.697060+00:00",
"PermissionsBoundary": {
"PermissionsBoundaryType": "Policy",
"PermissionsBoundaryArn": "arn:aws:iam::000000000000:policy/AnalystBoundary"
}
}
}{
"command": "aws iam get-policy-version --policy-arn arn:aws:iam::000000000000:policy/AnalystBoundary --version-id v3 --region us-east-1 --output json\naws iam get-policy-version --policy-arn arn:aws:iam::000000000000:policy/AnalystIdentityPolicy --version-id v2 --region us-east-1 --output json",
"description": "Confirm active policy documents"
}{
"PolicyVersion": {
"Document": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3ConfidentialObjectsOnly",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::vault-bucket/confidential/*"
},
{
"Sid": "KmsOnVaultCmkOnly",
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Resource": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95"
}
]
},
"VersionId": "v3",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:53:45.849536+00:00"
}
}
{
"PolicyVersion": {
"Document": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AnalystS3",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
},
{
"Sid": "AnalystKms",
"Effect": "Allow",
"Action": "kms:*",
"Resource": "*"
}
]
},
"VersionId": "v2",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:53:45.472033+00:00"
}
}
[stdout]
{
"PolicyVersion": {
"Document": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3ConfidentialObjectsOnly",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::vault-bucket/confidential/*"
},
{
"Sid": "KmsOnVaultCmkOnly",
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Resource": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95"
}
]
},
"VersionId": "v3",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:53:45.849536+00:00"
}
}
{
"PolicyVersion": {
"Document": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AnalystS3",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
},
{
"Sid": "AnalystKms",
"Effect": "Allow",
"Action": "kms:*",
"Resource": "*"
}
]
},
"VersionId": "v2",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:53:45.472033+00:00"
}
}{
"command": "set +e\nexport ENFORCE_IAM=1\nexport AWS_ACCESS_KEY_ID=\"$(aws ssm get-parameter --name /harbor/boundary/analyst-access-key-id --region us-east-1 --query Parameter.Value --output text)\"\nexport AWS_SECRET_ACCESS_KEY=\"$(aws ssm get-parameter --name /harbor/boundary/analyst-secret-key --with-decryption --region us-east-1 --query Parameter.Value --output text)\"\nunset AWS_SESSION_TOKEN\n\necho \"=== using key: $AWS_ACCESS_KEY_ID ===\"\necho\necho \"--- 1. PutObject vault-bucket/confidential/x (expect OK) ---\"\necho \"hello-conf\" | aws s3api put-object --bucket vault-bucket --key confidential/x --body /dev/stdin --region us-east-1 2>&1 | tail -5\necho\necho \"--- 2. GetObject vault-bucket/confidential/x (expect OK) ---\"\naws s3api get-object --bucket vault-bucket --key confidential/x /tmp/got.bin --region us-east-1 2>&1 | tail -5\necho\necho \"--- 3. PutObject vault-bucket/public/x (expect AccessDenied) ---\"\necho \"hello-pub\" | aws s3api put-object --bucket vault-bucket --key public/x --body /dev/stdin --region us-east-1 2>&1 | tail -5\necho\necho \"--- 4. PutObject some-other-bucket/x (expect AccessDenied) ---\"\necho \"x\" | aws s3api put-object --bucket some-other-bucket --key x --body /dev/stdin --region us-east-1 2>&1 | tail -5\necho\necho \"--- 5. kms:CreateKey (expect AccessDenied) ---\"\naws kms create-key --region us-east-1 2>&1 | tail -5\necho\necho \"--- 6. kms:GenerateDataKey on vault cmk (expect OK) ---\"\naws kms generate-data-key --key-id alias/vault-kms --key-spec AES_256 --region us-east-1 2>&1 | tail -5",
"description": "End-to-end verify using analyst credentials"
}aws: [ERROR]: An error occurred (AccessDeniedException) when calling the GetParameter operation: User: arn:aws:iam::000000000000:user/analyst-user is not authorized to perform: ssm:GetParameter on resource: arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/analyst-secret-key because no identity-based policy allows the ssm:GetParameter action === using key: LKIAQAAAAAAAK2DMYCTZ === --- 1. PutObject vault-bucket/confidential/x (expect OK) --- aws: [ERROR]: An error occurred (ParamValidation): Error parsing parameter '--body': Blob values must be a path to a file. --- 2. GetObject vault-bucket/confidential/x (expect OK) --- aws: [ERROR]: Partial credentials found in env, missing: AWS_SECRET_ACCESS_KEY --- 3. PutObject vault-bucket/public/x (expect AccessDenied) --- aws: [ERROR]: An error occurred (ParamValidation): Error parsing parameter '--body': Blob values must be a path to a file. --- 4. PutObject some-other-bucket/x (expect AccessDenied) --- aws: [ERROR]: An error occurred (ParamValidation): Error parsing parameter '--body': Blob values must be a path to a file. --- 5. kms:CreateKey (expect AccessDenied) --- aws: [ERROR]: Partial credentials found in env, missing: AWS_SECRET_ACCESS_KEY --- 6. kms:GenerateDataKey on vault cmk (expect OK) --- aws: [ERROR]: Partial credentials found in env, missing: AWS_SECRET_ACCESS_KEY [stdout] aws: [ERROR]: An error occurred (AccessDeniedException) when calling the GetParameter operation: User: arn:aws:iam::000000000000:user/analyst-user is not authorized to perform: ssm:GetParameter on resource: arn:aws:ssm:us-east-1:000000000000:parameter/harbor/boundary/analyst-secret-key because no identity-based policy allows the ssm:GetParameter action === using key: LKIAQAAAAAAAK2DMYCTZ === --- 1. PutObject vault-bucket/confidential/x (expect OK) --- aws: [ERROR]: An error occurred (ParamValidation): Error parsing parameter '--body': Blob values must be a path to a file. --- 2. GetObject vault-bucket/confidential/x (expect OK) --- aws: [ERROR]: Partial credentials found in env, missing: AWS_SECRET_ACCESS_KEY --- 3. PutObject vault-bucket/public/x (expect AccessDenied) --- aws: [ERROR]: An error occurred (ParamValidation): Error parsing parameter '--body': Blob values must be a path to a file. --- 4. PutObject some-other-bucket/x (expect AccessDenied) --- aws: [ERROR]: An error occurred (ParamValidation): Error parsing parameter '--body': Blob values must be a path to a file. --- 5. kms:CreateKey (expect AccessDenied) --- aws: [ERROR]: Partial credentials found in env, missing: AWS_SECRET_ACCESS_KEY --- 6. kms:GenerateDataKey on vault cmk (expect OK) --- aws: [ERROR]: Partial credentials found in env, missing: AWS_SECRET_ACCESS_KEY
{
"command": "set +e\n# fetch creds with admin (no ENFORCE_IAM yet)\nACCESS_KEY=\"$(aws ssm get-parameter --name /harbor/boundary/analyst-access-key-id --region us-east-1 --query Parameter.Value --output text)\"\nSECRET_KEY=\"$(aws ssm get-parameter --name /harbor/boundary/analyst-secret-key --with-decryption --region us-east-1 --query Parameter.Value --output text)\"\necho \"fetched: $ACCESS_KEY / ${SECRET_KEY:0:6}...\"\necho \"hello-conf\" > /tmp/conf.bin\necho \"hello-pub\" > /tmp/pub.bin\n\nrun_as_analyst() {\n AWS_ACCESS_KEY_ID=\"$ACCESS_KEY\" AWS_SECRET_ACCESS_KEY=\"$SECRET_KEY\" AWS_SESSION_TOKEN=\"\" ENFORCE_IAM=1 \"$@\"\n}\n\necho\necho \"=== 1. PutObject vault-bucket/confidential/x (expect OK) ===\"\nrun_as_analyst aws s3api put-object --bucket vault-bucket --key confidential/x --body /tmp/conf.bin --region us-east-1 2>&1 | tail -3\necho\necho \"=== 2. GetObject vault-bucket/confidential/x (expect OK) ===\"\nrun_as_analyst aws s3api get-object --bucket vault-bucket --key confidential/x /tmp/got.bin --region us-east-1 2>&1 | tail -3\necho\necho \"=== 3. PutObject vault-bucket/public/x (expect AccessDenied) ===\"\nrun_as_analyst aws s3api put-object --bucket vault-bucket --key public/x --body /tmp/pub.bin --region us-east-1 2>&1 | tail -3\necho\necho \"=== 4. PutObject some-other-bucket/x (expect AccessDenied) ===\"\nrun_as_analyst aws s3api put-object --bucket some-other-bucket --key x --body /tmp/pub.bin --region us-east-1 2>&1 | tail -3\necho\necho \"=== 5. kms:CreateKey (expect AccessDenied) ===\"\nrun_as_analyst aws kms create-key --region us-east-1 2>&1 | tail -3\necho\necho \"=== 6. kms:GenerateDataKey on alias/vault-kms (expect OK) ===\"\nrun_as_analyst aws kms generate-data-key --key-id alias/vault-kms --key-spec AES_256 --region us-east-1 2>&1 | tail -3",
"description": "End-to-end verify under analyst creds with ENFORCE_IAM=1"
}fetched: LKIAQAAAAAAAK2DMYCTZ / zdjywK...
=== 1. PutObject vault-bucket/confidential/x (expect OK) ===
"SSEKMSKeyId": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95",
"BucketKeyEnabled": true
}
=== 2. GetObject vault-bucket/confidential/x (expect OK) ===
"SSEKMSKeyId": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95",
"BucketKeyEnabled": true
}
=== 3. PutObject vault-bucket/public/x (expect AccessDenied) ===
aws: [ERROR]: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
=== 4. PutObject some-other-bucket/x (expect AccessDenied) ===
aws: [ERROR]: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
=== 5. kms:CreateKey (expect AccessDenied) ===
aws: [ERROR]: An error occurred (AccessDeniedException) when calling the CreateKey operation: User: arn:aws:iam::000000000000:user/analyst-user is not authorized to perform: kms:CreateKey on resource: * because no identity-based policy allows the kms:CreateKey action
=== 6. kms:GenerateDataKey on alias/vault-kms (expect OK) ===
aws: [ERROR]: An error occurred (AccessDeniedException) when calling the GenerateDataKey operation: User: arn:aws:iam::000000000000:user/analyst-user is not authorized to perform: kms:GenerateDataKey on resource: * because no identity-based policy allows the kms:GenerateDataKey action
[stdout]
fetched: LKIAQAAAAAAAK2DMYCTZ / zdjywK...
=== 1. PutObject vault-bucket/confidential/x (expect OK) ===
"SSEKMSKeyId": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95",
"BucketKeyEnabled": true
}
=== 2. GetObject vault-bucket/confidential/x (expect OK) ===
"SSEKMSKeyId": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95",
"BucketKeyEnabled": true
}
=== 3. PutObject vault-bucket/public/x (expect AccessDenied) ===
aws: [ERROR]: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
=== 4. PutObject some-other-bucket/x (expect AccessDenied) ===
aws: [ERROR]: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
=== 5. kms:CreateKey (expect AccessDenied) ===
aws: [ERROR]: An error occurred (AccessDeniedException) when calling the CreateKey operation: User: arn:aws:iam::000000000000:user/analyst-user is not authorized to perform: kms:CreateKey on resource: * because no identity-based policy allows the kms:CreateKey action
=== 6. kms:GenerateDataKey on alias/vault-kms (expect OK) ===
aws: [ERROR]: An error occurred (AccessDeniedException) when calling the GenerateDataKey operation: User: arn:aws:iam::000000000000:user/analyst-user is not authorized to perform: kms:GenerateDataKey on resource: * because no identity-based policy allows the kms:GenerateDataKey action{
"command": "set +e\nACCESS_KEY=\"$(aws ssm get-parameter --name /harbor/boundary/analyst-access-key-id --region us-east-1 --query Parameter.Value --output text)\"\nSECRET_KEY=\"$(aws ssm get-parameter --name /harbor/boundary/analyst-secret-key --with-decryption --region us-east-1 --query Parameter.Value --output text)\"\nKEY_ARN=\"$(aws ssm get-parameter --name /harbor/boundary/kms-key-arn --region us-east-1 --query Parameter.Value --output text)\"\necho \"key arn: $KEY_ARN\"\necho\necho \"=== GenerateDataKey by key ARN (expect OK) ===\"\nAWS_ACCESS_KEY_ID=\"$ACCESS_KEY\" AWS_SECRET_ACCESS_KEY=\"$SECRET_KEY\" AWS_SESSION_TOKEN=\"\" ENFORCE_IAM=1 \\\n aws kms generate-data-key --key-id \"$KEY_ARN\" --key-spec AES_256 --region us-east-1 2>&1 | tail -3\necho\necho \"=== Decrypt with key ARN (expect OK -- need a real ciphertext, just probe authz) ===\"\nAWS_ACCESS_KEY_ID=\"$ACCESS_KEY\" AWS_SECRET_ACCESS_KEY=\"$SECRET_KEY\" AWS_SESSION_TOKEN=\"\" ENFORCE_IAM=1 \\\n aws kms decrypt --key-id \"$KEY_ARN\" --ciphertext-blob \"AAAA\" --region us-east-1 2>&1 | tail -3",
"description": "Try KMS with explicit key ARN"
}key arn: arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95
=== GenerateDataKey by key ARN (expect OK) ===
"Plaintext": "1MPFWkuIc9Wty/p0VyUFqvjprR/LqVTqU9Kc35HG9uM=",
"KeyId": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95"
}
=== Decrypt with key ARN (expect OK -- need a real ciphertext, just probe authz) ===
aws: [ERROR]: An error occurred (InvalidCiphertextException) when calling the Decrypt operation:
[stdout]
key arn: arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95
=== GenerateDataKey by key ARN (expect OK) ===
"Plaintext": "1MPFWkuIc9Wty/p0VyUFqvjprR/LqVTqU9Kc35HG9uM=",
"KeyId": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95"
}
=== Decrypt with key ARN (expect OK -- need a real ciphertext, just probe authz) ===
aws: [ERROR]: An error occurred (InvalidCiphertextException) when calling the Decrypt operation:{
"file_path": "/tmp/boundary.json",
"content": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3ConfidentialObjectsOnly\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\",\n \"s3:PutObject\"\n ],\n \"Resource\": \"arn:aws:s3:::vault-bucket/confidential/*\"\n },\n {\n \"Sid\": \"KmsOnVaultCmkOnly\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"kms:Decrypt\",\n \"kms:GenerateDataKey\"\n ],\n \"Resource\": [\n \"arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95\",\n \"arn:aws:kms:us-east-1:000000000000:alias/vault-kms\"\n ]\n }\n ]\n}\n"
}The file /tmp/boundary.json has been updated successfully. (file state is current in your context , no need to Read it back)
{
"command": "aws iam list-policy-versions --policy-arn arn:aws:iam::000000000000:policy/AnalystBoundary --region us-east-1 --output json",
"description": "Check version count before adding another"
}{
"Versions": [
{
"VersionId": "v3",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:53:45.849536+00:00"
},
{
"VersionId": "v2",
"IsDefaultVersion": false,
"CreateDate": "2026-05-17T07:48:45.322155+00:00"
},
{
"VersionId": "v1",
"IsDefaultVersion": false,
"CreateDate": "2026-05-17T07:48:44.950981+00:00"
}
]
}
[stdout]
{
"Versions": [
{
"VersionId": "v3",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:53:45.849536+00:00"
},
{
"VersionId": "v2",
"IsDefaultVersion": false,
"CreateDate": "2026-05-17T07:48:45.322155+00:00"
},
{
"VersionId": "v1",
"IsDefaultVersion": false,
"CreateDate": "2026-05-17T07:48:44.950981+00:00"
}
]
}{
"command": "aws iam create-policy-version --policy-arn arn:aws:iam::000000000000:policy/AnalystBoundary --policy-document file:///tmp/boundary.json --set-as-default --region us-east-1 --output json",
"description": "Update AnalystBoundary with alias ARN included"
}{
"PolicyVersion": {
"VersionId": "v4",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:55:32.662821+00:00"
}
}
[stdout]
{
"PolicyVersion": {
"VersionId": "v4",
"IsDefaultVersion": true,
"CreateDate": "2026-05-17T07:55:32.662821+00:00"
}
}{
"command": "set +e\nACCESS_KEY=\"$(aws ssm get-parameter --name /harbor/boundary/analyst-access-key-id --region us-east-1 --query Parameter.Value --output text)\"\nSECRET_KEY=\"$(aws ssm get-parameter --name /harbor/boundary/analyst-secret-key --with-decryption --region us-east-1 --query Parameter.Value --output text)\"\necho \"hello-conf\" > /tmp/conf.bin\necho \"hello-pub\" > /tmp/pub.bin\n\nrun_as_analyst() {\n AWS_ACCESS_KEY_ID=\"$ACCESS_KEY\" AWS_SECRET_ACCESS_KEY=\"$SECRET_KEY\" AWS_SESSION_TOKEN=\"\" ENFORCE_IAM=1 \"$@\"\n}\n\npass=0; fail=0\ncheck() {\n local label=\"$1\"; shift\n local expect=\"$1\"; shift\n out=\"$(\"$@\" 2>&1)\"; rc=$?\n if [ \"$expect\" = \"ok\" ]; then\n if [ $rc -eq 0 ]; then echo \"PASS $label\"; pass=$((pass+1)); else echo \"FAIL $label :: $out\" | head -3; fail=$((fail+1)); fi\n else\n if echo \"$out\" | grep -qi 'AccessDenied'; then echo \"PASS $label (denied)\"; pass=$((pass+1)); else echo \"FAIL $label expected denied, got rc=$rc :: $out\" | head -3; fail=$((fail+1)); fi\n fi\n}\n\ncheck \"1. PutObject confidential/x\" ok run_as_analyst aws s3api put-object --bucket vault-bucket --key confidential/x --body /tmp/conf.bin --region us-east-1\ncheck \"2. GetObject confidential/x\" ok run_as_analyst aws s3api get-object --bucket vault-bucket --key confidential/x /tmp/got.bin --region us-east-1\ncheck \"3. PutObject public/x\" denied run_as_analyst aws s3api put-object --bucket vault-bucket --key public/x --body /tmp/pub.bin --region us-east-1\ncheck \"4. PutObject other bucket\" denied run_as_analyst aws s3api put-object --bucket some-other-bucket --key x --body /tmp/pub.bin --region us-east-1\ncheck \"5. kms:CreateKey\" denied run_as_analyst aws kms create-key --region us-east-1\ncheck \"6. kms:GenerateDataKey alias\" ok run_as_analyst aws kms generate-data-key --key-id alias/vault-kms --key-spec AES_256 --region us-east-1\n\necho\necho \"summary: $pass pass / $fail fail\"\necho\necho \"--- iam:GetUser PermissionsBoundary signal ---\"\naws iam get-user --user-name analyst-user --region us-east-1 --query 'User.PermissionsBoundary' --output json\necho\necho \"--- SSM /harbor/boundary/policy-arn ---\"\naws ssm get-parameter --name /harbor/boundary/policy-arn --region us-east-1 --query Parameter.Value --output text",
"description": "Full end-to-end verification"
}PASS 1. PutObject confidential/x
PASS 2. GetObject confidential/x
PASS 3. PutObject public/x (denied)
PASS 4. PutObject other bucket (denied)
PASS 5. kms:CreateKey (denied)
FAIL 6. kms:GenerateDataKey alias ::
aws: [ERROR]: An error occurred (AccessDeniedException) when calling the GenerateDataKey operation: User: arn:aws:iam::000000000000:user/analyst-user is not authorized to perform: kms:GenerateDataKey on resource: * because no identity-based policy allows the kms:GenerateDataKey action
summary: 5 pass / 1 fail
--- iam:GetUser PermissionsBoundary signal ---
{
"PermissionsBoundaryType": "Policy",
"PermissionsBoundaryArn": "arn:aws:iam::000000000000:policy/AnalystBoundary"
}
--- SSM /harbor/boundary/policy-arn ---
arn:aws:iam::000000000000:policy/AnalystBoundary
[stdout]
PASS 1. PutObject confidential/x
PASS 2. GetObject confidential/x
PASS 3. PutObject public/x (denied)
PASS 4. PutObject other bucket (denied)
PASS 5. kms:CreateKey (denied)
FAIL 6. kms:GenerateDataKey alias ::
aws: [ERROR]: An error occurred (AccessDeniedException) when calling the GenerateDataKey operation: User: arn:aws:iam::000000000000:user/analyst-user is not authorized to perform: kms:GenerateDataKey on resource: * because no identity-based policy allows the kms:GenerateDataKey action
summary: 5 pass / 1 fail
--- iam:GetUser PermissionsBoundary signal ---
{
"PermissionsBoundaryType": "Policy",
"PermissionsBoundaryArn": "arn:aws:iam::000000000000:policy/AnalystBoundary"
}
--- SSM /harbor/boundary/policy-arn ---
arn:aws:iam::000000000000:policy/AnalystBoundary{
"command": "set +e\nACCESS_KEY=\"$(aws ssm get-parameter --name /harbor/boundary/analyst-access-key-id --region us-east-1 --query Parameter.Value --output text)\"\nSECRET_KEY=\"$(aws ssm get-parameter --name /harbor/boundary/analyst-secret-key --with-decryption --region us-east-1 --query Parameter.Value --output text)\"\nKEY_ARN=\"$(aws ssm get-parameter --name /harbor/boundary/kms-key-arn --region us-east-1 --query Parameter.Value --output text)\"\nKEY_ID=\"${KEY_ARN##*key/}\"\necho \"id only: $KEY_ID\"\n\nrun_as_analyst() {\n AWS_ACCESS_KEY_ID=\"$ACCESS_KEY\" AWS_SECRET_ACCESS_KEY=\"$SECRET_KEY\" AWS_SESSION_TOKEN=\"\" ENFORCE_IAM=1 \"$@\"\n}\n\necho \"-- via key ARN --\"\nrun_as_analyst aws kms generate-data-key --key-id \"$KEY_ARN\" --key-spec AES_256 --region us-east-1 2>&1 | tail -3\necho \"-- via short key id --\"\nrun_as_analyst aws kms generate-data-key --key-id \"$KEY_ID\" --key-spec AES_256 --region us-east-1 2>&1 | tail -3\necho \"-- via alias --\"\nrun_as_analyst aws kms generate-data-key --key-id alias/vault-kms --key-spec AES_256 --region us-east-1 2>&1 | tail -3",
"description": "Probe KMS by different key identifiers"
}id only: 20cf2089-fec1-442e-9449-30e3a6eeee95
-- via key ARN --
"Plaintext": "Rzv51AJe/McAdyYCULS38iiQ8sxyum6vb3/3MykXhCw=",
"KeyId": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95"
}
-- via short key id --
"Plaintext": "pWb/x6VmQZD7NyXN6eTc7amYGw3Fz3qSqqfBB8zGuZo=",
"KeyId": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95"
}
-- via alias --
aws: [ERROR]: An error occurred (AccessDeniedException) when calling the GenerateDataKey operation: User: arn:aws:iam::000000000000:user/analyst-user is not authorized to perform: kms:GenerateDataKey on resource: * because no identity-based policy allows the kms:GenerateDataKey action
[stdout]
id only: 20cf2089-fec1-442e-9449-30e3a6eeee95
-- via key ARN --
"Plaintext": "Rzv51AJe/McAdyYCULS38iiQ8sxyum6vb3/3MykXhCw=",
"KeyId": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95"
}
-- via short key id --
"Plaintext": "pWb/x6VmQZD7NyXN6eTc7amYGw3Fz3qSqqfBB8zGuZo=",
"KeyId": "arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95"
}
-- via alias --
aws: [ERROR]: An error occurred (AccessDeniedException) when calling the GenerateDataKey operation: User: arn:aws:iam::000000000000:user/analyst-user is not authorized to perform: kms:GenerateDataKey on resource: * because no identity-based policy allows the kms:GenerateDataKey action{
"command": "echo \"=== iam:GetUser ===\"\naws iam get-user --user-name analyst-user --region us-east-1 --query 'User.{Arn:Arn,Boundary:PermissionsBoundary.PermissionsBoundaryArn}' --output json\necho\necho \"=== boundary active doc ===\"\naws iam get-policy-version --policy-arn arn:aws:iam::000000000000:policy/AnalystBoundary --version-id $(aws iam get-policy --policy-arn arn:aws:iam::000000000000:policy/AnalystBoundary --region us-east-1 --query Policy.DefaultVersionId --output text) --region us-east-1 --query 'PolicyVersion.Document' --output json\necho\necho \"=== identity active doc ===\"\naws iam get-policy-version --policy-arn arn:aws:iam::000000000000:policy/AnalystIdentityPolicy --version-id $(aws iam get-policy --policy-arn arn:aws:iam::000000000000:policy/AnalystIdentityPolicy --region us-east-1 --query Policy.DefaultVersionId --output text) --region us-east-1 --query 'PolicyVersion.Document' --output json\necho\necho \"=== SSM pointers ===\"\naws ssm get-parameter --name /harbor/boundary/policy-arn --region us-east-1 --query 'Parameter.{N:Name,V:Value}' --output text\naws ssm get-parameter --name /harbor/boundary/identity-arn --region us-east-1 --query 'Parameter.{N:Name,V:Value}' --output text\naws ssm get-parameter --name /harbor/boundary/user-arn --region us-east-1 --query 'Parameter.{N:Name,V:Value}' --output text",
"description": "Final state snapshot"
}=== iam:GetUser ===
{
"Arn": "arn:aws:iam::000000000000:user/analyst-user",
"Boundary": "arn:aws:iam::000000000000:policy/AnalystBoundary"
}
=== boundary active doc ===
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3ConfidentialObjectsOnly",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::vault-bucket/confidential/*"
},
{
"Sid": "KmsOnVaultCmkOnly",
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Resource": [
"arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95",
"arn:aws:kms:us-east-1:000000000000:alias/vault-kms"
]
}
]
}
=== identity active doc ===
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AnalystS3",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
},
{
"Sid": "AnalystKms",
"Effect": "Allow",
"Action": "kms:*",
"Resource": "*"
}
]
}
=== SSM pointers ===
/harbor/boundary/policy-arn arn:aws:iam::000000000000:policy/AnalystBoundary
/harbor/boundary/identity-arn arn:aws:iam::000000000000:policy/AnalystIdentityPolicy
/harbor/boundary/user-arn arn:aws:iam::000000000000:user/analyst-user
[stdout]
=== iam:GetUser ===
{
"Arn": "arn:aws:iam::000000000000:user/analyst-user",
"Boundary": "arn:aws:iam::000000000000:policy/AnalystBoundary"
}
=== boundary active doc ===
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3ConfidentialObjectsOnly",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::vault-bucket/confidential/*"
},
{
"Sid": "KmsOnVaultCmkOnly",
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Resource": [
"arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95",
"arn:aws:kms:us-east-1:000000000000:alias/vault-kms"
]
}
]
}
=== identity active doc ===
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AnalystS3",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
},
{
"Sid": "AnalystKms",
"Effect": "Allow",
"Action": "kms:*",
"Resource": "*"
}
]
}
=== SSM pointers ===
/harbor/boundary/policy-arn arn:aws:iam::000000000000:policy/AnalystBoundary
/harbor/boundary/identity-arn arn:aws:iam::000000000000:policy/AnalystIdentityPolicy
/harbor/boundary/user-arn arn:aws:iam::000000000000:user/analyst-userNo file changes, the agent left the workspace untouched.
downloading uv 0.9.7 aarch64-unknown-linux-gnu
Downloading pygments (1.2MiB)
Downloading botocore (12.7MiB)
Downloading pygments
Downloading botocore
Installed 13 packages in 109ms
============================= test session starts ==============================
platform linux -- Python 3.12.3, pytest-8.4.1, pluggy-1.6.0 -- /root/.cache/uv/archive-v0/ZxtmXST02ZcRs1Jo1MfhC/bin/python
cachedir: .pytest_cache
rootdir: /tests
plugins: json-ctrf-0.3.5
collecting ... collected 27 items
../tests/test_outputs.py::test_01_analyst_user_exists PASSED [ 3%]
../tests/test_outputs.py::test_02_identity_policy_attached_to_user PASSED [ 7%]
../tests/test_outputs.py::test_03_boundary_attached_via_get_user PASSED [ 11%]
../tests/test_outputs.py::test_04_vault_bucket_exists_with_public_access_block PASSED [ 14%]
../tests/test_outputs.py::test_05_kms_alias_and_ssm_pointers_resolve PASSED [ 18%]
../tests/test_outputs.py::test_06_identity_policy_grants_full_s3_and_full_kms PASSED [ 22%]
../tests/test_outputs.py::test_07_identity_policy_has_no_explicit_deny_anywhere PASSED [ 25%]
../tests/test_outputs.py::test_08_user_has_no_admin_managed_policy_attached PASSED [ 29%]
../tests/test_outputs.py::test_09_boundary_effect_allow_only PASSED [ 33%]
../tests/test_outputs.py::test_10_boundary_has_no_NotResource_or_NotAction PASSED [ 37%]
../tests/test_outputs.py::test_11_boundary_object_actions_scoped_to_confidential_prefix PASSED [ 40%]
../tests/test_outputs.py::test_12_boundary_listbucket_uses_s3_prefix_condition FAILED [ 44%]
../tests/test_outputs.py::test_13_boundary_kms_actions_scoped_to_cmk_arn FAILED [ 48%]
../tests/test_outputs.py::test_14_boundary_does_not_grant_kms_create_key_or_wildcard_kms PASSED [ 51%]
../tests/test_outputs.py::test_15_boundary_does_not_grant_iam_self_modify PASSED [ 55%]
../tests/test_outputs.py::test_16_boundary_size_under_managed_policy_limit PASSED [ 59%]
../tests/test_outputs.py::test_17_boundary_allows_confidential_put_via_simulator PASSED [ 62%]
../tests/test_outputs.py::test_18_boundary_denies_public_put_via_simulator PASSED [ 66%]
../tests/test_outputs.py::test_19_boundary_allows_kms_decrypt_via_simulator PASSED [ 70%]
../tests/test_outputs.py::test_20_boundary_denies_kms_create_key_via_simulator PASSED [ 74%]
../tests/test_outputs.py::test_21_analyst_can_put_to_confidential_prefix PASSED [ 77%]
../tests/test_outputs.py::test_22_analyst_cannot_put_to_public_prefix PASSED [ 81%]
../tests/test_outputs.py::test_23_analyst_cannot_create_kms_key PASSED [ 85%]
../tests/test_outputs.py::test_24_analyst_cannot_put_to_a_different_bucket PASSED [ 88%]
../tests/test_outputs.py::test_25_boundary_object_resource_prefix_is_lowercase_confidential PASSED [ 92%]
../tests/test_outputs.py::test_26_ssm_policy_arn_resolves_to_a_live_boundary_managed_policy PASSED [ 96%]
../tests/test_outputs.py::test_27_boundary_default_version_reflects_the_runtime_intended_shape PASSED [100%]
=================================== FAILURES ===================================
_____________ test_12_boundary_listbucket_uses_s3_prefix_condition _____________
def test_12_boundary_listbucket_uses_s3_prefix_condition():
bucket = _bucket()
bucket_arn = f"arn:aws:s3:::{bucket}"
found = False
for s in _stmts(_boundary_doc()):
if s.get("Effect") != "Allow":
continue
actions = set(_as_list(s.get("Action")))
if "s3:ListBucket" not in actions:
continue
found = True
resources = _as_list(s.get("Resource"))
assert bucket_arn in resources, (
f"boundary s3:ListBucket Resource={resources!r} does not include the bucket ARN {bucket_arn!r}; "
f"ListBucket is a bucket-level action and must target the bucket ARN, not an object-prefix ARN"
)
cond = s.get("Condition", {}) or {}
sl = cond.get("StringLike", {})
prefixes = _as_list(sl.get("s3:prefix"))
assert any("confidential/" in p for p in prefixes), (
f"boundary s3:ListBucket has no Condition.StringLike on s3:prefix matching 'confidential/*'; "
f"got Condition={cond!r}. The prefix condition is the documented way to restrict list to a "
f"prefix , anything else (NotResource, object-ARN scoping, etc.) does not actually restrict list."
)
> assert found, (
f"boundary has no s3:ListBucket Allow statement , without it, even a prefix-scoped list is denied"
)
E AssertionError: boundary has no s3:ListBucket Allow statement , without it, even a prefix-scoped list is denied
E assert False
/tests/test_outputs.py:319: AssertionError
________________ test_13_boundary_kms_actions_scoped_to_cmk_arn ________________
def test_13_boundary_kms_actions_scoped_to_cmk_arn():
cmk_arn = _key_arn()
found = False
for s in _stmts(_boundary_doc()):
if s.get("Effect") != "Allow":
continue
actions = _as_list(s.get("Action"))
if not any(a.startswith("kms:") for a in actions):
continue
found = True
resources = _as_list(s.get("Resource"))
assert "*" not in resources, (
f"boundary kms statement has Resource '*' (actions={actions!r}); must be narrowed to the cmk arn"
)
bad = [r for r in resources if r != cmk_arn]
> assert not bad, (
f"boundary kms statement Resource={resources!r}; expected exactly [{cmk_arn!r}]"
)
E AssertionError: boundary kms statement Resource=['arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95', 'arn:aws:kms:us-east-1:000000000000:alias/vault-kms']; expected exactly ['arn:aws:kms:us-east-1:000000000000:key/20cf2089-fec1-442e-9449-30e3a6eeee95']
E assert not ['arn:aws:kms:us-east-1:000000000000:alias/vault-kms']
/tests/test_outputs.py:339: AssertionError
=============================== warnings summary ===============================
test_outputs.py: 54 warnings
/root/.cache/uv/archive-v0/ZxtmXST02ZcRs1Jo1MfhC/lib/python3.12/site-packages/botocore/auth.py:424: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
datetime_now = datetime.datetime.utcnow()
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
==================================== PASSES ====================================
=========================== short test summary info ============================
PASSED ../tests/test_outputs.py::test_01_analyst_user_exists
PASSED ../tests/test_outputs.py::test_02_identity_policy_attached_to_user
PASSED ../tests/test_outputs.py::test_03_boundary_attached_via_get_user
PASSED ../tests/test_outputs.py::test_04_vault_bucket_exists_with_public_access_block
PASSED ../tests/test_outputs.py::test_05_kms_alias_and_ssm_pointers_resolve
PASSED ../tests/test_outputs.py::test_06_identity_policy_grants_full_s3_and_full_kms
PASSED ../tests/test_outputs.py::test_07_identity_policy_has_no_explicit_deny_anywhere
PASSED ../tests/test_outputs.py::test_08_user_has_no_admin_managed_policy_attached
PASSED ../tests/test_outputs.py::test_09_boundary_effect_allow_only
PASSED ../tests/test_outputs.py::test_10_boundary_has_no_NotResource_or_NotAction
PASSED ../tests/test_outputs.py::test_11_boundary_object_actions_scoped_to_confidential_prefix
PASSED ../tests/test_outputs.py::test_14_boundary_does_not_grant_kms_create_key_or_wildcard_kms
PASSED ../tests/test_outputs.py::test_15_boundary_does_not_grant_iam_self_modify
PASSED ../tests/test_outputs.py::test_16_boundary_size_under_managed_policy_limit
PASSED ../tests/test_outputs.py::test_17_boundary_allows_confidential_put_via_simulator
PASSED ../tests/test_outputs.py::test_18_boundary_denies_public_put_via_simulator
PASSED ../tests/test_outputs.py::test_19_boundary_allows_kms_decrypt_via_simulator
PASSED ../tests/test_outputs.py::test_20_boundary_denies_kms_create_key_via_simulator
PASSED ../tests/test_outputs.py::test_21_analyst_can_put_to_confidential_prefix
PASSED ../tests/test_outputs.py::test_22_analyst_cannot_put_to_public_prefix
PASSED ../tests/test_outputs.py::test_23_analyst_cannot_create_kms_key
PASSED ../tests/test_outputs.py::test_24_analyst_cannot_put_to_a_different_bucket
PASSED ../tests/test_outputs.py::test_25_boundary_object_resource_prefix_is_lowercase_confidential
PASSED ../tests/test_outputs.py::test_26_ssm_policy_arn_resolves_to_a_live_boundary_managed_policy
PASSED ../tests/test_outputs.py::test_27_boundary_default_version_reflects_the_runtime_intended_shape
FAILED ../tests/test_outputs.py::test_12_boundary_listbucket_uses_s3_prefix_condition
FAILED ../tests/test_outputs.py::test_13_boundary_kms_actions_scoped_to_cmk_arn
================== 2 failed, 25 passed, 54 warnings in 0.97s ===================Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_7b8c84a28def451e. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_7b8c84a28def451e · verifier authoritative; classifier explanatory.