Knowledge · Cloudflare

Cloudflare Zero Trust Free로 웹사이트와 Preview 비공개 설정하기

무료 50명 요금제부터 Access 로그인 정책, Worker 전체·Preview 전용 보호까지

Cloudflare Zero Trust Free에 가입하고 이메일 허용 정책을 만든 뒤 Workers의 운영 사이트 전체 또는 Preview만 로그인 사용자에게 공개하는 과정을 실제 설정 경험으로 정리한다.

Cloudflare Workers로 웹사이트를 운영하다 보면 모든 페이지를 공개할 필요는 없다. 개인용 투자 대시보드는 본인만 열어보고 싶고, 블로그의 작업 중인 Preview는 실제 발행 전까지 비공개로 두고 싶었다.

로그인 시스템을 직접 만들 수도 있지만, Cloudflare Zero Trust의 Access 기능을 사용하면 이미 배포된 Worker 앞에 인증 단계를 추가할 수 있다.

이번에는 서로 다른 두 가지 설정을 적용했다.

서비스보호 범위기대하는 동작
개인용 INVESTAll traffic운영 주소·API·workers.dev·Preview 전부 로그인 필요
공개 BLOGPreviews only운영 사이트는 공개, Preview에만 로그인 필요

아래 내용은 2026년 10월 24일 실제로 설정한 화면과 당시 Cloudflare 공식 문서를 기준으로 정리했다. 메뉴가 달라졌다면 본문 하단의 공식 문서를 참고하면 된다.

1. Zero Trust Free는 몇 명까지 무료일까?

Cloudflare Zero Trust Free의 기본 요금은 $0, 사용자 한도는 최대 50명이다.

항목내용
요금$0
무료 사용자최대 50명
별도 무료 체험 만료Free 플랜 자체에 정해진 체험 종료일 없음
Access 인증 및 정책Free 플랜에서 이용 가능
최초 조직 생성Free 선택 시에도 결제 정보 입력 필요

50명은 도메인 수, Worker 수, Cloudflare 계정 수, 월 방문자 수가 아니다. Zero Trust의 Access에 실제로 인증한 사용자 좌석(seat) 수다. 같은 사용자가 여러 앱에 로그인해도 사용자 한 명으로 계산되며, 여러 기기를 이용한다고 기기마다 별도로 세는 방식도 아니다. 단, 인증한 사용자는 좌석을 점유하며 자동으로 해제되지 않을 수 있다.

또한 Zero Trust Free와 Workers·D1 등 다른 Cloudflare 제품의 요금 및 한도는 별개다. 결제수단을 등록했다고 Free 플랜 가입만으로 청구되는 것은 아니지만, 별도 유료 기능을 활성화할 때는 비용을 확인해야 한다.

Cloudflare 공식 문서도 Zero Trust Free의 최초 조직 설정에서 결제 정보를 입력하도록 안내하며, Free를 선택했다면 그 단계에서 과금하지 않는다고 설명한다.

2. Cloudflare Zero Trust 조직 만들기

기존 Cloudflare 계정이 있고 Worker를 이미 배포했다는 전제에서 시작한다.

  1. Cloudflare Dashboard에 로그인한다.
  2. 왼쪽 메뉴에서 Zero Trust를 연다.
  3. 처음이라면 Cloudflare One 초기 설정 화면에서 Team name을 지정한다. 별도로 제공되는 팀 식별 이름이며, 개인 이메일이나 비밀번호를 적는 곳이 아니다.
  4. 요금제에서 Zero Trust Free를 선택한다.
  5. 요청하는 결제 정보를 입력하고 조직 활성화를 마친다.
  6. 다시 Zero Trust 화면에서 Access controls 메뉴가 보이는지 확인한다.

처음 설정하면서 Workers & Pages → invest → Access를 누를 때마다 Zero Trust 초기 안내 화면으로 이동했다. 조직 설정을 먼저 완료한 후에야 Access 정책과 Worker 보호를 설정할 수 있었다.

화면의 Connect a private web application 등은 별도의 애플리케이션 연결 흐름을 위한 안내다. 이미 Cloudflare Workers에 배포된 서비스를 전체 보호하려는 경우 Tunnel을 새로 만들 필요 없이 Worker의 Access 탭으로 돌아가면 된다.

3. 본인 이메일만 허용하는 정책 만들기

먼저 누가 접속할 수 있는가를 정한다.

메뉴:

Zero Trust → Access controls → Policies → Add a policy

다음은 개인용으로 설정했던 값이다.

