# AWS S3 버킷 정책 작성하기: HTTP 요청을 거부하는 aws:SecureTransport 조건

> S3 버킷 정책 편집기에 aws:SecureTransport 조건의 거부 문을 넣어 HTTP 요청을 거부하는 정책을 저장하고, 저장 후 콘솔이 보여 주는 정책을 읽습니다. 실제로 막히는지는 시험하지 않았습니다. 실습이 끝나면 버킷을 삭제합니다.

- 주소: https://copyandrun.com/blog/aws-s3-bucket-policy-deny-http/
- 분야: 클라우드
- 발행일: 2026-10-18
- 태그: AWS, S3, 버킷 정책, SecureTransport, 전송 암호화

S3는 HTTPS와 HTTP 둘 다로 요청을 받을 수 있고, 버킷 정책에 `aws:SecureTransport` 조건을 넣으면 HTTPS가 아닌 요청을 거부할 수 있습니다(AWS 문서 기준, 아래 확인 범위에 링크). 이 글은 정책을 저장하는 데까지만 다루며 HTTP 요청이 실제로 거부되는지는 시험하지 않았습니다. 이 글에서는 빈 버킷을 하나 만들어 그 정책을 직접 입력하고 저장한 뒤, 콘솔에 표시되는 모습까지 확인합니다. 버킷의 다른 보안 기본값은 [S3 버킷 보안 기본값 글](/blog/aws-s3-bucket-secure-defaults-console/)에서 다룹니다.

## 준비물

| 항목 | 내용 |
| --- | --- |
| AWS 계정 | 실습용 IAM 사용자. 버킷 생성, 버킷 정책 편집, 삭제 권한 필요 |
| 리전 | 아시아 태평양(서울) ap-northeast-2 |
| 버킷 이름 | `cr-demo-policy-1018`. 이름이 이미 쓰이고 있으면 끝의 숫자를 바꿉니다 |
| 예상 소요 시간 | 약 20분 |
| 변경 사항 | 버킷 1개 생성과 버킷 정책 저장. 마지막에 버킷을 삭제합니다 |

화면의 계정 정보는 가렸습니다.

## 1. 버킷 만들기

S3 콘솔 위쪽에서 리전을 아시아 태평양(서울)로 바꾼 뒤 `버킷 만들기`를 누르고 이름에 `cr-demo-policy-1018`을 입력한 뒤 나머지는 기본값으로 만듭니다.

