---
title: "IAM & PAM — Gestion des Identités et Accès Privilégiés"
domain: security
subdomain: hardening
type: playbook
tags: [iam, pam, mfa, rbac, privileged-access, identity, active-directory]
difficulty: intermediate
status: stable
updated: "Fri Jun 19 2026 00:00:00 GMT+0000 (Coordinated Universal Time)"
---
## IAM vs PAM

```
IAM (Identity and Access Management)
  → Gérer QUI peut accéder à QUOI
  → Tous les utilisateurs : employés, prestataires, systèmes
  → Outils : Active Directory, Keycloak, Azure AD

PAM (Privileged Access Management)
  → Gérer les accès des comptes À HAUTS PRIVILÈGES
  → Admins, root, comptes de service critiques
  → Outils : CyberArk, HashiCorp Vault, Teleport, Smallstep
```

---

## Architecture IAM — Concepts

### RBAC (Role-Based Access Control)
```
Principe : Droits attribués via des RÔLES, pas directement aux utilisateurs

Exemple :
  Role "soc-analyst" :
    → Lecture alertes SIEM
    → Lecture/écriture TheHive
    → Lecture MISP
    → PAS d'accès serveurs de prod

  Role "soc-lead" :
    → Tout "soc-analyst"
    → Gestion utilisateurs TheHive
    → Accès Velociraptor (lecture)

  Role "admin-infra" :
    → Accès SSH serveurs (via bastion)
    → Pas d'accès SIEM

Attribution : User → (membre de) → Groupe → (a) → Role → (permet) → Permission
```

### Principle of Least Privilege
```
□ Chaque compte n'a que les droits strictement nécessaires
□ Pas de comptes partagés (1 personne = 1 compte)
□ Comptes admin séparés des comptes user (marc.admin vs marc)
□ Comptes de service avec droits minimaux et sans login interactif
□ Revue des droits trimestrielle (access review)
□ Révocation immédiate au départ d'un employé
```

---

## Active Directory — Bonnes pratiques IAM

```powershell
# Tier Model Microsoft — Séparer les comptes admin par niveau
# Tier 0 : Domain Admins, Enterprise Admins (DC uniquement)
# Tier 1 : Server Admins (serveurs membres)
# Tier 2 : Workstation Admins (postes de travail)

# Créer un compte admin Tier 0 séparé
New-ADUser -Name "marc.t0" -GivenName "Marc" -Surname "T0-Admin" `
  -UserPrincipalName "marc.t0@domain.local" `
  -Path "OU=Tier0-Admins,OU=Admin,DC=domain,DC=local" `
  -AccountPassword (ConvertTo-SecureString "P@ssw0rd!" -AsPlainText -Force) `
  -Enabled $true

# Fine-Grained Password Policy pour les admins
New-ADFineGrainedPasswordPolicy -Name "Admins-PSO" `
  -Precedence 10 `
  -MinPasswordLength 20 `
  -PasswordHistoryCount 24 `
  -MaxPasswordAge "30.00:00:00" `
  -LockoutThreshold 5 `
  -LockoutDuration "00:30:00"

Add-ADFineGrainedPasswordPolicySubject "Admins-PSO" -Subjects "Domain Admins"

# Audit des membres des groupes sensibles
Get-ADGroupMember "Domain Admins" | Select-Object Name, SamAccountName
Get-ADGroupMember "Enterprise Admins" | Select-Object Name, SamAccountName

# Comptes inactifs depuis 90 jours
$cutoff = (Get-Date).AddDays(-90)
Get-ADUser -Filter {LastLogonDate -lt $cutoff -and Enabled -eq $true} `
  -Properties LastLogonDate | Select-Object Name, LastLogonDate
```

---

## MFA — Authentification Multi-Facteurs

### Méthodes MFA (par niveau de sécurité)

| Méthode | Sécurité | Résistance phishing |
|---------|----------|---------------------|
| SMS OTP | Faible | Non (SIM swap) |
| TOTP (Google Auth, Authy) | Moyen | Non |
| Push notification (Duo) | Moyen | Non (MFA fatigue) |
| FIDO2 / WebAuthn | Très haute | Oui |
| Hardware key (YubiKey) | Très haute | Oui |

### MFA sur SSH (Linux)

```bash
# Google Authenticator PAM
apt install libpam-google-authenticator

# Pour chaque utilisateur
google-authenticator
# Répondre oui à toutes les questions
# Sauvegarder le QR code et les codes de secours

# /etc/pam.d/sshd
auth required pam_google_authenticator.so

# /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