항목설정값
Policy nameONSEMO Invest Owner Only
ActionAllow
Session duration24 hours
Include → SelectorEmails
Include → Value접속을 허용할 본인 이메일 한 개
Override global MFAOff
  1. Policy name을 입력하고 Action = Allow를 선택한다.
  2. Include에서 Selector = Emails를 선택한다.
  3. Value에 허용할 정확한 이메일을 한 개 입력한다.
  4. 세션 시간을 정하고 MFA 설정을 확인한다.
  5. 아래의 Save policy를 누른다.

Everyone을 허용하면 누구나 인증을 시도해 접근할 수 있고, Email domain을 허용하면 해당 이메일 도메인을 사용하는 여러 사람이 대상이 된다. 개인 전용 사이트라면 Emails에 본인 주소만 지정해야 한다.

한 가지 주의할 점은 정책 생성만으로 사이트가 잠기지는 않는다는 것이다. 이제 원하는 Worker에 이 정책을 연결해야 한다.

MFA는 어떻게 할까?

이번에 Override global MFA = Off로 둔 것은 MFA를 강제로 해제했다는 뜻이 아니다. 애플리케이션 또는 조직의 기본 MFA 규칙을 상속하도록 한 것이다.

Cloudflare Access는 Identity Provider 기반 MFA와 Access 자체의 Independent MFA를 구분한다. 중요한 정보를 보관하는 개인 서비스라면 별도 MFA를 켜는 편이 더 안전하다.

설정 위치는 Zero Trust → Access controls → Applications → 대상 애플리케이션 → Configure → Authentication → MFA이다. 정책 수준에서는 Policies → 해당 정책 → Configure → Multi-factor authentication도 확인한다. 정책의 설정이 애플리케이션 및 조직의 기본 설정보다 우선할 수 있다.

4. INVEST 운영 사이트와 Preview를 한 번에 보호하기

가장 중요한 설정이다. 운영 사이트 한 주소만 막고 다른 workers.dev 주소를 열어두면 보호가 불완전할 수 있다.

메뉴:

Cloudflare Dashboard → Workers & Pages → invest → Access

설정 순서:

  1. 대상 Worker invest를 선택한다.
  2. Access 탭을 연다.
  3. Protect this Worker behind Access를 클릭한다.
  4. 보호 범위를 All traffic으로 지정한다.
  5. Authentication policy에서 ONSEMO Invest Owner Only를 선택한다.
  6. 대상 Worker와 범위를 다시 확인한 후 Apply Access를 누른다.

이때 Protect all Workers가 아닌 Protect this Worker를 선택해야 한다. 전자는 해당 계정의 다른 Worker까지 접근 제한을 걸 수 있다.

Cloudflare 공식 문서에 따르면 Worker 단위 All traffic은 다음을 모두 보호한다.

  • 연결된 Custom Domain: 예를 들어 invest.onsemo.com
  • 연결된 Worker Route
  • workers.dev 호스트 주소
  • 해당 Worker의 Preview
  • 위 주소에서 접근하는 정적 리소스와 API 경로

즉, Worker 전체 보호와 특정 Hostname만 지정해서 보호하는 방식은 범위가 다르다. Hostname 기반 Access는 설정한 호스트나 경로만 보호하므로 다른 주소를 통해 동일 Worker에 접근할 수 있는지 따로 살펴야 한다.

주의: Worker 수준 Access는 현재 WebSocket 연결을 지원하지 않아 업그레이드 요청이 403으로 실패할 수 있다. 실시간 WebSocket 애플리케이션이라면 Hostname 기반 Access를 비롯한 다른 구성이 필요한지 검토한다.

5. BLOG는 운영을 공개하고 Preview만 보호하기

공개 블로그의 경우에는 운영 주소가 누구에게나 열려 있어야 한다. 따라서 INVEST와 같은 All traffic을 선택하면 안 된다.

메뉴:

Cloudflare Dashboard → Workers & Pages → blog → Access

설정 순서:

  1. blog Worker를 선택한다.
  2. Access → Protect this Worker behind Access를 클릭한다.
  3. Previews only를 선택한다.
  4. Authentication policy에서 본인 이메일만 허용하는 정책을 선택한다.
  5. Apply Access를 누른다.

이렇게 하면 https://blog.onsemo.com은 공개하면서, BLOG의 Preview Worker 주소에만 로그인을 요구한다.

기존의 ONSEMO Invest Owner Only 정책을 재사용할 수도 있다. 다만 같은 정책을 공유한다면 나중에 허용 이메일을 변경할 때 연결된 모든 애플리케이션에 영향이 있으므로 주의해야 한다. 용도가 같다면 ONSEMO Owner Only처럼 공통 정책으로 이름을 정리하는 방법도 있다.

6. Self-hosted application과 Worker 보호의 차이

처음에는 Zero Trust → Access controls → Applications → Create new application에서 호스트 이름을 등록하는 방법도 살펴봤다.

