ログインしたからといって権限が生まれるわけではない
한국어 원문으로 표시합니다.
한 줄 요약
인증(authentication) 은 "누구인가", 인가(authorization) 는 "무엇을 할 수 있는가" 입니다. 클라우드는 이 둘을 완전히 분리해 두었고, 그래서 로그인에 성공해도 아무것도 못 하는 상태가 정상입니다.
왜 이게 필요했나
401 과 403 을 구분하지 못하면 디버깅이 두 배로 오래 걸립니다.
| 응답 | 뜻 | 고칠 곳 |
|---|---|---|
| 401 Unauthorized | 누군지 모르겠다 | 자격증명·토큰·서명 |
| 403 Forbidden | 누군지 알지만 안 된다 | 정책·권한 |
이름이 헷갈리게 붙었습니다 — 401 이 실은 인증 실패이고 403 이 인가 실패입니다.
클라우드 API 에서 AccessDenied 를 받으면 그건 403 계열이고, 자격증명은
정상이라는 뜻입니다. 키를 다시 발급받아도 소용없습니다.
어떻게 동작하나
주체(principal)의 종류
권한은 "사람" 에게만 붙지 않습니다.
| 주체 | 예 | 특징 |
|---|---|---|
| 사용자(user) | 담당자 계정 | 장기 자격증명. 사람이 로그인 |
| 그룹(group) | developers |
사용자 묶음. 권한을 모아 준다 |
| 역할(role) | ec2-app-role |
누구든 맡을 수 있다. 임시 자격증명 |
| 서비스 | 람다 함수, EC2 인스턴스 | 역할을 맡아 동작한다 |
| 외부 신원 | 구글·깃허브 OIDC | 연합으로 역할을 맡는다 |
여기서 역할이 핵심 개념입니다. 사람이 아니라 "권한 묶음" 이고, 조건을 만족하는 주체가 잠시 빌려 씁니다. 뒤 모듈에서 자세히 다룹니다.
평가 순서 — 명시적 거부가 이긴다
여러 정책이 한 주체에 붙어 있을 때 결과는 이렇게 정해집니다.
1. 명시적 Deny 가 하나라도 있으면 → 거부 (무엇도 이를 뒤집지 못한다)
2. 명시적 Allow 가 하나라도 있으면 → 허용
3. 아무것도 없으면 → 거부 (기본 거부)
두 가지가 중요합니다.
- 기본이 거부입니다. 권한은 더해야만 생깁니다. 안전한 기본값입니다.
- Deny 가 절대 우선입니다. 관리자 권한이 있어도 조직 차원의 Deny 하나면 막힙니다. 가드레일을 만드는 방법이 이것입니다.
정책이 붙는 두 자리
같은 결과를 두 방향에서 만들 수 있습니다.
- 신원 기반(identity-based) — 주체에 붙인다. "이 사람은 저 버킷을 읽을 수 있다"
- 자원 기반(resource-based) — 자원에 붙인다. "이 버킷은 저 사람이 읽을 수 있다"
계정 안에서는 보통 신원 기반만 씁니다. 계정을 넘어가면 양쪽이 다 필요합니다 — 남의 계정 주체가 우리 버킷을 읽으려면, 그쪽 신원 정책에 허용이 있고 우리 버킷 정책에도 허용이 있어야 합니다. 크로스 계정 접근이 자주 실패하는 이유입니다.
현장에서 만나는 모습
AccessDenied를 받고 키를 재발급 → 인가 문제라 아무 효과 없음.- 관리자인데 특정 동작만 막힘 → 상위 조직 정책의 Deny.
- 크로스 계정 접근이 안 됨 → 한쪽에만 허용을 넣었다.
거부당했을 때 무엇을 보나
AccessDenied 를 받았을 때 아무 곳이나 뒤지지 않으려면, 확인 순서를 정해 두어야 한다. 클라우드에서 하나의 요청이 허용되기까지 통과해야 하는 관문이 여럿이기 때문이다.
- 내가 지금 누구인가. 생각한 주체가 맞는지부터 본다. 인스턴스에서 도는 코드는 대개 붙어 있는 역할로 동작하는데, 사람들은 자기 개인 자격 증명으로 시험해 보고 "되는데요" 라고 말한다. 현재 주체를 출력하는 명령이 어느 클라우드에나 있으니 그것부터 찍는다.
- 어느 관문에서 막혔는가. 조직 차원의 정책, 신원 정책, 자원 정책, 그리고 임시 자격 증명을 발급할 때 좁혀 둔 범위. 이 중 하나라도 허용하지 않으면 거부다.
- 동작 이름과 자원 이름이 정확한가. 정책에 적은 동작 이름의 오타는 오류를 내지 않고 그냥 안 맞는 규칙이 된다. 자원 표기도 마찬가지로, 버킷 자체와 그 안의 객체는 서로 다른 자원이라 둘 다 필요한 경우가 흔하다.
- 조건이 붙어 있지 않은가. 출발지 IP, 시각, 태그, 다중 인증 여부 같은 조건이 붙어 있으면 평소에는 되다가 특정 상황에서만 막힌다. "어제는 됐는데" 라는 신고의 상당수가 여기서 나옵니다.
그리고 판정을 추측하지 말고 도구로 물어보는 습관이 중요하다. 주요 클라우드는 "이 주체가 이 동작을 이 자원에 할 수 있는가" 를 실제로 평가해 주는 기능을 제공하고, 어느 정책이 결정을 내렸는지까지 알려 준다. 정책 문서를 눈으로 읽어 추론하는 것보다 몇 배 빠르고, 사람이 놓치기 쉬운 상위 조직 정책까지 포함해 답한다.
마지막으로 로그를 본다. 거부된 요청은 감사 로그에 남고, 거기에는 주체·동작·자원·시각이 전부 들어 있다. 개발자가 말로 전한 증상보다 이 한 줄이 훨씬 정확하므로, 조사의 출발점은 언제나 이 기록이어야 한다.
다음에 볼 것
그 정책 문서가 실제로 어떻게 생겼는지 한 줄씩 뜯어봅니다.