Lý Thuyết Cốt Lõi
1. Triển Khai RBAC — Nền Tảng Phân Quyền Azure
RBAC (Role-Based Access Control) là hệ thống phân quyền của Azure, hoạt động theo 3 thành phần: Security Principal (ai), Role Definition (làm được gì), và Scope (phạm vi nào). Mô hình "Deny by default" — mọi quyền phải được cấp tường minh, không có quyền ngầm định.
- • User: tài khoản cá nhân trong Entra ID
- • Group: gán role cho group → tất cả member được thừa hưởng
- • Service Principal: identity cho ứng dụng/dịch vụ
- • Managed Identity: identity tự quản bởi Azure cho resource
- • JSON file định nghĩa tập Actions được phép
- •
Actions: quyền control plane (quản lý resource) - •
DataActions: quyền data plane (đọc/ghi dữ liệu) - •
NotActions: loại trừ khỏi Actions
- • Management Group → Subscription → Resource Group → Resource
- • Role gán ở scope cha tự động kế thừa xuống scope con
- • Không thể giới hạn quyền đã kế thừa bằng cách deny ở scope con (ngoại trừ Deny Assignment)
- • Nguyên tắc: gán ở scope nhỏ nhất cần thiết (least privilege)
2. Role Definition — Các Role Quan Trọng
| Built-in Role | Quyền hạn | Gán role cho người khác? |
|---|---|---|
| Owner | Toàn quyền tất cả resource | Có |
| Contributor | Tạo/sửa/xóa resource, không quản lý quyền | Không |
| Reader | Chỉ xem, không thay đổi bất cứ thứ gì | Không |
| User Access Administrator | Chỉ quản lý quyền (không tạo resource) | Có |
| Virtual Machine Contributor | Quản lý VM nhưng không truy cập network/storage | Không |
| Storage Blob Data Reader | Đọc dữ liệu blob (DataActions), không quản lý storage account | Không |
- • Built-in role quá rộng (Contributor cho phép xóa VM, bạn chỉ muốn start/stop)
- • Cần kết hợp nhiều quyền từ nhiều service
- • Tối đa 5.000 custom roles per tenant
- •
AssignableScopes: chỉ định sub/MG nào có thể dùng role này
- •
*= mọi thao tác - •
Microsoft.Compute/*= mọi thao tác Compute - •
Microsoft.Compute/*/read= đọc mọi resource Compute - • NotActions không phải "deny" — chỉ là loại trừ khỏi wildcard
3. Role Assignment — Gán Quyền Thực Tế
Role Assignment là hành động kết nối Security Principal + Role Definition + Scope. Mỗi assignment là 1 record riêng biệt. Tối đa 4.000 role assignments per subscription.
- • Gán role cho Group thay vì User riêng lẻ — dễ quản lý, dễ audit
- • Dùng Managed Identity cho resource/app thay vì store credential
- • Review định kỳ qua Access Reviews (Entra ID P2)
- • Dùng PIM (Privileged Identity Management) cho quyền nhạy cảm: just-in-time access
- • Portal → Resource → Access Control (IAM) → Check Access
- • Nhập email/Object ID của user → xem tất cả roles kế thừa
- • CLI:
az role assignment list --assignee <email> - • CLI:
az role assignment list --allđể xuất toàn bộ assignments
4. So Sánh Azure Roles vs Microsoft Entra Roles
Đây là điểm thường gây nhầm lẫn trong kỳ thi. Azure RBAC roles và Entra ID roles là hai hệ thống hoàn toàn độc lập, quản lý hai phạm vi khác nhau.
| Tiêu chí | Azure RBAC Roles | Entra ID Roles |
|---|---|---|
| Quản lý thứ gì | Azure resources (VM, Storage, VNet…) | Entra ID objects (Users, Groups, Apps…) |
| Scope | MG / Sub / RG / Resource | Tenant-wide (toàn bộ Entra tenant) |
| Cấp phép qua | Azure Portal → IAM → Role assignments | Entra Portal → Roles and administrators |
| Custom role | Hỗ trợ (tạo JSON với Actions) | Hỗ trợ (Entra ID P1 trở lên) |
| Ví dụ role quan trọng | Owner, Contributor, Reader | Global Administrator, User Administrator, Billing Administrator |
| Giao nhau? | Global Administrator có thể "Elevate" thành User Access Admin trên Root MG — đây là điểm giao duy nhất | |
Bài Tập Thực Hành (Lab)
Tạo Resource Group và gán Built-in Role cho User
SUB_ID=$(az account show --query id -o tsv)
# Tạo Resource Group
az group create \
--name rg-az104-m05 \
--location southeastasia \
--tags Course=AZ-104 Module=05 Environment=Lab
# Tạo test user trong Entra ID
az ad user create \
--display-name "RBAC Test User" \
--user-principal-name rbactestuser@$(az account show --query tenantId -o tsv).onmicrosoft.com \
--password "P@ssw0rd2024!" \
--force-change-password-next-sign-in false
# Lấy Object ID của user vừa tạo
USER_OID=$(az ad user list \
--display-name "RBAC Test User" \
--query "[0].id" -o tsv)
echo "User OID: $USER_OID"
# Gán role Reader tại scope Resource Group
az role assignment create \
--assignee $USER_OID \
--role "Reader" \
--scope "/subscriptions/$SUB_ID/resourceGroups/rg-az104-m05"
echo "Reader role assigned to RBAC Test User on rg-az104-m05"
Tạo Custom Role — Storage Reader nhưng không xóa được
SUB_ID=$(az account show --query id -o tsv)
# Tạo custom role definition JSON
cat > /tmp/storage-reader-nodelete.json << EOF
{
"Name": "Storage Reader No Delete",
"Description": "Xem storage accounts và đọc blob data, nhưng không được xóa",
"Actions": [
"Microsoft.Storage/storageAccounts/read",
"Microsoft.Storage/storageAccounts/listKeys/action",
"Microsoft.Resources/subscriptions/resourceGroups/read"
],
"NotActions": [
"Microsoft.Storage/storageAccounts/delete"
],
"DataActions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read"
],
"NotDataActions": [],
"AssignableScopes": [
"/subscriptions/$SUB_ID"
]
}
EOF
# Tạo custom role
az role definition create \
--role-definition /tmp/storage-reader-nodelete.json
echo "Custom role 'Storage Reader No Delete' created"
# Gán custom role cho test user tại RG scope
USER_OID=$(az ad user list --display-name "RBAC Test User" --query "[0].id" -o tsv)
az role assignment create \
--assignee $USER_OID \
--role "Storage Reader No Delete" \
--scope "/subscriptions/$SUB_ID/resourceGroups/rg-az104-m05"
Tạo Storage Account và kiểm tra Effective Access
SUB_ID=$(az account show --query id -o tsv)
USER_OID=$(az ad user list --display-name "RBAC Test User" --query "[0].id" -o tsv)
# Tạo Storage Account để test
STORAGE_NAME="stm05rbac$(date +%s | tail -c 5)"
az storage account create \
--name $STORAGE_NAME \
--resource-group rg-az104-m05 \
--location southeastasia \
--sku Standard_LRS \
--kind StorageV2 \
--tags Course=AZ-104 Module=05
echo "Storage account: $STORAGE_NAME"
# Xem tất cả role assignments của user tại RG này
az role assignment list \
--assignee $USER_OID \
--scope "/subscriptions/$SUB_ID/resourceGroups/rg-az104-m05" \
--include-inherited \
-o table
# Xem tất cả role assignments toàn subscription (bao gồm kế thừa)
az role assignment list \
--assignee $USER_OID \
--all \
--include-inherited \
-o table
Cấu hình System-Assigned Managed Identity cho VM
SUB_ID=$(az account show --query id -o tsv)
# Tạo VM nhỏ với System-Assigned Managed Identity
az vm create \
--resource-group rg-az104-m05 \
--name vm-rbac-test \
--image Ubuntu2204 \
--size Standard_B1s \
--admin-username azureuser \
--generate-ssh-keys \
--assign-identity \
--location southeastasia \
--tags Course=AZ-104 Module=05
# Lấy Principal ID của Managed Identity
MI_PRINCIPAL=$(az vm show \
--resource-group rg-az104-m05 \
--name vm-rbac-test \
--query "identity.principalId" -o tsv)
echo "Managed Identity Principal ID: $MI_PRINCIPAL"
# Gán role Storage Blob Data Reader cho Managed Identity
# Để VM có thể đọc blob mà không cần credential
az role assignment create \
--assignee $MI_PRINCIPAL \
--role "Storage Blob Data Reader" \
--scope "/subscriptions/$SUB_ID/resourceGroups/rg-az104-m05"
echo "Storage Blob Data Reader assigned to VM Managed Identity"
Cleanup — Dọn dẹp tài nguyên
SUB_ID=$(az account show --query id -o tsv)
# Xóa role assignments trước khi xóa user/role
USER_OID=$(az ad user list --display-name "RBAC Test User" --query "[0].id" -o tsv)
az role assignment delete \
--assignee $USER_OID \
--role "Reader" \
--scope "/subscriptions/$SUB_ID/resourceGroups/rg-az104-m05"
az role assignment delete \
--assignee $USER_OID \
--role "Storage Reader No Delete" \
--scope "/subscriptions/$SUB_ID/resourceGroups/rg-az104-m05"
# Xóa custom role definition (bắt buộc xóa hết assignments trước)
az role definition delete --name "Storage Reader No Delete"
# Xóa test user
az ad user delete --id $USER_OID
# Xóa Resource Group (xóa VM, storage, và toàn bộ resource)
az group delete --name rg-az104-m05 --yes --no-wait
Kết Quả Đầu Ra
Thực hành gán Owner/Contributor/Reader tại MG, Subscription, RG, Resource theo nguyên tắc least privilege
Viết JSON custom role với Actions, NotActions, DataActions, AssignableScopes đúng cú pháp
Nắm rõ hai hệ thống độc lập, không nhầm lẫn Global Admin với Owner, User Admin với RBAC
Enable System-assigned MI cho VM, gán RBAC role cho MI, loại bỏ nhu cầu lưu credential trong code
Dùng "Check Access" trên Portal và az role assignment list để xem permissions thực tế của user
Nắm cơ chế kế thừa từ scope cha xuống con, giới hạn tối đa 4.000 assignments per subscription
Ứng Dụng Thực Tế
Tình huống 1: Công ty phần mềm — DevOps team phân quyền theo môi trường
Dev team cần tự do trong môi trường Dev/Staging, nhưng Production phải kiểm soát chặt. 50 developer, 5 DevOps senior, 2 DBA.
3 Security Groups: SG-Dev (Contributor trên RG dev/staging), SG-DevOps-Senior (Contributor trên RG prod), SG-DBA (custom role: SQL Server Contributor only). Thêm user vào group thay vì gán role trực tiếp.
PIM (Privileged Identity Management) cho role Owner trên Production — chỉ active khi cần, có approval, audit log đầy đủ. CI/CD pipeline dùng Service Principal với Contributor trên RG prod, tự động rotate secret.
Developer onboard/offboard: chỉ thêm/xóa khỏi group. Zero standing access trên Production. Mọi thao tác prod được audit log. Giảm 95% risk do quyền sai.
Tình huống 2: Chuỗi F&B — App đọc secret từ Key Vault không cần password
App .NET chạy trên Azure App Service cần đọc connection string từ Key Vault. Lưu credential trong config file không an toàn.
Enable System-assigned Managed Identity cho App Service. Gán role "Key Vault Secrets User" cho MI. App dùng DefaultAzureCredential trong SDK — tự động lấy token từ MI mà không cần username/password.
Key Vault Access Policy hoặc RBAC mode đều được. Recommend: RBAC mode (Key Vault Secrets User role). Không lưu secret nào trong appsettings.json. CI/CD pipeline cũng dùng Managed Identity thay Service Principal khi có thể.
Zero credentials trong code hay config. Azure quản lý vòng đời credential. Developer không biết password Key Vault. Audit log mọi lần app đọc secret. Đáp ứng ISO 27001 về bảo vệ credential.
Tình huống 3: Công ty kiểm toán — Vendor ngoài cần review hạ tầng Azure
Công ty kiểm toán BigFour cần xem cấu hình Azure để lập báo cáo tuân thủ. Họ không được phép thay đổi bất cứ thứ gì.
Mời email tài khoản của công ty kiểm toán làm B2B Guest user. Gán role Reader tại Subscription scope. Tạo custom role "Auditor View" chỉ có quyền read + list, không có listKeys (không xem được secret keys).
Set expiration date cho Guest account (30 ngày). Conditional Access: chỉ cho phép truy cập từ IP công ty kiểm toán. Sau kiểm toán: disable account và export audit log Activity Log toàn bộ hành động của Guest.
Kiểm toán viên thấy đúng thứ họ cần. Không cấp VPN hay account nội bộ. Sau kiểm toán cleanup tức thì. Activity Log ghi đầy đủ mọi thứ kiểm toán viên đã xem — sẵn sàng cho kiểm toán nội bộ tiếp theo.