#!/usr/bin/env bash set -euo pipefail # Contract tests for production handoff controls. Network calls are replaced by # a narrow aws stub so we test fail-closed command construction without cloud credentials. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../scripts/bash/casan-paths.sh" SHIP="$CASAN_HARNESS_ROOT/scripts/bash/audit-ship-s3.sh" WORK="$(mktemp -d)"; trap 'rm -rf "$WORK"' EXIT PASS=0; FAIL=0 pass() { echo "PASS: $1"; PASS=$((PASS+1)); } fail() { echo "FAIL: $1"; FAIL=$((FAIL+1)); } rc() { set +e; "$@" >/dev/null 2>&1; local code=$?; set -e; echo "$code"; } mkdir -p "$WORK/bin" cat > "$WORK/bin/aws" <<'AWS' #!/usr/bin/env bash set -euo pipefail printf '%s\n' "$*" >> "${AWS_LOG:?}" if [[ "$1 $2" == "s3api get-object-lock-configuration" ]]; then printf '%s\n' '{"ObjectLockConfiguration":{"ObjectLockEnabled":"Enabled","Rule":{"DefaultRetention":{"Mode":"COMPLIANCE","Days":365}}}}' fi if [[ "$1 $2" == "s3api head-object" ]]; then exit 1 fi AWS chmod +x "$WORK/bin/aws" printf '%064d\n' 0 > "$WORK/head.txt" AWS_LOG="$WORK/aws.log" PATH="$WORK/bin:$PATH" CASAN_PROFILE=prod \ CASAN_S3_BUCKET=casan-production-audit CASAN_S3_REGION=ap-northeast-1 \ CASAN_S3_RETENTION_DAYS=365 CASAN_S3_KMS_KEY_ID=alias/casan-audit bash "$SHIP" "$WORK/head.txt" >/dev/null 2>&1 \ && grep -q -- '--object-lock-mode COMPLIANCE' "$WORK/aws.log" \ && grep -q -- '--server-side-encryption aws:kms' "$WORK/aws.log" \ && grep -q -- '--ssekms-key-id alias/casan-audit' "$WORK/aws.log" \ && pass "S3 anchor uses COMPLIANCE Object Lock and SSE-KMS" || fail "S3 anchor missing immutable controls" [[ "$(rc env PATH="$WORK/bin:$PATH" CASAN_PROFILE=dev CASAN_S3_BUCKET=casan-production-audit CASAN_S3_REGION=ap-northeast-1 CASAN_S3_KMS_KEY_ID=alias/casan-audit bash "$SHIP" "$WORK/head.txt")" -ne 0 ]] \ && pass "non-production profile is refused" || fail "non-production profile accepted" cat > "$WORK/bin/aws" <<'AWS' #!/usr/bin/env bash if [[ "$1 $2" == "s3api get-object-lock-configuration" ]]; then printf '%s\n' '{"ObjectLockConfiguration":{"ObjectLockEnabled":"Disabled","Rule":{"DefaultRetention":{"Mode":"COMPLIANCE","Days":365}}}}' fi AWS chmod +x "$WORK/bin/aws" [[ "$(rc env PATH="$WORK/bin:$PATH" CASAN_PROFILE=prod CASAN_S3_BUCKET=casan-production-audit CASAN_S3_REGION=ap-northeast-1 CASAN_S3_KMS_KEY_ID=alias/casan-audit bash "$SHIP" "$WORK/head.txt")" -ne 0 ]] \ && pass "bucket without Object Lock is refused" || fail "Object-Lock-free bucket accepted" printf 'not-a-digest\n' > "$WORK/bad-head.txt" [[ "$(rc env PATH="$WORK/bin:$PATH" CASAN_PROFILE=prod CASAN_S3_BUCKET=casan-production-audit CASAN_S3_REGION=ap-northeast-1 CASAN_S3_KMS_KEY_ID=alias/casan-audit bash "$SHIP" "$WORK/bad-head.txt")" -ne 0 ]] \ && pass "malformed audit head is refused" || fail "malformed audit head accepted" echo "===== PRODUCTION HANDOFF SUMMARY: PASS=$PASS FAIL=$FAIL =====" [[ "$FAIL" -eq 0 ]]