하지만 두 방식은 보호 범위가 다르다.

방법보호 대상사용하기 좋은 경우
Self-hosted application의 Public hostname지정한 호스트 이름 또는 URL 경로특정 도메인이나 경로만 잠그려는 경우
Worker의 All trafficWorker의 운영 및 Preview 전체개인 전용 Worker 전체를 비공개로 만드는 경우
Worker의 Previews onlyWorker의 Preview만운영 사이트는 공개하고 미리보기만 제한하는 경우

이번에는 이미 배포된 Worker에 대한 범위별 보호가 목적이므로 Worker의 Access 탭에서 처리했다.

서로 다른 Access 규칙이 같은 요청에 적용되면 Hostname/Path → 개별 Worker → 계정 전체 Worker 순서로 더 구체적인 규칙이 우선한다. 이미 다른 Self-hosted 설정이 있다면 접근 허용 예외가 생기지 않는지 확인해야 한다.

7. 설정 후 반드시 검증하기

로그인 화면이 보인다고 접근 제어가 완벽하다고 단정해서는 안 된다. 로그인한 브라우저에는 세션이 남아 있을 수 있으므로 시크릿 모드 또는 로그아웃한 다른 브라우저에서 확인한다.

INVEST 점검

  1. 시크릿 모드에서 https://invest.onsemo.com을 연다.
  2. Cloudflare Access 로그인 화면이 뜨는지 확인한다.
  3. 허용한 본인 계정으로 로그인해 앱이 정상 작동하는지 확인한다.
  4. 다른 계정으로는 로그인할 수 없는지 확인한다.
  5. workers.dev 주소와 주요 API 경로도 인증 없이 본문이나 데이터가 공개되지 않는지 확인한다.
  6. Preview가 있다면 Preview 주소도 비인증 상태에서 점검한다.

로그인 페이지로의 리디렉션 또는 접근 거부 응답이 나올 수 있다. 중요한 것은 인증하지 않은 방문자가 앱과 민감한 API 응답을 받지 못해야 한다는 점이다.

이번 INVEST 설정에서는 사용자 로그인 성공을 확인한 뒤, 별도의 GitHub Actions에서 로그인하지 않은 환경으로 앱과 주요 API 경로 접근이 차단되는지 검사했다.

BLOG 점검

  1. 시크릿 모드에서 https://blog.onsemo.com을 연다. 로그인 없이 공개 페이지가 열려야 한다.
  2. 실제 GitHub PR의 Cloudflare Preview URL을 연다. 로그인 화면이 나와야 한다.
  3. 인증 후 Preview가 정상 작동하는지 확인한다.

Preview는 브랜치가 아니라 실제 Cloudflare에 배포된 URL에서 확인한다. GitHub 저장소가 Private이라고 해서 Preview도 자동으로 비공개가 되는 것은 아니다.

8. 나중에 관리할 메뉴

목적메뉴
허용 이메일 정책 수정Zero Trust → Access controls → Policies
Access 애플리케이션 설정 확인Zero Trust → Access controls → Applications
Worker 전체·Preview 보호 변경Workers & Pages → 대상 Worker → Access
MFA 요구 방식 변경Access controls → Applications → 대상 앱 → Authentication → MFA
사용 중인 좌석 수Zero Trust → Team & Resources → Users
Zero Trust 요금제Zero Trust → Settings → Cloudflare One plan

한번 인증한 사용자는 세션이나 좌석을 유지할 수 있다. 세션만 종료하는 것과 허용 정책에서 사용자를 제외하는 것은 다르다. 접속 권한을 없애려면 정책의 허용 대상도 변경해야 한다.

9. 공개와 비공개의 경계 정하기

로그인 기능을 직접 구현하기 전에 Cloudflare Access처럼 이미 제공되는 접근 제어 기능을 활용할 수 있는지 확인할 필요가 있었다.

다만 Access라는 이름만 보고 여러 화면을 오가다 보면 호스트 기반 설정, Worker 전체 보호, Preview 전용 보호가 혼동되기 쉽다. 실제로 중요한 것은 누가 로그인하는가뿐 아니라 어느 범위까지 보호하는가였다.

개인용 서비스에는 All traffic, 공개 운영하는 블로그의 미리보기에는 Previews only를 적용하는 것으로 정리했다. 웹사이트 코드와 별개로 보호 범위를 지정하고, 마지막에 실제 비인증 접속을 검증한 경험을 남겨둔다.

공식 참고 자료

Cloudflare웹사이트 운영CloudflareZero TrustAccessWorkersPreview보안MFA비공개 사이트
연결된 프로젝트BLOG
관련 KnowledgeKnowledge 가이드