Skip to content

English {#english}

Control Plane: Via Zuplo API Gateway vs Direct Worker — Comparison and Recommendation

Purpose: Compare using the Zuplo API gateway for Control Plane vs calling the Worker directly, summarize pros/cons, and give an operational recommendation. No code proposals.

References: tenant-onboarding-flow.md, step5-confirm-submit-to-provisioning-flow.md, prego-control-plane README, onboarding-pulumi-ansible-stripe-zuplo-queue-logpush-analysis.md.


1. Context: Callers and Endpoints

CallerEndpoint examplesAuth / notes
www (browser)POST /v1/tenants, GET /v1/jobs/:id, GET /v1/subdomain/check, POST /v1/checkoutPublic; CORS needed. No API Key (onboarding).
StripePOST /webhooks/stripeStripe signature verification. Must be public URL.
GitHub Actions / Ansible / internalGET/POST /internal/*Bearer INTERNAL_API_KEY. Server/workflow only.
Cron(Worker internal schedule)No external call.

PREGO_CONTROL_PLANE_URL is the “Control Plane entry point” for www and external callers. If it points to Zuplo, Zuplo receives first and proxies to the Worker; if to the Worker URL, the Worker receives directly. Business logic always lives in prego-control-plane (Worker).


2. Via Zuplo API Gateway

Setup: www / Stripe etc. → Zuplo (routing, policies) → Control Plane Worker.

2.1 Pros

ItemDetail
Rate limitingPath- and client-level limits in Zuplo. Helps with POST /v1/tenants abuse and DDoS.
API Key and policiesCan apply API Key policies to /v1/* when needed (www may not use yet; consistent gateway for future B2B/partner API).
ObservabilityZuplo dashboard for request volume, errors, latency in one place.
Single entryTenant API (post-provisioning) and Control Plane under same gateway domain → easier unified CORS, domain, auth.
Routing/variantsRoute to different backends or A/B/canary via Zuplo policies.

2.2 Cons

ItemDetail
Latency / hopRequest goes Zuplo → Worker; slight extra delay vs direct.
Stripe webhookStripe sends signed body to webhook URL. Via Zuplo, body must reach Worker unchanged for signature verification; no re-serialization or modification. Requires configuration and verification.
CostZuplo usage-based cost. Small at low traffic; notable at high call volume.
OpsManage Zuplo config, keys, policies and Worker deployment together. Failures need “Zuplo vs Worker” segment debugging.
Internal calls/internal/* is already protected by Bearer; internal systems can call Worker URL directly and skip Zuplo. “Only public via Zuplo” is consistent but yields two URL kinds (public = Zuplo, internal = Worker).

3. Direct Worker Call

Setup: www / Stripe etc. → Control Plane Worker directly.

3.1 Pros

ItemDetail
SimplicitySingle entry (Worker URL). Set deployment and env (PREGO_CONTROL_PLANE_URL).
LatencyNo extra hop; shorter response time.
Stripe webhookWorker receives Stripe events directly. No body mutation issues for signature verification.
CostNo Zuplo cost; only Worker, D1, Queue, etc.
DebuggingOnly Worker logs and Trace to check on failure.

3.2 Cons

ItemDetail
Rate limitingImplement in Worker or rely on Cloudflare WAF/Rate Limiting. Path-level limits are more work in Worker alone.
Public endpoint protectionPOST /v1/tenants etc. fully public → Worker exposed to scraping/retry storms. Need WAF/bot strategy.
ObservabilityWorker metrics and Logpush work, but “API gateway–level” dashboard is separate or Cloudflare-only.
Policy consistencyTo apply same gateway policies (keys, quotas) as tenant API later, need more Worker logic or add Zuplo in front later.

4. Comparison Summary

CriteriaVia ZuploDirect Worker
Rate limiting / DDoSEasy with Zuplo policiesWorker/WAF or CF features
Stripe webhookConfig and body pass-through careSimple direct receive
LatencyOne extra hop possibleShorter
CostZuplo cost addedNone
Ops / debuggingTwo layers (Zuplo + Worker)Worker only
Public/internal unityPublic-only via Zuplo → two URLsSingle URL, simple
ObservabilityZuplo dashboardWorker / Logpush etc.

5. Recommendation

  • Current phase (onboarding and provisioning stability first): Prefer direct Worker as default.

    • Reasons: Simpler to implement and operate; Stripe webhook received directly by Worker is easier to verify and debug.
    • Protect public endpoints (POST /v1/tenants, GET /v1/jobs, etc.) with Cloudflare WAF and Rate Limiting first; add simple rate limit (e.g. by IP/key) in Worker if needed.
  • When to consider Zuplo:

    • When you want tenant API and Control Plane under the same domain and policy,
    • When you need path- or key-level rate limits and quotas for POST /v1/tenants etc.,
    • When opening B2B/partner API on Control Plane paths and want API Key and usage dashboard unified in Zuplo.
      Then put Zuplo in front. You can keep Stripe webhook on a direct Worker URL and route only www/public API through Zuplo (hybrid: public = Zuplo → Worker; webhook/internal = direct Worker).

Summary:

  • Recommendation: Run with direct Worker for now, protected by WAF and Worker-level rate limit.
  • Option: If policy, observability, and unification needs grow, move only public endpoints to Zuplo and keep Stripe webhook and /internal/* on direct Worker.

한국어 {#korean}

Control Plane: Zuplo API 게이트웨이 경유 vs Worker 직호출 비교 및 추천

목적: Control Plane 관련 기능을 Zuplo API 게이트웨이를 경유해 사용할 때와 Worker를 직접 호출할 때의 장단점을 분석·비교하고, 운영 관점에서 추천안을 정리한다. 코드 제안 없음.

참조: tenant-onboarding-flow.md, step5-confirm-submit-to-provisioning-flow.md, prego-control-plane README, onboarding-pulumi-ansible-stripe-zuplo-queue-logpush-analysis.md.


1. 전제: Control Plane 호출처와 엔드포인트 구분

호출처엔드포인트 예인증/특성
www(브라우저)POST /v1/tenants, GET /v1/jobs/:id, GET /v1/subdomain/check, POST /v1/checkout공개·CORS 필요. API Key 없음(온보딩 단계).
StripePOST /webhooks/stripeStripe Signature 검증. 공개 URL이어야 함.
GitHub Actions / Ansible / 내부GET/POST /internal/*Bearer INTERNAL_API_KEY. 서버·워크플로만 호출.
Cron(Worker 내부 스케줄)외부 호출 없음.

PREGO_CONTROL_PLANE_URL이 가리키는 곳이 곧 “www·외부에서 보는 Control Plane 진입점”이다. Zuplo URL이면 Zuplo가 먼저 받아 Worker로 프록시하고, Worker URL이면 Worker가 직접 받는다. 비즈니스 로직은 항상 prego-control-plane(Worker) 에 있다.


2. Zuplo API 게이트웨이 경유 방식

구성: www / Stripe 등 → Zuplo (라우팅·정책) → Control Plane Worker.

2.1 장점

항목내용
Rate limitingZuplo에서 경로·클라이언트별 제한 설정 가능. POST /v1/tenants 남용·DDoS 완화에 유리.
API Key·정책필요 시 /v1/* 에 API Key 정책 적용 가능(현재 www는 미사용이어도, 추후 B2B·파트너 API 노출 시 일관된 게이트웨이).
관측성Zuplo 대시보드에서 요청량·에러·레이턴시를 한곳에서 확인 가능.
일관된 진입점테넌트 API(프로비저닝 완료 후)와 Control Plane을 같은 게이트웨이 도메인 아래 두면, CORS·도메인·인증 정책을 통일하기 쉬움.
변형·라우팅경로별로 다른 백엔드로 스위칭하거나, A/B·카나리 배포를 Zuplo 정책으로 처리 가능.

2.2 단점

항목내용
레이턴시·홉요청이 Zuplo → Worker 로 한 번 더 거치므로, 직호출 대비 소폭 지연 가능.
Stripe WebhookStripe는 Webhook URL에 서명 검증을 붙여 보냄. Zuplo 경유 시 Zuplo가 body를 그대로 Worker에 전달해야 하고, Worker에서 서명 검증 시 원본 body가 필요. 프록시 시 body 재직렬화·변형이 없어야 함. 설정·검증 필요.
비용Zuplo 사용량 기반 비용 추가. 트래픽이 적으면 미미하나, 호출량이 크면 고려 대상.
운영 포인트 증가Zuplo 설정·키·정책과 Worker 배포를 함께 관리해야 함. 장애 시 “Zuplo vs Worker” 구간 분리 디버깅 필요.
내부 호출/internal/* 는 Bearer로 이미 보호되므로, 내부 시스템이 Worker URL을 직접 호출하면 Zuplo를 거칠 필요가 없음. “공개 엔드포인트만 Zuplo”로 나누면 일관되지만, URL이 두 종류(공개=Zuplo, 내부=Worker)가 됨.

3. Worker 직호출 방식

구성: www / Stripe 등 → Control Plane Worker 직접.

3.1 장점

항목내용
단순성진입점이 하나(Worker URL). 배포·환경 변수(PREGO_CONTROL_PLANE_URL)만 맞추면 됨.
레이턴시홉이 없어 직호출이므로 상대적으로 짧은 응답 시간.
Stripe WebhookWorker가 Stripe 이벤트를 직접 수신. 서명 검증 시 body 변형 이슈 없음.
비용Zuplo 비용 없음. Worker·D1·Queue 등 기존 Cloudflare 비용만.
디버깅장애 시 Worker 로그·Trace만 보면 됨.

3.2 단점

항목내용
Rate limitingWorker 단에서 직접 구현하거나, Cloudflare WAF/Rate Limiting 규칙에 의존해야 함. Worker만으로는 경로별 세밀한 제한이 상대적으로 번거로움.
공개 엔드포인트 보호POST /v1/tenants 등이 완전 공개이면, 스크래핑·재시도 폭주에 Worker가 직접 노출. WAF·Bot 전략으로 보완 필요.
관측성Worker 메트릭·Logpush로 해결 가능하지만, “API 게이트웨이 수준” 대시보드는 별도 구축 또는 Cloudflare 대시보드에 의존.
정책 통일나중에 테넌트 API와 동일한 게이트웨이 정책(키·할당량)을 적용하려면 Worker 쪽 로직 추가 또는 Zuplo를 나중에 앞단에 도입해야 함.

4. 비교 요약

기준Zuplo 경유Worker 직호출
Rate limiting / DDoS 완화Zuplo 정책으로 적용 용이Worker/WAF 구현 또는 CF 기능에 의존
Stripe Webhook설정·body 전달 주의직접 수신으로 단순
레이턴시1홉 추가 가능짧음
비용Zuplo 비용 추가없음
운영·디버깅Zuplo + Worker 두 레이어Worker만
공개/내부 통일공개만 Zuplo로 두면 URL 이원화단일 URL로 단순
관측성Zuplo 대시보드 활용Worker/Logpush 등

5. 추천

  • 현 단계(온보딩·프로비저닝 안정화 우선): Worker 직호출을 기본으로 두는 것을 추천한다.

    • 이유: 구현·운영이 단순하고, Stripe Webhook을 Worker가 직접 받는 구성이 검증·디버깅에 유리하다.
    • 공개 엔드포인트(POST /v1/tenants, GET /v1/jobs 등)는 Cloudflare WAF·Rate Limiting 규칙으로 1차 보호하고, 필요 시 Worker 내부에 단순 rate limit(예: IP/키별)을 추가하는 방식으로 충분할 수 있다.
  • Zuplo 경유를 고려할 시점:

    • 테넌트 API와 Control Plane을 같은 도메인·같은 정책 아래 두고 싶을 때,
    • POST /v1/tenants 등에 경로별·키별 세밀한 rate limit·할당량이 필요해질 때,
    • B2B·파트너용 API를 Control Plane 경로에도 열고 API Key·사용량 대시보드를 Zuplo로 통일하고 싶을 때
      에 Zuplo를 앞단에 두는 구성을 검토하면 된다. 이때 Stripe Webhook은 Worker 직링크를 유지하고, www·공개 API만 Zuplo로 라우팅하는 하이브리드(공개 = Zuplo → Worker, Webhook/내부 = Worker 직호출)도 가능하다.

정리:

  • 추천: 당장은 Worker 직호출로 운영하고, WAF/Worker 수준 rate limit으로 보호.
  • 선택: 정책·관측·일원화 요구가 커지면 공개 엔드포인트만 Zuplo 경유로 전환하고, Stripe Webhook·/internal/* 는 계속 Worker 직호출 유지.
Help