![버킷 cr-demo-policy-1018이 생성되었다는 초록색 알림과 객체가 없는 새 버킷 화면](https://copyandrun.com/img/aws-s3-bucket-policy-deny-http/01-bucket.png)

## 2. 비어 있는 버킷 정책 확인하기

버킷을 열고 `권한` 탭을 아래로 내려 `버킷 정책` 칸을 봅니다.

![버킷 정책 칸이 비어 있고 위쪽에 퍼블릭 액세스 차단 안내가 보이는 권한 탭 화면](https://copyandrun.com/img/aws-s3-bucket-policy-deny-http/02-empty-policy.png)

새 버킷에는 정책이 없습니다. 위쪽 파란 상자는 이 버킷의 퍼블릭 액세스 차단 설정이 켜져 있다는 안내입니다. 이 설정과 방금 만들 정책은 서로 다른 장치입니다. 퍼블릭 액세스 차단은 외부 공개를 막고, 이 글의 정책은 전송 방식(HTTP인지 HTTPS인지)을 조건으로 거부합니다. `편집`을 누릅니다.

![버킷 ARN과 비어 있는 JSON 편집기가 보이는 버킷 정책 편집 화면](https://copyandrun.com/img/aws-s3-bucket-policy-deny-http/03-editor.png)

편집 화면 위쪽에 버킷 ARN이 표시됩니다. 정책 안의 `Resource`에 이 ARN을 그대로 씁니다. 오른쪽 위에는 외부 링크 모양의 `정책 예제` 단추가 있습니다. 이 단추는 누르지 않았습니다.

## 3. 정책 입력하기

편집기의 내용을 모두 지우고 아래 정책을 붙여 넣습니다. 버킷 이름을 바꿨다면 `Resource`의 두 ARN도 같은 이름으로 고칩니다.

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyInsecureTransport",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::cr-demo-policy-1018",
        "arn:aws:s3:::cr-demo-policy-1018/*"
      ],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    }
  ]
}
```

| 항목 | 값 | 의미 |
| --- | --- | --- |
| Effect | `Deny` | 조건에 맞으면 거부합니다 |
| Principal | `*` | 모든 요청자가 대상입니다 |
| Action | `s3:*` | 이 버킷에 대한 모든 S3 작업이 대상입니다 |
| Resource | 버킷 ARN과 `/*` | 버킷 자체와 안의 객체 모두입니다 |
| Condition | `aws:SecureTransport`가 `false` | HTTPS가 아닌 요청일 때만 위 거부가 적용됩니다 |

이 실습에서는 같은 내용을 한 줄로 입력했습니다. 입력한 뒤 편집기 아래쪽의 검사 칸을 확인합니다. 아래 화면은 편집기를 아래로 스크롤한 상태라 입력한 글자는 보이지 않고, 입력한 정책은 5번 화면에서 볼 수 있습니다.

![정책 편집기 아래쪽 검사 칸에 보안, 오류, 경고, 추천이 모두 0으로 표시된 화면](https://copyandrun.com/img/aws-s3-bucket-policy-deny-http/04-validation.png)

보안, 오류, 경고, 추천이 모두 0이었습니다. `변경 사항 저장`을 누릅니다.

## 4. 저장된 정책 읽기

저장하면 초록 알림 `버킷 정책을 편집했습니다.`가 나오고 권한 탭의 `버킷 정책` 칸에 정책이 표시됩니다.

![저장된 버킷 정책이 Deny 문과 aws:SecureTransport false 조건을 포함한 JSON으로 표시된 화면](https://copyandrun.com/img/aws-s3-bucket-policy-deny-http/05-saved.png)

한 줄로 입력한 정책이 콘솔에서는 줄 단위로 정리되어 표시되었습니다. 표시된 내용은 위에 적은 정책과 같습니다. 이 칸에서 `편집`으로 다시 고치거나 `삭제`로 정책을 지울 수 있습니다.

## 5. 정리: 버킷 삭제

버킷 목록에서 `cr-demo-policy-1018`만 선택하고 `삭제`를 누릅니다.

![cr-demo-policy-1018 버킷을 삭제할지 묻고 버킷 이름 입력칸이 있는 삭제 확인 화면](https://copyandrun.com/img/aws-s3-bucket-policy-deny-http/06-delete-dialog.png)

화면 제목의 버킷 이름이 지우려는 버킷과 같은지 확인한 뒤 이름을 입력하고 `버킷 삭제`를 누릅니다.

![버킷이 삭제되었다는 초록색 알림과 버킷이 1개만 남은 목록 화면](https://copyandrun.com/img/aws-s3-bucket-policy-deny-http/07-deleted.png)

삭제 뒤 목록에는 이미 있던 버킷 1개가 남았고, 이름은 가렸습니다. 이 버킷은 이 실습에서 다루지 않았습니다.

## 자주 막히는 곳

- **정책이 저장되지 않는 경우**: 이 실습에서는 오류 상황을 만들지 않았습니다. 편집기 아래 검사 칸의 오류 표시를 먼저 확인하고 따옴표와 쉼표를 점검합니다.
- **Resource를 버킷 ARN 하나만 쓰는 경우**: AWS 문서 기준으로 `s3:ListBucket` 같은 버킷 대상 작업은 버킷 ARN에, `s3:GetObject` 같은 객체 대상 작업은 `/*`가 붙은 ARN에 일치합니다. 그래서 이 글의 정책은 두 ARN을 모두 썼습니다. 하나만 쓴 경우는 시험하지 않았습니다.
- **HTTP 요청이 정말 막히는지 궁금한 경우**: 이 글에서는 시험하지 않았습니다. 아래 "이어서 해 볼 것"에 시험 방법을 적었습니다.
- **`s3:*` 거부의 범위**: AWS 문서 기준으로 명시적 거부는 허용보다 우선합니다. 조건에 맞는 요청은 요청자의 권한과 관계없이 거부되므로, HTTP로 접속하는 기존 도구가 있는지 먼저 확인한 뒤 적용합니다. 이 정책이 거부하는 것은 HTTP 요청뿐이라 HTTPS인 콘솔에서는 정책을 계속 고칠 수 있습니다(문서 기준).

## 이어서 해 볼 것

- 버킷에 객체 하나를 올리고 HTTPS와 HTTP로 각각 요청해 응답을 비교하기. 객체 공개가 꺼져 있으면 익명 요청은 둘 다 거부로 보일 수 있으니 서명된 요청으로 시험합니다. AWS CLI는 기본이 HTTPS이므로 HTTP를 시험하려면 `--endpoint-url http://s3.ap-northeast-2.amazonaws.com`처럼 주소를 직접 지정합니다. 이 방법은 이 글에서 실행하지 않았고, 기대 결과(HTTP는 AccessDenied)도 문서 기준입니다
- 같은 정책을 [IAM 정책 시뮬레이터 글](/blog/aws-iam-policy-simulator-read/)의 방식으로 시뮬레이터에 넣어 `aws:SecureTransport` 값을 바꿔 가며 결과를 비교하기
- 버킷에 정책을 저장한 뒤 CloudTrail 이벤트 기록에서 `PutBucketPolicy` 이벤트가 남았는지 확인하기. 이벤트가 나타나기까지 시간이 걸릴 수 있습니다(문서 기준). 읽는 방법은 [CloudTrail 이벤트 기록 글](/blog/aws-cloudtrail-event-history-read/)에 있습니다

## 확인한 범위와 확인하지 않은 것

- 확인한 것: 버킷 생성, 빈 버킷 정책 화면, 정책 입력과 검사 결과, 저장 후 표시되는 정책, 버킷 삭제.
- 확인하지 않은 것: HTTP 요청이 실제로 거부되는지, 정책이 다른 문과 함께 있을 때의 동작, `Resource` 구성에 따른 차이. 정책 의미 설명(명시적 거부 우선, 조건 키의 의미, Resource 대응)은 AWS 문서에 근거한 것이며 이 실습에서 직접 시험하지 않았습니다. 근거 문서: [버킷 정책 예시(HTTPS 요청만 허용)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html), [S3 보안 모범 사례](https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html), [정책 평가 로직](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html), [S3 작업과 리소스 유형](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazons3.html). 화면 문구는 이 실습 시점의 한국어 콘솔 기준입니다.