systemctl restart sshd
```

### Keycloak — SSO + MFA centralisé

```yaml
# docker-compose.yml
services:
  keycloak:
    image: quay.io/keycloak/keycloak:24.0
    ports:
      - "8080:8080"
    environment:
      - KEYCLOAK_ADMIN=admin
      - KEYCLOAK_ADMIN_PASSWORD=ChangeMe!2026
      - KC_DB=postgres
      - KC_DB_URL=jdbc:postgresql://postgres/keycloak
      - KC_DB_USERNAME=keycloak
      - KC_DB_PASSWORD=keycloak_pass
    command: start-dev
    depends_on:
      - postgres

  postgres:
    image: postgres:15
    environment:
      - POSTGRES_DB=keycloak
      - POSTGRES_USER=keycloak
      - POSTGRES_PASSWORD=keycloak_pass
```

```
# Configuration Keycloak — Realm SOC
1. Créer Realm "soc"
2. Authentication > Required Actions > Configure OTP → enabled
3. Authentication > Flows > Browser → OTP conditionnel
4. Clients → Ajouter TheHive, Shuffle, Grafana (OIDC)
5. Users → Assigner rôles selon RBAC
```

---

## PAM — Gestion des accès privilégiés

### HashiCorp Vault — Coffre-fort des secrets

```bash
# Installation Vault
wget https://releases.hashicorp.com/vault/1.17.0/vault_1.17.0_linux_amd64.zip
unzip vault_1.17.0_linux_amd64.zip && mv vault /usr/local/bin/

# Docker
docker run -d --name vault \
  -p 8200:8200 \
  -e VAULT_DEV_ROOT_TOKEN_ID=myroot \
  -e VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200 \
  hashicorp/vault:latest

# Accès GUI : http://localhost:8200
export VAULT_ADDR='http://localhost:8200'
export VAULT_TOKEN='myroot'
```

```bash
# Stocker des secrets
vault kv put secret/database \
  host=db.internal \
  username=app_user \
  password=SuperSecret123

# Lire un secret
vault kv get secret/database
vault kv get -field=password secret/database

# Secret dynamique — Vault génère un compte DB temporaire
vault secrets enable database
vault write database/config/mydb \
  plugin_name=postgresql-database-plugin \
  connection_url="postgresql://{{username}}:{{password}}@postgres:5432/prod" \
  allowed_roles="app-role" \
  username="vault-admin" \
  password="vault-admin-pass"

vault write database/roles/app-role \
  db_name=mydb \
  creation_statements="CREATE ROLE '{{name}}' WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO '{{name}}';" \
  default_ttl="1h" \
  max_ttl="24h"

# Obtenir un credential temporaire
vault read database/creds/app-role
# → username: v-app-role-abc123
# → password: A1B2-XXXX (expire dans 1h)
```

---

### Teleport — Bastion et audit de sessions

```yaml
# docker-compose.yml
services:
  teleport:
    image: public.ecr.aws/gravitational/teleport:15
    ports:
      - "3022:3022"  # SSH
      - "3080:3080"  # Web UI + API
      - "3025:3025"  # Tunnel
    volumes:
      - ./teleport.yaml:/etc/teleport/teleport.yaml
      - teleport_data:/var/lib/teleport
    command: start

volumes:
  teleport_data:
```

```yaml
# teleport.yaml
teleport:
  nodename: teleport-server
  data_dir: /var/lib/teleport
  log:
    output: stderr
    severity: INFO

auth_service:
  enabled: yes
  cluster_name: soc-lab

ssh_service:
  enabled: yes
  labels:
    env: lab

proxy_service:
  enabled: yes
  web_listen_addr: 0.0.0.0:3080
  public_addr: teleport.soc-lab:3080
```

```bash
# Créer un admin
tctl users add admin --roles=editor,access,auditor

# Connexion SSH via Teleport (avec MFA)
tsh login --proxy=teleport.soc-lab:3080 --user=marc
tsh ssh user@serveur

# Audit des sessions (enregistrement vidéo)
# Web UI : https://teleport.soc-lab:3080/web/cluster/soc-lab/audit/events
```

---

## Checklist IAM/PAM

```
IAM
□ Tous les comptes nominatifs (pas de comptes génériques)
□ MFA activé sur tous les accès (VPN, SSH, web apps)
□ RBAC configuré — revue trimestrielle des droits
□ Offboarding immédiat (désactivation J0)
□ SSO centralisé (Keycloak) pour les apps internes
□ Logs d'authentification collectés dans le SIEM

PAM
□ Comptes admin séparés des comptes user
□ Mots de passe admin stockés dans Vault (rotation auto)
□ Accès serveurs uniquement via bastion (Teleport)
□ Sessions admin enregistrées (audit complet)
□ Credentials applicatifs dans Vault (pas dans le code)
□ Credentials de service à rotation automatique (TTL)
□ Break-glass account pour urgence (monitored)
```
