Skip to Content
문서제한과 정책

제한과 정책

Deplite는 호출 폭주를 막기 위해 여러 층의 제한을 둬요.

위치기준
워크플로우 단위 rate limit서버분·시간·일당 호출 횟수
토큰 단위 rate limit서버분·시간·일당 호출 횟수
토큰 읽기(조회) rate limit서버분당 호출 횟수

워크플로우 YAML에는 따로 limit 설정 필드가 없어요. 모든 제한은 대시보드에서 워크플로우 또는 API 토큰에 설정해요.

워크플로우 단위 rate limit

대시보드의 워크플로우 상세에서 분·시간·일당 호출 횟수를 설정해요.

필드의미
rateLimitPerMinute1분 안에 허용할 호출 수
rateLimitPerHour1시간 안에 허용할 호출 수
rateLimitPerDay1일 안에 허용할 호출 수

세 값은 독립적으로 평가돼요.
한 윈도우라도 초과하면 trigger 호출은 즉시 HTTP 429로 거절돼요.

{ "statusCode": 429, "code": "rate_limited", "message": "Rate limit exceeded for workflow \"deploy-prod\" (minute: 6/5)", "window": "minute" }

거절 이벤트는 rate_limit_blocks 테이블에 기록되고, audit log에 rate_limit.block 액션으로 남아요.

토큰 단위 rate limit

API 토큰 발급 시 함께 설정할 수 있어요.
동일 토큰의 호출이 분·시간·일당 한도를 넘으면 워크플로우 단위와 마찬가지로 HTTP 429로 거절돼요.

{ "name": "CI/CD", "scopes": [{ "type": "trigger", "triggerIds": ["..."] }], "rateLimitPerMinute": 10, "rateLimitPerHour": 100, "rateLimitPerDay": 1000 }

워크플로우 단위 제한과 토큰 단위 제한은 서로 독립이라, 둘 다 통과해야 호출이 디스패치돼요.

토큰 읽기(조회) rate limit

토큰 접근 범위 조회 엔드포인트(GET /v1/token, /v1/agents, /v1/devices, /v1/workflows)에만 적용되는 별도 한도예요.
읽기 호출은 Job을 만들지 않아서, Job 카운트 기반인 토큰 단위 rate limit과는 따로 계산해요.
기본값은 토큰당 분당 60회이고, 서버 환경변수 API_TOKEN_READ_RATE_LIMIT_PER_MINUTE로 조정해요.

{ "statusCode": 429, "error": "Too Many Requests", "message": "Rate limit exceeded for api token reads (minute: 61/60)", "scope": "token_read", "window": "minute", "limit": 60, "observed": 61 }

차단되면 audit log에 rate_limit.block(scope: 'token_read')이 남아요.
쓰기 증폭을 막기 위해 토큰당 윈도우 1회만 기록해요.

셀프 호스팅 운영 주의: 이 카운터는 인스턴스 메모리에 있어서, 다중 인스턴스 배포에서는 인스턴스당 한도로 동작해요.
전역 한도가 아니라 열거(enumeration) 폭주를 늦추는 완화책으로 봐주세요.

force 우회

서버 측 워크플로우 rate limit을 명시적으로 우회해야 할 때(긴급 핫픽스 등)는 trigger 호출 시 force: true로 보내요.

curl -X POST .../triggers/<id>/run \ -d '{"ref": "main", "force": true, "forceReason": "hotfix CVE-2026-X"}'
조건동작
호출자 role조직의 owner만 허용. member 호출 시 거절
forceReason비어 있으면 거절 (forceReason is required when force=true)
Job 기록forced: true, forceReason이 함께 저장
Audit logtrigger.force_run 액션이 별도로 남음

토큰 단위 rate limit은 force로도 우회되지 않아요(토큰 자체를 회전하거나 한도를 늘려야 함).

중복 제거 (Idempotency)

Webhook 호출 시 Idempotency-Key 헤더를 보내면, 같은 키의 두 번째 호출은 첫 Job을 그대로 돌려줘요.

curl -X POST .../triggers/<id>/run \ -H "Idempotency-Key: deploy-2026-05-31-001" \ -d '{"ref": "main"}'

내부적으로 idempotency 키는 ${triggerId}:${workflowName}:${clientKey} 형태로 저장돼요.
같은 클라이언트 키라도 트리거+워크플로우 단위로 별도 추적되므로, 다른 트리거에 같은 키를 보내도 충돌하지 않아요.

Agent 큐 동작

Agent는 동시에 처리할 수 있는 Job을 내부 채널(기본 크기 4)로 받아 순차 실행해요.

큐가 차 있는 상태에서 새 deploy 이벤트가 도착하면, 현재 구현에서는 Agent가 로컬 로그에만 기록하고 silent drop해요.
서버에는 rejected job으로 보고되지 않으니, 대시보드에서 누락이 보이면 Agent 로그(job queue full; rejecting)를 확인해주세요.
많은 동시 실행이 필요하면 Agent를 여러 대로 늘려주세요.

실전 시나리오

A — 머지 폭주에서 워크플로우 보호

여러 PR이 동시에 머지되면서 같은 deploy 트리거가 폭주할 때, 대시보드 워크플로우 설정에서 rateLimitPerMinute = 1로 잡아 두면 1분에 한 번만 허용돼요.
두 번째 호출은 HTTP 429로 거절돼요.

B — 헬스체크 트리거 안정화

Cron 트리거를 1분 간격으로 걸어두고, 워크플로우에 rateLimitPerMinute = 1을 함께 설정하면 외부에서 webhook으로 또 같은 워크플로우를 호출해도 1분 1회 한도를 지켜줘요.

C — 긴급 핫픽스로 우회

평소엔 rateLimitPerHour = 4이지만 보안 패치는 즉시 배포해야 할 때, 대시보드의 트리거 상세 → Run 버튼에서 Force 체크박스를 켜고 refforceReason을 입력해요.
체크박스는 조직 owner 권한 사용자에게만 노출돼요.

{ "ref": "hotfix/cve-2026-x", "force": true, "forceReason": "CVE-2026-X 패치 — Sec팀 승인" }

Job 기록은 forced: true + forceReason 으로 남고, audit log에는 trigger.force_run 액션이 추가로 남아요.

관련 문서

최종 수정 일자: