أمان IAM والهوية
أفضل ممارسات إدارة بيانات الاعتماد
4 دقيقة للقراءة
بيانات الاعتماد هي ناقل الهجوم الأساسي لخروقات السحابة. دراسة Palo Alto Networks 2024 وجدت أكثر من 90,000 ملف .env مسرب، منها 1,185 تحتوي مفاتيح وصول AWS نشطة. الإدارة السليمة لبيانات الاعتماد غير قابلة للتفاوض.
تسلسل بيانات الاعتماد الهرمي
ليست كل بيانات الاعتماد متساوية. رتب الأولويات حسب المخاطر:
| نوع بيانات الاعتماد | مستوى المخاطر | التوصية |
|---|---|---|
| حساب Root | حرج | مفتاح MFA مادي، لا مفاتيح وصول أبداً |
| مستخدمي IAM المديرين | عالي | MFA مطلوب، جلسات محدودة الوقت |
| حسابات الخدمة | عالي | أدوار بدلاً من مفاتيح، تدوير منتظم |
| مفاتيح المطورين | متوسط | قصيرة العمر، مراقبة، نطاق محدود |
| رموز التطبيقات | متوسط | أسرار مدارة، تدوير تلقائي |
إزالة بيانات الاعتماد طويلة العمر
AWS: استخدم الأدوار بدلاً من المفاتيح
المشكلة:
# ملف .env للمطور (موجود في 90,000+ ملف مسرب)
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
الحل - أدوار EC2 Instance:
# CloudFormation - ربط الدور بـ EC2
Resources:
MyInstance:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref MyInstanceProfile
# لا بيانات اعتماد في الـ instance - يوفرها STS
MyInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- !Ref MyRole
MyRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
Azure: استخدم Managed Identities
المشكلة:
# Service principal مع client secret
az ad sp create-for-rbac --name "MyApp" --password "SuperSecretPassword123"
الحل - Managed Identity:
# إنشاء VM مع system-assigned managed identity
az vm create \
--name MyVM \
--resource-group MyRG \
--assign-identity '[system]'
# كود التطبيق - لا حاجة لبيانات اعتماد
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential() # تستخدم managed identity تلقائياً
GCP: استخدم Workload Identity
المشكلة:
# مفتاح service account منزّل (كابوس أمني)
gcloud iam service-accounts keys create key.json
export GOOGLE_APPLICATION_CREDENTIALS=./key.json
الحل - Workload Identity لـ GKE:
# Kubernetes service account مع ربط GCP
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-ksa
annotations:
iam.gke.io/gcp-service-account: my-sa@project.iam.gserviceaccount.com
# ربط KSA بـ GSA
gcloud iam service-accounts add-iam-policy-binding \
my-sa@project.iam.gserviceaccount.com \
--role="roles/iam.workloadIdentityUser" \
--member="serviceAccount:project.svc.id.goog[namespace/my-ksa]"
إدارة الأسرار
عندما تكون بيانات الاعتماد ضرورية، أدرها بشكل صحيح:
AWS Secrets Manager
import boto3
from botocore.exceptions import ClientError
def get_secret(secret_name):
client = boto3.client('secretsmanager')
response = client.get_secret_value(SecretId=secret_name)
return response['SecretString']
# تفعيل التدوير التلقائي
# aws secretsmanager rotate-secret --secret-id MySecret --rotation-rules ...
Azure Key Vault
from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
client = SecretClient(vault_url="https://my-vault.vault.azure.net/", credential=credential)
secret = client.get_secret("DatabasePassword")
password = secret.value
HashiCorp Vault
# تخزين السر
vault kv put secret/myapp/config db_password="secret123"
# الاسترجاع مع وصول قائم على TTL
vault kv get -format=json secret/myapp/config
استراتيجيات تدوير المفاتيح
تدوير مفاتيح الوصول AWS
#!/bin/bash
# تدوير مفاتيح الوصول لمستخدم IAM
USER="application-user"
# إنشاء مفتاح جديد
NEW_KEY=$(aws iam create-access-key --user-name $USER --query 'AccessKey')
# تحديث التطبيق بالمفتاح الجديد (خاص بالتطبيق)
# ...
# اختبار عمل المفتاح الجديد
# ...
# حذف المفتاح القديم
aws iam delete-access-key --user-name $USER --access-key-id $OLD_KEY_ID
التدوير الآلي مع Lambda
import boto3
import json
def lambda_handler(event, context):
sm_client = boto3.client('secretsmanager')
secret_id = event['SecretId']
step = event['Step']
if step == 'createSecret':
# توليد بيانات اعتماد جديدة
new_password = generate_secure_password()
sm_client.put_secret_value(
SecretId=secret_id,
SecretString=json.dumps({'password': new_password}),
VersionStages=['AWSPENDING']
)
elif step == 'setSecret':
# تحديث الخدمة ببيانات الاعتماد الجديدة
update_database_password(secret_id)
elif step == 'testSecret':
# التحقق من عمل بيانات الاعتماد الجديدة
test_connection(secret_id)
elif step == 'finishSecret':
# ترقية pending إلى current
sm_client.update_secret_version_stage(
SecretId=secret_id,
VersionStage='AWSCURRENT',
MoveToVersionId=event['ClientRequestToken']
)
الاستجابة الطارئة لبيانات الاعتماد
عند اختراق بيانات الاعتماد:
| الإجراء | أمر AWS | الأولوية |
|---|---|---|
| تعطيل المفتاح فوراً | aws iam update-access-key --status Inactive |
1 |
| إلغاء الجلسات النشطة | حذف inline policy للدور، فرض إعادة المصادقة | 2 |
| تدقيق CloudTrail | البحث عن استخدام المفتاح المخترق | 3 |
| تدوير جميع الأسرار ذات الصلة | تحديث الأنظمة المعتمدة | 4 |
| التحقيق في السبب الجذري | كيف تسربت المفاتيح؟ | 5 |
# طوارئ: تعطيل جميع مفاتيح الوصول لمستخدم
aws iam list-access-keys --user-name compromised-user | \
jq -r '.AccessKeyMetadata[].AccessKeyId' | \
xargs -I {} aws iam update-access-key --user-name compromised-user \
--access-key-id {} --status Inactive
التالي، سنستكشف تقوية المصادقة مع MFA وسياسات الوصول المشروط. :::