Identity & Access Management
1 - Défis IAM Multi-Cloud
1.1 Problématique
| Défi | Description |
|---|---|
| Identités multiples | Un user = N comptes cloud |
| Politiques différentes | Syntaxe et concepts différents |
| Audit fragmenté | Logs dispersés |
| Rotation credentials | Complexe à automatiser |
2 - SSO avec Identity Provider
2.1 Architecture centralisée
2.2 AWS SAML avec Azure AD
# AWS - SAML Provider
resource "aws_iam_saml_provider" "azure_ad" {
name = "AzureAD"
saml_metadata_document = file("azure-ad-metadata.xml")
}
# AWS - Rôle assumable via SAML
resource "aws_iam_role" "admin_saml" {
name = "AzureAD-Admin"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Federated = aws_iam_saml_provider.azure_ad.arn
}
Action = "sts:AssumeRoleWithSAML"
Condition = {
StringEquals = {
"SAML:aud" = "https://signin.aws.amazon.com/saml"
}
}
}
]
})
}
resource "aws_iam_role_policy_attachment" "admin_saml" {
role = aws_iam_role.admin_saml.name
policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
}
2.3 GCP Workload Identity Federation
# GCP - Workload Identity Pool
resource "google_iam_workload_identity_pool" "azure" {
workload_identity_pool_id = "azure-pool"
display_name = "Azure AD Pool"
}
# GCP - OIDC Provider
resource "google_iam_workload_identity_pool_provider" "azure_oidc" {
workload_identity_pool_id = google_iam_workload_identity_pool.azure.workload_identity_pool_id
workload_identity_pool_provider_id = "azure-oidc"
oidc {
issuer_uri = "https://login.microsoftonline.com/${var.azure_tenant_id}/v2.0"
}
attribute_mapping = {
"google.subject" = "assertion.sub"
"attribute.aud" = "assertion.aud"
}
}
3 - Service Accounts Cross-Cloud
3.1 AWS vers GCP
# GCP - Service Account
resource "google_service_account" "cross_cloud" {
account_id = "aws-cross-cloud"
display_name = "AWS Cross Cloud Access"
}
# GCP - IAM pour Workload Identity
resource "google_service_account_iam_binding" "aws_access" {
service_account_id = google_service_account.cross_cloud.name
role = "roles/iam.workloadIdentityUser"
members = [
"principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.aws.name}/attribute.aws_role/arn:aws:iam::123456789:role/GCPAccess"
]
}
# Python - Accès GCP depuis AWS
import google.auth
from google.auth import aws
credentials = aws.Credentials(
audience="//iam.googleapis.com/projects/123/locations/global/workloadIdentityPools/aws-pool/providers/aws-provider",
subject_token_type="urn:ietf:params:aws:token-type:aws4_request",
service_account_impersonation_url=f"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/aws-cross-cloud@{project}.iam.gserviceaccount.com:generateAccessToken"
)
# Utiliser les credentials
from google.cloud import storage
client = storage.Client(credentials=credentials)
3.2 Azure vers AWS
# AWS - Rôle pour Azure
resource "aws_iam_role" "azure_access" {
name = "AzureServiceAccess"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Federated = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/sts.windows.net/${var.azure_tenant_id}/"
}
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = {
"sts.windows.net/${var.azure_tenant_id}/:aud" = var.azure_app_id
}
}
}
]
})
}
4 - Secrets Management Unifié
4.1 HashiCorp Vault
4.2 Configuration Vault Multi-Cloud
# Vault - AWS Secrets Engine
resource "vault_aws_secret_backend" "aws" {
access_key = var.aws_access_key
secret_key = var.aws_secret_key
region = "eu-west-1"
path = "aws"
}
resource "vault_aws_secret_backend_role" "deploy" {
backend = vault_aws_secret_backend.aws.path
name = "deploy"
credential_type = "assumed_role"
role_arns = ["arn:aws:iam::123456789:role/DeployRole"]
}
# Vault - Azure Secrets Engine
resource "vault_azure_secret_backend" "azure" {
subscription_id = var.azure_subscription_id
tenant_id = var.azure_tenant_id
client_id = var.azure_client_id
client_secret = var.azure_client_secret
path = "azure"
}
# Vault - GCP Secrets Engine
resource "vault_gcp_secret_backend" "gcp" {
credentials = file("gcp-sa.json")
path = "gcp"
}
4.3 Utilisation dans Kubernetes
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: vault-secrets
spec:
provider: vault
parameters:
vaultAddress: "https://vault.example.com"
roleName: "k8s-role"
objects: |
- objectName: "aws-creds"
secretPath: "aws/creds/deploy"
secretKey: "access_key"
- objectName: "azure-creds"
secretPath: "azure/creds/deploy"
secretKey: "client_secret"
---
apiVersion: v1
kind: Pod
spec:
volumes:
- name: secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "vault-secrets"
5 - RBAC unifié
5.1 Mapping des rôles
| Rôle | AWS | Azure | GCP |
|---|---|---|---|
| Admin | AdministratorAccess | Owner | Owner |
| DevOps | PowerUserAccess | Contributor | Editor |
| Dev | Developer | Developer | Developer |
| ReadOnly | ViewOnlyAccess | Reader | Viewer |
5.2 Terraform pour RBAC cohérent
# Variables communes
variable "devops_users" {
type = list(string)
default = ["[email protected]", "[email protected]"]
}
# AWS
resource "aws_iam_group" "devops" {
name = "devops"
}
resource "aws_iam_group_policy_attachment" "devops" {
group = aws_iam_group.devops.name
policy_arn = "arn:aws:iam::aws:policy/PowerUserAccess"
}
# Azure
resource "azurerm_role_assignment" "devops" {
for_each = toset(var.devops_users)
scope = data.azurerm_subscription.current.id
role_definition_name = "Contributor"
principal_id = data.azuread_user.users[each.key].object_id
}
# GCP
resource "google_project_iam_member" "devops" {
for_each = toset(var.devops_users)
project = var.gcp_project_id
role = "roles/editor"
member = "user:${each.key}"
}
6 - Audit centralisé
6.1 Collecter les logs
# Centralisation dans Datadog/Splunk/ELK
sources:
aws:
- CloudTrail
- CloudWatch Logs
azure:
- Activity Log
- Azure AD Sign-in logs
gcp:
- Cloud Audit Logs
- Access Transparency logs
6.2 Alertes unifiées
# Règles d'alerte communes
alerts:
- name: "Privileged Access"
condition: |
(aws.eventName IN ["AssumeRole", "CreateUser", "AttachUserPolicy"])
OR (azure.operationName CONTAINS "roleAssignments/write")
OR (gcp.methodName CONTAINS "SetIamPolicy")
severity: high
- name: "Failed Authentication"
condition: |
(aws.errorCode == "AccessDenied")
OR (azure.resultType == "Failure")
OR (gcp.status.code != 0)
severity: medium
Résumé
Dans ce chapitre, nous avons appris :
- Les défis IAM Multi-Cloud
- Le SSO avec Identity Provider
- Les Service Accounts cross-cloud
- HashiCorp Vault pour les secrets
- Le RBAC unifié
- L'audit centralisé
Prochaine étape
Dans le prochain chapitre, nous verrons la Gestion des données.
→ Chapitre suivant : Gestion des données