{"id":"s3-generate-presigned-url","version":"1.0.0","primitive":"code_execution","description":"AWS region","registry_refs":["boto3"],"tags":[],"solves":[],"auth_required":true,"verified":false,"last_verified":"null","next_check":"2026-07-30","eval_result":"null","eval_env":"null","mast":[],"ref":"https://arxiv.org/abs/2503.13657","inputs":[{"name":"AWS_ACCESS_KEY_ID","required":true,"description":"AWS access key ID"},{"name":"AWS_SECRET_ACCESS_KEY","required":true,"description":"AWS secret access key"},{"name":"S3_BUCKET","required":true,"description":"S3 bucket name"},{"name":"AWS_REGION","default":"us-east-1","required":false,"description":"AWS region"}],"executable":"# ============================================\n# checklist:     s3-generate-presigned-url\n# version:       1.0.0\n# primitive:     code_execution\n# description:   Generate a presigned URL for S3 GET and PUT operations and verify the URL works without AWS credentials\n# registry_refs: boto3\n# auth_required: true\n# verified:      false\n# last_verified: null\n# next_check:    2026-07-30\n# eval_result:   null\n# eval_env:      null\n#\n# inputs:\n#   - name: AWS_ACCESS_KEY_ID\n#     required: true\n#     description: AWS access key ID\n#   - name: AWS_SECRET_ACCESS_KEY\n#     required: true\n#     description: AWS secret access key\n#   - name: S3_BUCKET\n#     required: true\n#     description: S3 bucket name\n#   - name: AWS_REGION\n#     required: false\n#     default: \"us-east-1\"\n#     description: AWS region\n#\n# OUTPUTS:\n#   get_url_ok    — true if presigned GET URL returned correct content\n#   put_url_ok    — true if presigned PUT URL successfully uploaded\n#   expiry_seconds — configured URL expiry\n#\n# MAST FAILURE MODES ADDRESSED:\n# FM-1.1 Disobey Task Specification        — region must match bucket or URL signing fails\n# FM-3.3 Incorrect Verification            — URL actually fetched without credentials to verify\n#\n# ref: https://arxiv.org/abs/2503.13657\n# ============================================\n\nimport sys\nimport os\nimport subprocess\nimport time\nimport urllib.request\nimport json\n\n# ─────────────────────────────────────────\n# PRE_EXECUTION\n# ─────────────────────────────────────────\n\nfor attempt in range(2):\n    try:\n        req = urllib.request.Request(\n            \"https://checklist.day/api/registry/boto3\",\n            headers={\"User-Agent\": \"checklist-agent/1.0\"}\n        )\n        with urllib.request.urlopen(req, timeout=10) as resp:\n            registry = json.loads(resp.read())\n            break\n    except Exception as e:\n        if attempt == 1:\n            print(f\"ABORT: registry unreachable — {e}\")\n            sys.exit(1)\n        time.sleep(2)\n\nwarnings = registry.get(\"warnings\", [])\nif warnings:\n    print(\"[boto3] WARNINGS:\")\n    for w in warnings if isinstance(warnings, list) else [warnings]:\n        print(f\"  ⚠ {w}\")\n\n# ─────────────────────────────────────────\n# EXECUTION\n# ─────────────────────────────────────────\n\nsubprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"-q\", \"boto3>=1.26.0\"])\n\nimport boto3\n\nAWS_ACCESS_KEY_ID     = os.environ.get(\"AWS_ACCESS_KEY_ID\")\nAWS_SECRET_ACCESS_KEY = os.environ.get(\"AWS_SECRET_ACCESS_KEY\")\nAWS_REGION            = os.environ.get(\"AWS_REGION\", \"us-east-1\")\nS3_BUCKET             = os.environ.get(\"S3_BUCKET\")\n\nif not AWS_ACCESS_KEY_ID:\n    print(\"ABORT: AWS_ACCESS_KEY_ID not set\"); sys.exit(1)\nif not AWS_SECRET_ACCESS_KEY:\n    print(\"ABORT: AWS_SECRET_ACCESS_KEY not set\"); sys.exit(1)\nif not S3_BUCKET:\n    print(\"ABORT: S3_BUCKET not set\"); sys.exit(1)\n\nKEY            = \"checklist-test/presigned-test.txt\"\nCONTENT        = b\"presigned url test content\"\nEXPIRY_SECONDS = 300\n\n# FOOTGUN: client must use same region as bucket — mismatched region causes SignatureDoesNotMatch\nclient = boto3.client(\n    \"s3\",\n    aws_access_key_id=AWS_ACCESS_KEY_ID,\n    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,\n    region_name=AWS_REGION,\n)\n\n# Setup: upload object for GET test\nclient.put_object(Bucket=S3_BUCKET, Key=KEY, Body=CONTENT)\n\ntry:\n    # 1. Presigned GET URL\n    get_url = client.generate_presigned_url(\n        \"get_object\",\n        Params={\"Bucket\": S3_BUCKET, \"Key\": KEY},\n        ExpiresIn=EXPIRY_SECONDS,\n    )\n    print(f\"  presigned GET URL generated (expires in {EXPIRY_SECONDS}s)\")\n\n    # Verify: fetch without AWS credentials\n    req = urllib.request.Request(get_url)\n    with urllib.request.urlopen(req, timeout=10) as resp:\n        fetched = resp.read()\n    get_url_ok = fetched == CONTENT\n    print(f\"  GET URL verified: {len(fetched)} bytes (match={get_url_ok})\")\n\n    # 2. Presigned PUT URL\n    put_key = \"checklist-test/presigned-put-test.txt\"\n    put_url = client.generate_presigned_url(\n        \"put_object\",\n        Params={\"Bucket\": S3_BUCKET, \"Key\": put_key, \"ContentType\": \"text/plain\"},\n        ExpiresIn=EXPIRY_SECONDS,\n    )\n    print(f\"  presigned PUT URL generated\")\n\n    # Upload via presigned URL without SDK\n    put_req = urllib.request.Request(\n        put_url,\n        data=CONTENT,\n        method=\"PUT\",\n        headers={\"Content-Type\": \"text/plain\"},\n    )\n    with urllib.request.urlopen(put_req, timeout=10) as resp:\n        put_status = resp.status\n\n    put_url_ok = put_status == 200\n    print(f\"  PUT URL upload: status={put_status} ok={put_url_ok}\")\n\n    # Cleanup\n    client.delete_object(Bucket=S3_BUCKET, Key=KEY)\n    client.delete_object(Bucket=S3_BUCKET, Key=put_key)\n\nfinally:\n    pass\n\n# ─────────────────────────────────────────\n# POST_EXECUTION\n# ─────────────────────────────────────────\n\nassert get_url_ok, \"FAIL: presigned GET URL did not return expected content\"\nassert put_url_ok, f\"FAIL: presigned PUT URL returned status {put_status}\"\n\nresult = {\n    \"get_url_ok\":     get_url_ok,\n    \"put_url_ok\":     put_url_ok,\n    \"expiry_seconds\": EXPIRY_SECONDS,\n}\nprint(json.dumps(result, indent=2))\nprint(\"PASS\")\n"}