Azure RBAC 와 Azure Policy (권한과 규칙)
"누가 무엇을 할 수 있나" 를 정하는 Azure RBAC(역할 정의, 범위, 할당, 제어 평면과 데이터 평면, PIM, 한도)와 "무엇을 어떻게 만들 수 있나" 를 정하는 Azure Policy(효과, 이니셔티브, 수정 작업, 예외)를 함께 정리합니다.
두 가지를 구분하기
| Azure RBAC | Azure Policy | |
|---|---|---|
| 질문 | 누가 이 작업을 할 수 있나 | 이 리소스가 규칙에 맞나 |
| 대상 | 사용자, 그룹, 서비스 주체, 관리 ID | 리소스의 속성 (리전, SKU, 태그, 네트워크 설정) |
| 거부 예 | Reader 가 VM 을 지우려 함 | Owner 가 East US 에 VM 을 만들려는데 허용 리전이 Korea Central 뿐 |
| 오류 코드 | AuthorizationFailed | RequestDisallowedByPolicy |
둘 다 관리 그룹, 구독, 리소스 그룹, 리소스 범위에 걸 수 있고 아래로 상속됩니다 (리소스 계층 참고).
RBAC 의 세 요소
역할 할당은 보안 주체(누구) + 역할 정의(무엇) + 범위(어디) 의 조합입니다.
자주 쓰는 기본 제공 역할입니다.
| 역할 | 할 수 있는 일 |
|---|---|
| Owner | 모든 것 + 역할 할당 |
| Contributor | 모든 것, 단 역할 할당과 일부 정책 작업은 못 함 |
| Reader | 읽기만 |
| User Access Administrator | 역할 할당만 |
| Role Based Access Control Administrator | 역할 할당만, 조건으로 줄 수 있는 역할을 제한 가능 |
| Storage Blob Data Contributor | Blob 데이터 읽기, 쓰기, 지우기 (데이터 평면) |
| Key Vault Secrets User | 비밀 값 읽기 (데이터 평면) |
제어 평면과 데이터 평면
역할 정의에는 actions(제어 평면)와 dataActions(데이터 평면)가 따로 있습니다. Contributor 나 Owner 도 dataActions 가 없어서 Blob 내용을 Entra 인증으로 읽지 못합니다. 스토리지 계정 키를 꺼낼 수 있어서 읽히는 것처럼 보일 뿐입니다. 키 인증을 끄면(allowSharedKeyAccess: false) Storage Blob Data 역할이 따로 필요합니다.
# 그룹에 리소스 그룹 범위로 역할 주기
az role assignment create --assignee-object-id <group-object-id> --assignee-principal-type Group \
--role "Contributor" --scope /subscriptions/<sub>/resourceGroups/rg-shop-dev
# 누가 무엇을 가졌나 (상속 포함)
az role assignment list --scope /subscriptions/<sub>/resourceGroups/rg-shop-dev --include-inherited -o table사용자 지정 역할
기본 역할이 너무 넓으면 사용자 지정 역할을 만듭니다. assignableScopes 로 쓸 수 있는 범위를 제한합니다.
{
"Name": "VM Operator (start, stop)",
"Actions": [
"Microsoft.Compute/virtualMachines/read",
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/deallocate/action",
"Microsoft.Compute/virtualMachines/restart/action"
],
"NotActions": [],
"AssignableScopes": ["/subscriptions/00000000-0000-0000-0000-000000000000"]
}NotActions 는 거부가 아니라 "이 역할에서 뺀다" 는 뜻입니다. 다른 역할이 그 작업을 주면 여전히 할 수 있습니다. 진짜 거부는 거부 할당(deny assignment)이고, 사용자가 직접 만들 수는 없고 배포 스택이나 관리형 앱 같은 기능이 만듭니다.
한도와 PIM
| 한도 (2026-10 기준) | 값 |
|---|---|
| 구독당 역할 할당 (구독, 리소스 그룹, 리소스 범위 합계) | 5,000 (늘릴 수 없음) |
| 관리 그룹당 역할 할당 | 500 |
| 테넌트당 사용자 지정 역할 | 5,000 |
한도에 걸리면 RoleAssignmentLimitExceeded 가 납니다. 개인 대신 그룹에 주고, 아래 범위의 중복 할당을 지우는 것이 첫 대응입니다. PIM(Privileged Identity Management) 의 적격(eligible) 할당은 한도에 세지 않고, 필요할 때만 승인과 MFA 를 거쳐 정해진 시간 동안 활성화되므로 보안과 한도 모두에 좋습니다. PIM 은 Microsoft Entra ID P2 가 필요합니다.
Azure Policy
정책 정의는 "조건 + 효과" 입니다. 여러 정의를 묶은 것이 이니셔티브(정책 집합) 이고, 범위에 거는 것이 할당 입니다.
| 효과 | 동작 |
|---|---|
Deny | 조건에 맞는 만들기, 바꾸기 요청을 거부 |
Audit | 허용하되 비준수로 표시 |
Modify | 태그나 속성을 자동으로 추가, 변경 (관리 ID 필요) |
DeployIfNotExists | 없으면 관련 리소스를 배포 (예: 진단 설정) |
AuditIfNotExists | 관련 리소스가 없으면 비준수 |
DenyAction | 지우기 같은 특정 작업을 막음 |
Disabled | 끔. 매개 변수로 효과를 바꿀 수 있게 만들면 편함 |
{
"if": {
"not": { "field": "location", "in": "[parameters('allowedLocations')]" }
},
"then": { "effect": "deny" }
}기본 제공 정의만으로도 많은 것을 할 수 있습니다. "Allowed locations", "Require a tag on resources", "Storage accounts should disable public network access", "Configure diagnostic settings to Log Analytics" 같은 정의를 먼저 찾아봅니다. 보안 기준은 Defender for Cloud 가 쓰는 Microsoft cloud security benchmark 이니셔티브가 출발점입니다.
기존 리소스와 수정 작업
정책은 할당 뒤 새로 만들거나 바꾸는 리소스에 즉시 적용되지만, 이미 있는 리소스의 준수 상태 평가는 주기적으로 돕니다. Modify 와 DeployIfNotExists 는 기존 리소스를 자동으로 고치지 않으므로 수정 작업(remediation task) 을 따로 실행합니다.
az policy state trigger-scan --resource-group rg-shop-prod
az policy remediation create --name fix-diag --policy-assignment <assignment-id> --resource-group rg-shop-prod예외와 단계적 도입
- 운영 중인 환경에 처음 정책을 넣을 때는
Audit으로 걸어 영향을 본 뒤Deny로 바꿉니다. - 할당의 적용 모드(enforcementMode) 를
DoNotEnforce로 두면 평가만 하고 막지 않습니다. - 꼭 필요한 예외는 리소스를 정책 범위에서 빼기보다 정책 예외(exemption) 를 만료일과 함께 남깁니다. 누가 왜 뺐는지 기록이 남습니다.
설계 요령
- 사람에게는 리소스 그룹 범위의 Contributor 나 더 좁은 역할을, 운영 Owner 는 PIM 적격 할당으로만 줍니다.
- 앱에는 관리 ID 와 데이터 평면 역할(Storage Blob Data Reader, Key Vault Secrets User)을 리소스 범위로 줍니다.
- 허용 리전, 필수 태그, 공용 네트워크 차단, 진단 설정은 관리 그룹 수준 이니셔티브로 겁니다.
- 정책과 역할 할당도 Bicep 이나 Terraform으로 관리해 검토 기록을 남깁니다.