error occurred while reprocess. capture_id: 30152, reason:Permission denied, user_id: 3615
RCA: error occurred while reprocess. capture_id: 30152, reason:Permission denied, user_id: 3615
Overview#
What Happened#
2026-04-29 22:57 UTC, cupixworks-worker 서비스(eu-central-1)에서 capture_id 30152에 대한 reprocess 요청이 Permission denied로 실패했다. user_id 3615과 user_id 2012 두 사용자가 각각 시도했으며, 두 건 모두 Pundit policy의 reinvoke? 권한 검사에서 거부되었다.
Quick Facts#
| Field | Value |
|---|---|
| exception.class | Cupix::Errors::PermissionDenied |
| exception.message | Permission denied |
| top_frame | app/invokers/capture_invoker.rb:273 |
| env | production, eu-central-1 |
Timeline#
- 2026-04-29T22:57:13Z — user_id 3615가 capture 30152 reprocess 시도, Permission denied
- 2026-04-29T22:57:47Z — user_id 2012가 capture 30152 reprocess 시도, Permission denied
- 2026-04-29T22:58:35Z — user_id 8이 capture 30152 reprocess 시도, "Model has invalid state to reprocess" (다른 에러 — 권한은 통과)
Error Log#
error occurred while reprocess. capture_id: 30152, reason:Permission denied, user_id: 3615
Impact#
- Service:
cupixworks-worker - 발생 횟수: 2
- 최초 발생: 2026-04-29T22:57:13.641Z
- 최근 발생: 2026-04-29T22:57:47.647Z
Root Cause Summary#
user_id 3615와 user_id 2012는 reinvoke? 정책에서 요구하는 administrator 또는 capture_qa_managers 관리 그룹에 속하지 않아 reprocess 권한이 거부되었다. CapturePolicy#reinvoke?는 admin_administrator? (admin 팀 + administrator 그룹) 또는 capture_qa_managers 그룹 멤버십만 허용하며, 해당 사용자들은 이 조건을 충족하지 못했다. 이는 의도된 보안 동작이지만, 에러가 error 레벨로 로깅되어 불필요한 알림을 유발하고 있다.
Technical Analysis#
Code Path#
- Entry point:
app/controllers/cli/v1/captures_controller.rb:10— CLI reinvoke 엔드포인트가CaptureOperation.reinvoke_captures를 호출 - Operation:
app/operations/capture_operation.rb:22-39— captures를 순회하며CaptureInvoker#reprocess_capture호출 - Permission check:
app/invokers/capture_invoker.rb:273— Pundit policy 검사에서PermissionDenied발생 - Error logging:
app/operations/capture_operation.rb:33— rescue에서Cupix::Logger.error로 기록
def reprocess_capture(opts = {})
raise Cupix::Errors::PermissionDenied.new(code: 'PERM10000', reason: 'Permission denied') unless Pundit.policy(self.current_user, @model).reinvoke?
raise Cupix::Errors::Entity.new(code: 'ENT10000', reason: 'Model has invalid state to reprocess') unless @model.reprocessible?
def reinvoke?
admin_administrator? || user.member_of_admin_groups?(%w[capture_qa_managers])
end
def admin_administrator?
user.member_of_admin_groups?(%w[administrator])
end
def member_of_admin_groups?(groups)
groups = parse_groups(groups)
self.team.domain == 'admin' && member_of_groups?(groups)
end
captures.each do |capture|
Cupix::Logger.info("start reprocess captures. capture_id: #{capture.id}, user_id: #{current_user.id}")
begin
capture_invoker = CaptureInvoker.new(model: capture, current_user: current_user)
capture_invoker.reprocess_capture
results << { id: capture.id, status: 'success' }
rescue StandardError => e
Cupix::Logger.error("error occurred while reprocess. capture_id: #{capture.id}, reason:#{e.message}, user_id: #{current_user.id}", reprocess: { error: e })
results << { id: capture.id, status: 'error', error: e.message }
end
end
기대 동작: reinvoke? 정책이 admin 팀 + administrator/capture_qa_managers 그룹 멤버만 허용.
실제 동작: user_id 3615, 2012는 해당 그룹에 속하지 않아 PermissionDenied 발생. 이 예외가 CaptureOperation의 rescue StandardError에 잡혀 error 레벨로 로깅됨.
Log Evidence#
검색 쿼리:
service:cupixworks-worker status:error "error occurred while reprocess"
Time range: 2026-04-29T21:00:00Z to 2026-04-29T23:59:00Z
service:cupixworks-worker "capture_id: 30152"
Time range: 2026-04-29T21:00:00Z to 2026-04-29T23:59:00Z
핵심 로그 (시간순):
{"timestamp": "2026-04-30 07:57:13 KST", "status": "info", "message": "start reprocess captures. capture_id: 30152, user_id: 3615"}
{"timestamp": "2026-04-30 07:57:13 KST", "status": "error", "message": "error occurred while reprocess. capture_id: 30152, reason:Permission denied, user_id: 3615"}
{"timestamp": "2026-04-30 07:57:47 KST", "status": "info", "message": "start reprocess captures. capture_id: 30152, user_id: 2012"}
{"timestamp": "2026-04-30 07:57:47 KST", "status": "error", "message": "error occurred while reprocess. capture_id: 30152, reason:Permission denied, user_id: 2012"}
{"timestamp": "2026-04-30 07:58:35 KST", "status": "info", "message": "start reprocess captures. capture_id: 30152, user_id: 8"}
{"timestamp": "2026-04-30 07:58:35 KST", "status": "error", "message": "error occurred while reprocess. capture_id: 30152, reason:Model has invalid state to reprocess, user_id: 8"}
user_id 8은 권한 검사를 통과했으나(admin 사용자로 추정), capture가 이미 유효하지 않은 상태여서 ENT10000 에러 발생. 이는 user 3615/2012의 시도가 실패한 후 admin이 수동으로 개입한 것으로 보임.
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | 사용자가 reinvoke 권한이 없는 그룹에 속함 | CapturePolicy#reinvoke?가 admin_administrator 또는 capture_qa_managers만 허용 (capture_policy.rb:34-36). user_id 8은 동일 capture에서 권한 통과. |
— | Confirmed |
| H2 | 인증 토큰 만료/무효화로 인한 일시적 권한 실패 | — | 동일 사용자의 요청이 인증까지는 성공(info 로그 "start reprocess" 기록됨). 두 명의 서로 다른 사용자에서 동일 에러 발생으로 토큰 문제 아님. | Rejected |
| H3 | 에러 로그 레벨이 과도 — 권한 거부는 예상 시나리오 | rescue StandardError가 PermissionDenied를 포함한 모든 에러를 error 레벨로 로깅 (capture_operation.rb:33). 권한 부족은 버그가 아닌 정상적인 접근 제어 동작. |
— | Confirmed |
Fix Recommendation#
즉시 조치 (Critical)#
없음. 권한 검사 자체는 정상 동작하고 있으며 보안 문제 없음.
단기 개선 (1주 이내)#
app/operations/capture_operation.rb:33—Cupix::Errors::PermissionDenied를 별도 rescue 절로 분리하여warn레벨로 로깅. 권한 거부는 예상되는 운영 시나리오이므로error레벨이 적절하지 않다.
captures.each do |capture| Cupix::Logger.info("start reprocess captures. capture_id: #{capture.id}, user_id: #{current_user.id}") begin capture_invoker = CaptureInvoker.new(model: capture, current_user: current_user) capture_invoker.reprocess_capture results << { id: capture.id, status: 'success' }+ rescue Cupix::Errors::PermissionDenied => e+ Cupix::Logger.warn("permission denied while reprocess. capture_id: #{capture.id}, user_id: #{current_user.id}")+ results << { id: capture.id, status: 'error', error: e.message } rescue StandardError => e Cupix::Logger.error("error occurred while reprocess. capture_id: #{capture.id}, reason:#{e.message}, user_id: #{current_user.id}", reprocess: { error: e }) results << { id: capture.id, status: 'error', error: e.message } end end장기 개선 (재발 방지)#
- CLI/Admin API 엔드포인트에서 reprocess 호출 전에 사전 권한 검사를 수행하여, 권한 없는 사용자의 요청이 invoker까지 도달하지 않도록 필터링.
- API 응답에 권한 부족 사유를 명확하게 반환하여, 프론트엔드/CLI에서 사용자에게 적절한 안내 제공.
Monitoring#
- 권한 거부 빈도 추적:
service:cupixworks-worker "permission denied while reprocess"
- 특정 사용자의 반복적 권한 거부 패턴 감지 (비인가 접근 시도 모니터링):
service:cupixworks-worker status:warn "permission denied" @user_id:*
Risk Assessment#
- Risk level: low
- 예상 복잡도: trivial