---
type: knowledge
domain: security
status: active
last-reviewed: 2026-07-27
---

# 권한 설계와 접근 통제 실전

> 한 줄 정의
> 인가(authZ)는 **"확인된 사용자가 무엇을 볼 수 있고 할 수 있는가"를 서버가 강제하는 일**이다. 누구인지 확인하는 인증(authN)은 [[인증 구현 실전]], 인가 모델의 설계 결정 기준은 [[05_보안 설계]] — 여기는 구현과 통제의 규율이다.

## 권한 모델 선택 — 조합이 현실이다

| 모델 | 판정 기준 | 맞는 경우 | 한계 |
|------|----------|----------|------|
| RBAC (기본값) | 역할 → 기능 매핑 | 메뉴·기능 단위 통제 (관리자/담당자/조회자) | "내 데이터만"을 표현 못 한다 |
| 소유자 기반 | 리소스의 소유자/담당자 필드 | 건 단위 데이터 (내 케이스·내 문서) | 역할 개념이 없다 |
| 속성 조건 (ABAC류) | 부서·지역·상태 등 속성 결합 | "본인 부서 + 진행 중 건만" 같은 교차 조건 | 규칙이 늘수록 디버깅 불가 |

- 실무는 셋의 조합이다: **기능 접근은 RBAC, 데이터 접근은 소유자/속성 스코프**. "RBAC 하나로 다 된다"고 시작하면 데이터 스코프가 핸들러마다 즉흥 구현된다.
- 역할 목록과 판정 규칙은 발주사 현업과 착수 전 합의 — 검수 시점의 역할 재정의는 전 화면 재검증이다.

## 제1규율 — 서버 측 강제

- **프론트에서 버튼을 숨기고 메뉴를 지우는 것은 통제가 아니다** — API를 직접 호출하면 그대로 뚫린다. 화면 숨김은 UX이고, 인가는 모든 요청에서 서버가 판정한다.
- 기본값은 deny-by-default: 규칙에 없는 요청은 거부다 → [[백엔드 원리]]. "허용 목록에 없으면 통과"로 짜인 인가는 신규 기능마다 구멍을 낳는다.
- 인가 실패 응답에 존재 여부를 흘리지 않는다 — 남의 리소스는 403보다 404가 안전한 경우가 많다(리소스 열거 차단).

## IDOR — 목록과 단건, 둘 다 막아야 한다

식별자를 남의 것으로 바꿔 접근하는 IDOR은 실무 1위 취약점이다(원리는 [[보안 원리]]). 방어는 두 지점 모두 필요하다:

| 지점 | 규율 | 한쪽만 하면 |
|------|------|------------|
| 목록 API | 쿼리에 사용자 스코프 필터를 항상 포함 | 단건만 막으면 목록에서 남의 ID가 노출된다 |
| 단건 API | 조회·수정·삭제 전 소유/담당 검증 | 목록만 막으면 ID 추측·공유 링크로 뚫린다 |

- 검증 대상은 조회만이 아니다 — **수정·삭제·다운로드·연관 리소스(첨부·댓글)**까지 같은 판정을 통과해야 한다.

## 데이터 스코프 필터 — 공통 지점에서 강제한다

- 스코프 필터를 개별 핸들러의 선의에 맡기면 핸들러 수만큼 누락 기회가 생긴다. **사용자 세션 → 스코프 컨텍스트 → 조회 계층 쿼리 필터**로 한 경로에 일원화하고, 조회 계층 공통 지점 한 곳에서 강제한다.
- 새 조회 기능이 추가돼도 공통 지점을 지나면 자동으로 걸리는 구조가 목표다 — "이번 API만 깜빡"이 구조적으로 불가능해야 한다.
- 테넌트 단위 격리(RLS·쿼리 가드)도 같은 원리의 상위 경계다 — 격리 모델과 책임은 [[멀티테넌시 설계와 책임 경계]].

## 사용자 경로와 시스템 자동 경로는 다른 정책이다

| 경로 | 스코프 정책 | 이유 |
|------|------------|------|
| 사용자 요청 (화면·대화형 조회) | 요청자 스코프 강제 | 본인 담당 데이터만 |
| 시스템 자동 (배치·스케줄·자동 발송) | 시스템 정책 스코프 (사용자 스코프 아님) | 자동 경로에 사용자 스코프가 새면 남의 건이 누락·오처리된다 |
| 관리자 조회 | 전체 허용 + 감사 로그 필수 | 통제는 사후 추적으로 대체 |

- 스코프 컨텍스트가 요청 경계를 넘어 배치·백그라운드 작업까지 전파되면 오동작한다 — **경로별 정책 표를 명시하고, 자동 경로는 진입 시점에 스코프를 시스템 정책으로 재설정**한다.

## 관리자 권한 — 예외가 아니라 더 강한 통제 대상

- 관리자는 별도 역할로 분리하고, 관리자 행위(권한 변경·타인 데이터 조회·설정 변경)는 **감사 로그 필수** — "누가 언제 무엇을"이 재구성돼야 한다.
- 개발자 계정 상시 관리자 금지 — 운영 데이터 접근은 필요 시점에 부여하고 회수한다. 개발 편의용 전체 권한 계정의 잔존은 이관·심사에서 터진다 ([[05_보안 설계]]).
- 권한 부여·회수 자체도 권한이다 — 누가 역할을 바꿀 수 있는지까지 매트릭스에 포함한다.

## 권한 매트릭스 — 코드가 아니라 산출물이다

- **역할×기능(및 데이터 스코프) 매트릭스**는 검수·인수인계 산출물이다. 발주사가 검수에서 판정하는 것은 코드가 아니라 이 표와 실동작의 일치다 — **코드와 매트릭스의 불일치는 결함**이다.
- 매트릭스는 착수 전 합의본에서 출발해 변경 시마다 갱신한다 — 검수 직전 역공학으로 작성한 매트릭스는 픽션이다.
- 데이터·소스·로그와 마찬가지로 권한 체계 정의의 소유권은 발주사에 있다 — 임의 역할 추가·완화는 합의 사항이다.

## 안티패턴

- **"화면에 안 보이니 안전하다"** — URL 직접 입력·API 직접 호출 한 번에 무너진다. 숨김은 보호가 아니다.
- **핸들러마다 스코프 필터 복붙** — 한 곳의 누락이 곧 유출이고, 리뷰로는 잡히지 않는다. 공통 지점 강제가 답이다.
- **자동 배치에 사용자 스코프 적용** — "안전하게 하려고" 넣은 필터가 남의 담당 건을 조용히 누락시킨다. 무성 실패다.
- **테스트를 관리자 계정으로만** — 인가 결함은 일반 역할·타인 데이터로 접근해야 드러난다. 역할별 시나리오 없이 인가 검증은 없다.

## 관련 문서

- [[00_보안 허브]] — 10_보안 진입점
- [[보안 원리]] — IDOR·최소 권한·deny-by-default의 원리 정본
- [[인증 구현 실전]] — 인증(authN) 짝: 세션·토큰·OAuth
- [[05_보안 설계]] — 인가 모델의 설계 결정 기준·납품 연결
- [[멀티테넌시 설계와 책임 경계]] — 테넌트 경계·RLS·격리 책임
- [[백엔드 원리]] — 인증/인가 분리·deny-by-default
- [[보안 점검 대응 실전]] — 접근 통제 지적사항의 점검 대응
