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; which aws",
"description": "Inspect environment"
}AWS_ENDPOINT_URL=http://localstack:4566 ENFORCE_IAM= aws-cli/2.34.45 Python/3.14.4 Linux/6.10.14-linuxkit exe/aarch64.ubuntu.24 /usr/local/bin/aws [stdout] AWS_ENDPOINT_URL=http://localstack:4566 ENFORCE_IAM= aws-cli/2.34.45 Python/3.14.4 Linux/6.10.14-linuxkit exe/aarch64.ubuntu.24 /usr/local/bin/aws
{
"command": "ls /app",
"description": "List app directory"
}(Bash completed with no output)
{
"command": "ls -la /app; echo \"---\"; aws sts get-caller-identity --endpoint-url $AWS_ENDPOINT_URL 2>&1",
"description": "List app and check identity"
}total 8
drwxr-xr-x 2 root root 4096 May 9 01:24 .
drwxr-xr-x 1 root root 4096 May 9 15:40 ..
---
{
"UserId": "000000000000",
"Account": "000000000000",
"Arn": "arn:aws:iam::000000000000:root"
}
[stdout]
total 8
drwxr-xr-x 2 root root 4096 May 9 01:24 .
drwxr-xr-x 1 root root 4096 May 9 15:40 ..
---
{
"UserId": "000000000000",
"Account": "000000000000",
"Arn": "arn:aws:iam::000000000000:root"
}{
"command": "openssl rand -hex 3",
"description": "Test that openssl is present for the suffix"
}b3e8b5 [stdout] b3e8b5
{
"file_path": "/app/setup.sh",
"content": "#!/usr/bin/env bash\nset -euo pipefail\n\nACCOUNT=000000000000\nREGION=us-east-1\nSUFFIX=$(openssl rand -hex 3)\n\nSOURCE_BUCKET=\"harbor-glue-source-$SUFFIX\"\nTARGET_BUCKET=\"harbor-glue-target-$SUFFIX\"\nSCRIPTS_BUCKET=\"harbor-glue-scripts-$SUFFIX\"\n\nROLE_NAME=harbor-glue-svc-role\nROLE_ARN=\"arn:aws:iam::$ACCOUNT:role/$ROLE_NAME\"\nALIAS=alias/harbor-glue-cmk\nSEC_CONFIG=harbor-glue-sec-config\nDB_NAME=harbor_etl_db\nTABLE_NAME=orders_raw\nJOB_NAME=harbor-orders-etl\n\nWORK=$(mktemp -d)\necho \"[*] suffix=$SUFFIX workdir=$WORK\"\n\n# ---- 1. Glue service role (trust + managed Glue policy) -------------------\ncat > \"$WORK/trust.json\" <<EOF\n{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Principal\": {\"Service\": \"glue.amazonaws.com\"},\n \"Action\": \"sts:AssumeRole\"\n }\n ]\n}\nEOF\n\naws iam create-role \\\n --role-name \"$ROLE_NAME\" \\\n --assume-role-policy-document \"file://$WORK/trust.json\" >/dev/null\n\naws iam attach-role-policy \\\n --role-name \"$ROLE_NAME\" \\\n --policy-arn arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole\n\necho \"[+] role $ROLE_ARN\"\n\n# ---- 2. Customer-managed KMS CMK ------------------------------------------\ncat > \"$WORK/key-policy.json\" <<EOF\n{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"AllowAccountRootAdmin\",\n \"Effect\": \"Allow\",\n \"Principal\": {\"AWS\": \"arn:aws:iam::$ACCOUNT:root\"},\n \"Action\": \"kms:*\",\n \"Resource\": \"*\"\n },\n {\n \"Sid\": \"AllowGlueServiceEnvelope\",\n \"Effect\": \"Allow\",\n \"Principal\": {\"Service\": \"glue.amazonaws.com\"},\n \"Action\": [\n \"kms:Encrypt\",\n \"kms:Decrypt\",\n \"kms:ReEncrypt*\",\n \"kms:GenerateDataKey*\",\n \"kms:DescribeKey\",\n \"kms:CreateGrant\"\n ],\n \"Resource\": \"*\",\n \"Condition\": {\n \"StringEquals\": {\n \"kms:ViaService\": \"glue.$REGION.amazonaws.com\",\n \"aws:SourceAccount\": \"$ACCOUNT\"\n }\n }\n },\n {\n \"Sid\": \"AllowGlueRoleDirectUse\",\n \"Effect\": \"Allow\",\n \"Principal\": {\"AWS\": \"$ROLE_ARN\"},\n \"Action\": [\n \"kms:Encrypt\",\n \"kms:Decrypt\",\n \"kms:ReEncrypt*\",\n \"kms:GenerateDataKey*\",\n \"kms:DescribeKey\"\n ],\n \"Resource\": \"*\",\n \"Condition\": {\n \"StringEquals\": {\n \"aws:SourceAccount\": \"$ACCOUNT\"\n },\n \"StringLike\": {\n \"kms:EncryptionContext:aws:s3:arn\": [\n \"arn:aws:s3:::$SOURCE_BUCKET/*\",\n \"arn:aws:s3:::$TARGET_BUCKET/*\",\n \"arn:aws:s3:::$SCRIPTS_BUCKET/*\"\n ]\n }\n }\n }\n ]\n}\nEOF\n\nKEY_ID=$(aws kms create-key \\\n --description \"Harbor Glue CMK (rotated quarterly)\" \\\n --key-usage ENCRYPT_DECRYPT \\\n --policy \"file://$WORK/key-policy.json\" \\\n --query 'KeyMetadata.KeyId' --output text)\nKEY_ARN=\"arn:aws:kms:$REGION:$ACCOUNT:key/$KEY_ID\"\n\naws kms enable-key-rotation --key-id \"$KEY_ID\" >/dev/null 2>&1 || true\naws kms create-alias --alias-name \"$ALIAS\" --target-key-id \"$KEY_ID\"\n\necho \"[+] CMK $KEY_ARN (alias $ALIAS)\"\n\n# ---- 3. Inline policy on role: KMS scoped to CMK; S3 scoped to 3 buckets --\ncat > \"$WORK/inline.json\" <<EOF\n{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"KMSEnvelopeOnHarborCMKOnly\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"kms:Encrypt\",\n \"kms:Decrypt\",\n \"kms:ReEncrypt*\",\n \"kms:GenerateDataKey*\",\n \"kms:DescribeKey\"\n ],\n \"Resource\": \"$KEY_ARN\"\n },\n {\n \"Sid\": \"S3ScopedToHarborGlueBuckets\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\",\n \"s3:PutObject\",\n
…[truncated]File created successfully at: /app/setup.sh (file state is current in your context , no need to Read it back) …[truncated]
{
"command": "chmod +x /app/setup.sh && /app/setup.sh 2>&1",
"description": "Run setup script"
}[*] suffix=06befd workdir=/tmp/tmp.9XpJWm6NSq [+] role arn:aws:iam::000000000000:role/harbor-glue-svc-role [+] CMK arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816 (alias alias/harbor-glue-cmk) [+] inline policy attached [+] bucket harbor-glue-source-06befd encrypted+policied [+] bucket harbor-glue-target-06befd encrypted+policied [+] bucket harbor-glue-scripts-06befd encrypted+policied [+] etl.py uploaded to s3://harbor-glue-scripts-06befd/etl.py [!] PutDataCatalogEncryptionSettings unsupported -- continuing best-effort: aws: [ERROR]: An error occurred (InternalFailure) when calling the PutDataCatalogEncryptionSettings operation: Sorry, the PutDataCatalogEncryptionSettings operation on the glue service is not currently supported by LocalStack. [+] security-configuration harbor-glue-sec-config [+] database harbor_etl_db [+] table harbor_etl_db.orders_raw [+] job harbor-orders-etl [+] SSM manifest published DONE suffix=06befd cmk=arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816 [stdout] [*] suffix=06befd workdir=/tmp/tmp.9XpJWm6NSq [+] role arn:aws:iam::000000000000:role/harbor-glue-svc-role [+] CMK arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816 (alias alias/harbor-glue-cmk) [+] inline policy attached [+] bucket harbor-glue-source-06befd encrypted+policied [+] bucket harbor-glue-target-06befd encrypted+policied [+] bucket harbor-glue-scripts-06befd encrypted+policied [+] etl.py uploaded to s3://harbor-glue-scripts-06befd/etl.py [!] PutDataCatalogEncryptionSettings unsupported -- continuing best-effort: aws: [ERROR]: An error occurred (InternalFailure) when calling the PutDataCatalogEncryptionSettings operation: Sorry, the PutDataCatalogEncryptionSettings operation on the glue service is not currently supported by LocalStack. [+] security-configuration harbor-glue-sec-config [+] database harbor_etl_db [+] table harbor_etl_db.orders_raw [+] job harbor-orders-etl [+] SSM manifest published DONE suffix=06befd cmk=arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816
{
"command": "set -e\necho \"=== KMS alias ===\"\naws kms list-aliases --query \"Aliases[?AliasName=='alias/harbor-glue-cmk'].[AliasName,TargetKeyId]\" --output table\n\necho \"=== KMS key policy (default) ===\"\nKEY_ID=$(aws kms describe-key --key-id alias/harbor-glue-cmk --query KeyMetadata.KeyId --output text)\naws kms get-key-policy --key-id \"$KEY_ID\" --policy-name default --output text | head -100\n\necho \"=== Role ===\"\naws iam get-role --role-name harbor-glue-svc-role --query 'Role.[RoleName,Arn]' --output table\naws iam list-attached-role-policies --role-name harbor-glue-svc-role --output table\naws iam list-role-policies --role-name harbor-glue-svc-role --output table",
"description": "Verify KMS + IAM"
}=== KMS alias ===
-------------------------------------------------------------------
| ListAliases |
+------------------------+----------------------------------------+
| alias/harbor-glue-cmk | 5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816 |
+------------------------+----------------------------------------+
=== KMS key policy (default) ===
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAccountRootAdmin",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::000000000000:root"},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "AllowGlueServiceEnvelope",
"Effect": "Allow",
"Principal": {"Service": "glue.amazonaws.com"},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey",
"kms:CreateGrant"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:ViaService": "glue.us-east-1.amazonaws.com",
"aws:SourceAccount": "000000000000"
}
}
},
{
"Sid": "AllowGlueRoleDirectUse",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::000000000000:role/harbor-glue-svc-role"},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "000000000000"
},
"StringLike": {
"kms:EncryptionContext:aws:s3:arn": [
"arn:aws:s3:::harbor-glue-source-06befd/*",
"arn:aws:s3:::harbor-glue-target-06befd/*",
"arn:aws:s3:::harbor-glue-scripts-06befd/*"
]
}
}
}
]
}
=== Role ===
---------------------------------------------------------
| GetRole |
+-------------------------------------------------------+
| harbor-glue-svc-role |
| arn:aws:iam::000000000000:role/harbor-glue-svc-role |
+-------------------------------------------------------+
-----------------------------------------------------------------------------
| ListAttachedRolePolicies |
+---------------------------------------------------------------------------+
|| AttachedPolicies ||
|+------------+------------------------------------------------------------+|
|| PolicyArn | arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole ||
|| PolicyName| AWSGlueServiceRole ||
|+------------+------------------------------------------------------------+|
--------------------------
| ListRolePolicies |
+------------------------+
|| PolicyNames ||
|+----------------------+|
|| harbor-glue-inline ||
|+----------------------+|
[stdout]
=== KMS alias ===
-------------------------------------------------------------------
| ListAliases |
+------------------------+----------------------------------------+
| alias/harbor-glue-cmk | 5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816 |
+------------------------+----------------------------------------+
=== KMS key policy (default) ===
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAccountRootAdmin",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::000000000000:root"},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "AllowGlueServiceEnvelope",
"Effect": "Allow",
"Principal": {"Service": "glue.amazonaws.com"},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey",
"kms:CreateGrant"
],
"Resource": "*",
"C
…[truncated]{
"command": "set -e\necho \"=== S3 buckets ===\"\naws s3api list-buckets --query \"Buckets[?starts_with(Name,'harbor-glue-')].Name\" --output table\n\necho \"=== Default encryption per bucket ===\"\nfor B in $(aws s3api list-buckets --query \"Buckets[?starts_with(Name,'harbor-glue-')].Name\" --output text); do\n echo \"--- $B ---\"\n aws s3api get-bucket-encryption --bucket \"$B\" --query 'ServerSideEncryptionConfiguration.Rules[0].ApplyServerSideEncryptionByDefault'\ndone\n\necho \"=== Bucket policy on source bucket ===\"\nSRC=$(aws ssm get-parameter --name /harbor/glue/source-bucket --query Parameter.Value --output text)\naws s3api get-bucket-policy --bucket \"$SRC\" --query Policy --output text | head -80\n\necho \"=== etl.py present in scripts bucket ===\"\nSCR=$(aws ssm get-parameter --name /harbor/glue/scripts-bucket --query Parameter.Value --output text)\naws s3api list-objects-v2 --bucket \"$SCR\" --query 'Contents[].Key' --output table",
"description": "Verify S3 buckets and policies"
}=== S3 buckets ===
--------------------------------
| ListBuckets |
+------------------------------+
| harbor-glue-scripts-06befd |
| harbor-glue-source-06befd |
| harbor-glue-target-06befd |
+------------------------------+
=== Default encryption per bucket ===
--- harbor-glue-scripts-06befd ---
{
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
}
--- harbor-glue-source-06befd ---
{
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
}
--- harbor-glue-target-06befd ---
{
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
}
=== Bucket policy on source bucket ===
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::harbor-glue-source-06befd",
"arn:aws:s3:::harbor-glue-source-06befd/*"
],
"Condition": {
"Bool": {"aws:SecureTransport": "false"}
}
},
{
"Sid": "DenyPutObjectWithoutSSEHeader",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::harbor-glue-source-06befd/*",
"Condition": {
"Null": {"s3:x-amz-server-side-encryption": "true"}
}
},
{
"Sid": "DenyPutObjectWithWrongSSEAlgorithm",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::harbor-glue-source-06befd/*",
"Condition": {
"StringNotEquals": {"s3:x-amz-server-side-encryption": "aws:kms"}
}
},
{
"Sid": "DenyPutObjectWithoutKMSKey",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::harbor-glue-source-06befd/*",
"Condition": {
"Null": {"s3:x-amz-server-side-encryption-aws-kms-key-id": "true"}
}
},
{
"Sid": "DenyPutObjectWithWrongKMSKey",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::harbor-glue-source-06befd/*",
"Condition": {
"StringNotEquals": {"s3:x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"}
}
}
]
}
=== etl.py present in scripts bucket ===
---------------
|ListObjectsV2|
+-------------+
| etl.py |
+-------------+
[stdout]
=== S3 buckets ===
--------------------------------
| ListBuckets |
+------------------------------+
| harbor-glue-scripts-06befd |
| harbor-glue-source-06befd |
| harbor-glue-target-06befd |
+------------------------------+
=== Default encryption per bucket ===
--- harbor-glue-scripts-06befd ---
{
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
}
--- harbor-glue-source-06befd ---
{
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
}
--- harbor-glue-target-06befd ---
{
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
}
=== Bucket policy on source bucket ===
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::harbor-glue-source-06befd",
"arn:aws:s3:::harbor-glue-source-06befd/*"
],
"Condition": {
"Bool": {"aws:SecureTransport": "false"}
}
},
{
"Sid": "DenyPutObjectWithoutSSEHeader",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "a
…[truncated]{
"command": "set -e\necho \"=== Glue Security Configuration ===\"\naws glue get-security-configuration --name harbor-glue-sec-config --query 'SecurityConfiguration.EncryptionConfiguration'\n\necho \"=== Glue Database ===\"\naws glue get-database --name harbor_etl_db --query 'Database.[Name,Description]' --output table\n\necho \"=== Glue Table schema ===\"\naws glue get-table --database-name harbor_etl_db --name orders_raw \\\n --query 'Table.[Name,TableType,StorageDescriptor.Location]' --output table\naws glue get-table --database-name harbor_etl_db --name orders_raw \\\n --query 'Table.StorageDescriptor.Columns' --output table\n\necho \"=== Glue Job ===\"\naws glue get-job --job-name harbor-orders-etl \\\n --query 'Job.[Name,Role,GlueVersion,SecurityConfiguration,MaxRetries,Command]'\n\necho \"=== Glue Job DefaultArguments ===\"\naws glue get-job --job-name harbor-orders-etl --query 'Job.DefaultArguments'",
"description": "Verify Glue catalog and job"
}=== Glue Security Configuration ===
{
"S3Encryption": [
{
"S3EncryptionMode": "SSE-KMS",
"KmsKeyArn": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
}
],
"CloudWatchEncryption": {
"CloudWatchEncryptionMode": "SSE-KMS",
"KmsKeyArn": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
},
"JobBookmarksEncryption": {
"JobBookmarksEncryptionMode": "CSE-KMS",
"KmsKeyArn": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
}
}
=== Glue Database ===
-----------------------------
| GetDatabase |
+---------------------------+
| harbor_etl_db |
| Harbor ETL data catalog |
+---------------------------+
=== Glue Table schema ===
------------------------------------------------
| GetTable |
+----------------------------------------------+
| orders_raw |
| EXTERNAL_TABLE |
| s3://harbor-glue-source-06befd/orders_raw/ |
+----------------------------------------------+
------------------------------
| GetTable |
+--------------+-------------+
| Name | Type |
+--------------+-------------+
| order_id | string |
| customer_id | string |
| amount | double |
| ts | timestamp |
+--------------+-------------+
=== Glue Job ===
[
"harbor-orders-etl",
"arn:aws:iam::000000000000:role/harbor-glue-svc-role",
"4.0",
"harbor-glue-sec-config",
1,
{
"Name": "glueetl",
"ScriptLocation": "s3://harbor-glue-scripts-06befd/etl.py",
"PythonVersion": "3"
}
]
=== Glue Job DefaultArguments ===
{
"--job-bookmark-option": "job-bookmark-enable",
"--enable-glue-datacatalog": "true",
"--enable-metrics": "true",
"--enable-continuous-cloudwatch-log": "true",
"--TempDir": "s3://harbor-glue-target-06befd/_tmp/"
}
[stdout]
=== Glue Security Configuration ===
{
"S3Encryption": [
{
"S3EncryptionMode": "SSE-KMS",
"KmsKeyArn": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
}
],
"CloudWatchEncryption": {
"CloudWatchEncryptionMode": "SSE-KMS",
"KmsKeyArn": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
},
"JobBookmarksEncryption": {
"JobBookmarksEncryptionMode": "CSE-KMS",
"KmsKeyArn": "arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816"
}
}
=== Glue Database ===
-----------------------------
| GetDatabase |
+---------------------------+
| harbor_etl_db |
| Harbor ETL data catalog |
+---------------------------+
=== Glue Table schema ===
------------------------------------------------
| GetTable |
+----------------------------------------------+
| orders_raw |
| EXTERNAL_TABLE |
| s3://harbor-glue-source-06befd/orders_raw/ |
+----------------------------------------------+
------------------------------
| GetTable |
+--------------+-------------+
| Name | Type |
+--------------+-------------+
| order_id | string |
| customer_id | string |
| amount | double |
| ts | timestamp |
+--------------+-------------+
=== Glue Job ===
[
"harbor-orders-etl",
"arn:aws:iam::000000000000:role/harbor-glue-svc-role",
"4.0",
"harbor-glue-sec-config",
1,
{
"Name": "glueetl",
"ScriptLocation": "s3://harbor-glue-scripts-06befd/etl.py",
"PythonVersion": "3"
}
]
=== Glue Job DefaultArguments ===
{
"--job-bookmark-option": "job-bookmark-enable",
"--enable-glue-datacatalog": "true",
"--enable-metrics": "true",
"--enabl
…[truncated]{
"command": "echo \"=== SSM manifest ===\"\naws ssm get-parameters-by-path --path /harbor/glue/ --recursive \\\n --query 'Parameters[].[Name,Value]' --output table",
"description": "Verify SSM manifest"
}=== SSM manifest === ------------------------------------------------------------------------------------------------------------------------------- | GetParametersByPath | +---------------------------------------------+-------------------------------------------------------------------------------+ | /harbor/glue/cmk-arn | arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816 | | /harbor/glue/sec-config | harbor-glue-sec-config | | /harbor/glue/database | harbor_etl_db | | /harbor/glue/table | orders_raw | | /harbor/glue/job-name | harbor-orders-etl | | /harbor/glue/svc-role-arn | arn:aws:iam::000000000000:role/harbor-glue-svc-role | | /harbor/glue/source-bucket | harbor-glue-source-06befd | | /harbor/glue/target-bucket | harbor-glue-target-06befd | | /harbor/glue/scripts-bucket | harbor-glue-scripts-06befd | | /harbor/glue/catalog-encryption-mode | SSE-KMS | | /harbor/glue/catalog-cmk-id | arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816 | | /harbor/glue/connection-password-encrypted | true | +---------------------------------------------+-------------------------------------------------------------------------------+ [stdout] === SSM manifest === ------------------------------------------------------------------------------------------------------------------------------- | GetParametersByPath | +---------------------------------------------+-------------------------------------------------------------------------------+ | /harbor/glue/cmk-arn | arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816 | | /harbor/glue/sec-config | harbor-glue-sec-config | | /harbor/glue/database | harbor_etl_db | | /harbor/glue/table | orders_raw | | /harbor/glue/job-name | harbor-orders-etl | | /harbor/glue/svc-role-arn | arn:aws:iam::000000000000:role/harbor-glue-svc-role | | /harbor/glue/source-bucket | harbor-glue-source-06befd | | /harbor/glue/target-bucket | harbor-glue-target-06befd | | /harbor/glue/scripts-bucket | harbor-glue-scripts-06befd | | /harbor/glue/catalog-encryption-mode | SSE-KMS | | /harbor/glue/catalog-cmk-id | arn:aws:kms:us-east-1:000000000000:key/5f6a2c2f-c3cc-416d-ad57-c0b5f4bdd816 | | /harbor/glue/connection-password-encrypted | true …[truncated]
No 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 134ms
============================= test session starts ==============================
platform linux -- Python 3.12.3, pytest-8.4.1, pluggy-1.6.0 -- /root/.cache/uv/archive-v0/b9Aa3DeTj8ASHGKM06vys/bin/python
cachedir: .pytest_cache
rootdir: /tests
plugins: json-ctrf-0.3.5
collecting ... collected 87 items
../tests/test_outputs.py::test_01_kms_alias_resolves_to_real_customer_key PASSED [ 1%]
../tests/test_outputs.py::test_02_glue_security_configuration_exists_with_correct_name PASSED [ 2%]
../tests/test_outputs.py::test_03_glue_database_exists_with_correct_name PASSED [ 3%]
../tests/test_outputs.py::test_04_glue_table_exists_in_database_with_correct_name PASSED [ 4%]
../tests/test_outputs.py::test_05_glue_etl_job_exists_with_correct_name PASSED [ 5%]
../tests/test_outputs.py::test_06_glue_service_role_exists_with_correct_name PASSED [ 6%]
../tests/test_outputs.py::test_07_three_buckets_exist_via_ssm_pointers PASSED [ 8%]
../tests/test_outputs.py::test_08_three_buckets_share_a_single_hex_suffix PASSED [ 9%]
../tests/test_outputs.py::test_09_scripts_bucket_holds_etl_py PASSED [ 10%]
../tests/test_outputs.py::test_10_cmk_policy_has_root_admin_statement PASSED [ 11%]
../tests/test_outputs.py::test_11_cmk_policy_admits_glue_service_principal PASSED [ 12%]
../tests/test_outputs.py::test_12_cmk_policy_glue_service_has_envelope_verbs PASSED [ 13%]
../tests/test_outputs.py::test_13_cmk_policy_admits_glue_role_principal PASSED [ 14%]
../tests/test_outputs.py::test_14_cmk_policy_role_principal_has_envelope_verbs PASSED [ 16%]
../tests/test_outputs.py::test_15_cmk_policy_no_principal_star_leak PASSED [ 17%]
../tests/test_outputs.py::test_16_cmk_policy_resource_field_is_star PASSED [ 18%]
../tests/test_outputs.py::test_17_sec_config_s3_encryption_is_a_list PASSED [ 19%]
../tests/test_outputs.py::test_18_sec_config_s3_mode_is_sse_kms_enum PASSED [ 20%]
../tests/test_outputs.py::test_19_sec_config_s3_kms_key_arn_matches_cmk PASSED [ 21%]
../tests/test_outputs.py::test_20_sec_config_cw_mode_is_sse_kms_enum PASSED [ 22%]
../tests/test_outputs.py::test_21_sec_config_cw_kms_key_arn_matches_cmk PASSED [ 24%]
../tests/test_outputs.py::test_22_sec_config_bookmark_mode_is_cse_kms_not_sse_kms PASSED [ 25%]
../tests/test_outputs.py::test_23_sec_config_bookmark_kms_key_arn_matches_cmk PASSED [ 26%]
../tests/test_outputs.py::test_24_sec_config_all_three_modes_use_same_cmk_canonically PASSED [ 27%]
../tests/test_outputs.py::test_25_catalog_encryption_mode_sse_kms PASSED [ 28%]
../tests/test_outputs.py::test_26_catalog_encryption_uses_correct_cmk PASSED [ 29%]
../tests/test_outputs.py::test_27_catalog_connection_password_encryption_enabled PASSED [ 31%]
../tests/test_outputs.py::test_28_catalog_connection_password_uses_cmk_when_api_returns PASSED [ 32%]
../tests/test_outputs.py::test_29_source_bucket_default_sse_kms_uses_cmk PASSED [ 33%]
../tests/test_outputs.py::test_30_target_bucket_default_sse_kms_uses_cmk PASSED [ 34%]
../tests/test_outputs.py::test_31_scripts_bucket_default_sse_kms_uses_cmk PASSED [ 35%]
../tests/test_outputs.py::test_32_no_bucket_falls_back_to_aes256 PASSED [ 36%]
../tests/test_outputs.py::test_33_role_trust_admits_only_glue_service PASSED [ 37%]
../tests/test_outputs.py::test_34_role_trust_action_is_sts_assume_role PASSED [ 39%]
../tests/test_outputs.py::test_35_role_has_aws_glue_service_role_attached PASSED [ 40%]
../tests/test_outputs.py::test_36_role_inline_grants_kms_generate_data_key PASSED [ 41%]
../tests/test_outputs.py::test_37_role_inline_grants_kms_decrypt PASSED [ 42%]
../tests/test_outputs.py::test_38_role_inline_kms_grant_is_scoped_to_cmk_arn PASSED [ 43%]
../tests/test_outputs.py::test_39_role_inline_s3_grant_is_scoped_to_three_buckets PASSED [ 44%]
../tests/test_outputs.py::test_40_role_inline_no_wildcard_action_action_star PASSED [ 45%]
../tests/test_outputs.py::test_41_cmk_in_inline_policy_matches_cmk_in_key_policy PASSED [ 47%]
../tests/test_outputs.py::test_42_inline_kms_resources_only_reference_one_distinct_key PASSED [ 48%]
../tests/test_outputs.py::test_43_etl_job_security_configuration_binding PASSED [ 49%]
../tests/test_outputs.py::test_44_etl_job_role_arn_matches_svc_role PASSED [ 50%]
../tests/test_outputs.py::test_45_etl_job_glue_version_is_modern PASSED [ 51%]
../tests/test_outputs.py::test_46_etl_job_command_is_glueetl_python_3 PASSED [ 52%]
../tests/test_outputs.py::test_47_etl_job_default_args_enable_bookmark PASSED [ 54%]
../tests/test_outputs.py::test_48_etl_job_default_args_enable_glue_datacatalog PASSED [ 55%]
../tests/test_outputs.py::test_49_etl_job_max_retries_bounded PASSED [ 56%]
../tests/test_outputs.py::test_50_etl_job_script_location_is_etl_py_in_scripts_bucket PASSED [ 57%]
../tests/test_outputs.py::test_51_glue_table_location_is_in_source_bucket PASSED [ 58%]
../tests/test_outputs.py::test_52_glue_table_has_columns_schema PASSED [ 59%]
../tests/test_outputs.py::test_53_glue_table_is_external_table PASSED [ 60%]
../tests/test_outputs.py::test_54_all_twelve_ssm_pointers_resolve_non_empty PASSED [ 62%]
../tests/test_outputs.py::test_55_ssm_cmk_arn_format_and_cross_check PASSED [ 63%]
../tests/test_outputs.py::test_56_ssm_svc_role_arn_format_and_cross_check PASSED [ 64%]
../tests/test_outputs.py::test_57_ssm_pointers_match_resource_names PASSED [ 65%]
../tests/test_outputs.py::test_58_ssm_catalog_cmk_matches_cmk_arn_pointer PASSED [ 66%]
../tests/test_outputs.py::test_59_no_inline_statement_grants_kms_star_on_resource_star PASSED [ 67%]
../tests/test_outputs.py::test_60_no_inline_statement_grants_s3_star_on_resource_star PASSED [ 68%]
../tests/test_outputs.py::test_61_no_bucket_uses_aws_managed_alias PASSED [ 70%]
../tests/test_outputs.py::test_62_sec_config_no_mode_is_disabled PASSED [ 71%]
../tests/test_outputs.py::test_63_no_attached_policy_is_aws_administrator PASSED [ 72%]
../tests/test_outputs.py::test_64_etl_job_no_disable_metrics PASSED [ 73%]
../tests/test_outputs.py::test_65_one_cmk_id_threads_through_every_surface PASSED [ 74%]
../tests/test_outputs.py::test_66_cmk_glue_service_statement_is_account_scoped PASSED [ 75%]
../tests/test_outputs.py::test_67_cmk_glue_service_statement_pinned_via_service_AND_source_account PASSED [ 77%]
../tests/test_outputs.py::test_68_catalog_encryption_round_trips_when_api_returns PASSED [ 78%]
../tests/test_outputs.py::test_69_bucket_policies_deny_non_tls PASSED [ 79%]
../tests/test_outputs.py::test_70_bucket_policies_deny_non_cmk_puts PASSED [ 80%]
../tests/test_outputs.py::test_71_database_location_uri_points_to_source_bucket PASSED [ 81%]
../tests/test_outputs.py::test_72_etl_job_timeout_is_bounded FAILED [ 82%]
../tests/test_outputs.py::test_73_etl_job_worker_type_is_named PASSED [ 83%]
../tests/test_outputs.py::test_74_etl_job_start_job_run_is_accepted_at_api_layer PASSED [ 85%]
../tests/test_outputs.py::test_75_keypolicy_role_principal_has_encryption_context_binding_to_our_buckets PASSED [ 86%]
../tests/test_outputs.py::test_76_start_job_run_then_get_job_run_state_progresses PASSED [ 87%]
../tests/test_outputs.py::test_77_bucket_policy_shape_blocks_wrong_kms_key_put PASSED [ 88%]
../tests/test_outputs.py::test_78_cmk_can_encrypt_and_decrypt_round_trip PASSED [ 89%]
../tests/test_outputs.py::test_79_get_job_default_arguments_round_trip_exactly PASSED [ 90%]
../tests/test_outputs.py::test_80_bucket_policy_denies_non_tls_request_simulated PASSED [ 91%]
../tests/test_outputs.py::test_81_no_role_inline_kms_or_s3_resource_uses_star PASSED [ 93%]
../tests/test_outputs.py::test_82_no_role_inline_or_keypolicy_uses_aws_star_principal PASSED [ 94%]
../tests/test_outputs.py::test_83_no_attached_role_policy_includes_admin_or_full_access PASSED [ 95%]
../tests/test_outputs.py::test_84_ssm_values_are_not_placeholder_strings PASSED [ 96%]
../tests/test_outputs.py::test_85_one_cmk_id_threads_through_eight_or_more_surfaces_strict PASSED [ 97%]
../tests/test_outputs.py::test_86_keypolicy_role_principal_statement_pinned_to_caller_account PASSED [ 98%]
../tests/test_outputs.py::test_87_keypolicy_no_resource_field_other_than_star PASSED [100%]
=================================== FAILURES ===================================
______________________ test_72_etl_job_timeout_is_bounded ______________________
def test_72_etl_job_timeout_is_bounded():
"""Job Timeout is set and bounded (<=480 minutes / 8h). Unbounded timeouts let a stuck job
chew through compute indefinitely; the audit wants explicit upper bounds on every retry/timeout
surface the job exposes."""
j = _job()
t = j.get("Timeout")
assert t is not None, "job Timeout unset"
> assert isinstance(t, int) and 1 <= t <= 480, (
f"job Timeout={t!r}; expected an int in [1,480] minutes"
)
E AssertionError: job Timeout=2880; expected an int in [1,480] minutes
E assert (True and 2880 <= 480)
E + where True = isinstance(2880, int)
/tests/test_outputs.py:1479: AssertionError
=============================== warnings summary ===============================
test_outputs.py: 263 warnings
/root/.cache/uv/archive-v0/b9Aa3DeTj8ASHGKM06vys/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_kms_alias_resolves_to_real_customer_key
PASSED ../tests/test_outputs.py::test_02_glue_security_configuration_exists_with_correct_name
PASSED ../tests/test_outputs.py::test_03_glue_database_exists_with_correct_name
PASSED ../tests/test_outputs.py::test_04_glue_table_exists_in_database_with_correct_name
PASSED ../tests/test_outputs.py::test_05_glue_etl_job_exists_with_correct_name
PASSED ../tests/test_outputs.py::test_06_glue_service_role_exists_with_correct_name
PASSED ../tests/test_outputs.py::test_07_three_buckets_exist_via_ssm_pointers
PASSED ../tests/test_outputs.py::test_08_three_buckets_share_a_single_hex_suffix
PASSED ../tests/test_outputs.py::test_09_scripts_bucket_holds_etl_py
PASSED ../tests/test_outputs.py::test_10_cmk_policy_has_root_admin_statement
PASSED ../tests/test_outputs.py::test_11_cmk_policy_admits_glue_service_principal
PASSED ../tests/test_outputs.py::test_12_cmk_policy_glue_service_has_envelope_verbs
PASSED ../tests/test_outputs.py::test_13_cmk_policy_admits_glue_role_principal
PASSED ../tests/test_outputs.py::test_14_cmk_policy_role_principal_has_envelope_verbs
PASSED ../tests/test_outputs.py::test_15_cmk_policy_no_principal_star_leak
PASSED ../tests/test_outputs.py::test_16_cmk_policy_resource_field_is_star
PASSED ../tests/test_outputs.py::test_17_sec_config_s3_encryption_is_a_list
PASSED ../tests/test_outputs.py::test_18_sec_config_s3_mode_is_sse_kms_enum
PASSED ../tests/test_outputs.py::test_19_sec_config_s3_kms_key_arn_matches_cmk
PASSED ../tests/test_outputs.py::test_20_sec_config_cw_mode_is_sse_kms_enum
PASSED ../tests/test_outputs.py::test_21_sec_config_cw_kms_key_arn_matches_cmk
PASSED ../tests/test_outputs.py::test_22_sec_config_bookmark_mode_is_cse_kms_not_sse_kms
PASSED ../tests/test_outputs.py::test_23_sec_config_bookmark_kms_key_arn_matches_cmk
PASSED ../tests/test_outputs.py::test_24_sec_config_all_three_modes_use_same_cmk_canonically
PASSED ../tests/test_outputs.py::test_25_catalog_encryption_mode_sse_kms
PASSED ../tests/test_outputs.py::test_26_catalog_encryption_uses_correct_cmk
PASSED ../tests/test_outputs.py::test_27
… (truncated at 12,000 chars, full verifier log is in the trial artifacts)Reproduce this trial: git checkout 2f94510 && PYTHONPATH=src python3 scripts/build_site.py , then open trial/trial_16ea3a3ecbfd4447. Re-running the agent live requires EVAL_PLATFORM_ENABLE_OAUTH_SMOKE=1 and is non-deterministic.
Trial trial_16ea3a3ecbfd4447 · verifier authoritative; classifier explanatory.