La sécurité des données est une responsabilité du Data Engineer, pas seulement du RSSI. En entretien, on évalue la capacité à concevoir des architectures qui protègent les données par défaut.
1Chiffrement at-rest et in-transit
Question discriminante
Quelle est la différence entre chiffrement at-rest et in-transit ? Comment les implémentez-vous ?
- At-rest — les données sont chiffrées quand elles sont stockées. S3 SSE-S3/SSE-KMS, BigQuery encryption, Snowflake BYOK
- In-transit — les données sont chiffrées pendant le transport. TLS 1.2+ obligatoire, HTTPS pour les APIs
- At-use (Confidential Computing) — les données sont chiffrées même pendant le traitement. GCP Confidential VMs
- CMEK (Customer Managed Encryption Keys) — gérer ses propres clés de chiffrement dans Cloud KMS pour les données très sensibles
- Chiffrement des colonnes PII — chiffrer individuellement les colonnes contenant des données personnelles (email, IBAN) dans le data warehouse
2Gestion des secrets : jamais en dur
Question discriminante
Quelles sont les règles absolues pour la gestion des secrets dans un pipeline data ?
# JAMAIS : credentials en dur dans le code
conn = psycopg2.connect(password='motdepasse123') # NON
# Bonne pratique 1 : variables d environnement
import os
conn = psycopg2.connect(password=os.environ['DB_PASSWORD'])
# Bonne pratique 2 : Secret Manager (GCP/AWS)
from google.cloud import secretmanager
def get_secret(name: str) -> str:
client = secretmanager.SecretManagerServiceClient()
secret = client.access_secret_version(name=name)
return secret.payload.data.decode('UTF-8')
# Bonne pratique 3 : Workload Identity (zéro credential)
# Le service s authentifie via son identité cloud
# Aucun secret à stocker ou à faire tourner
# Bonne pratique 4 : .gitignore strict
# .env, *.pem, credentials.json, *_key.json
3Contrôle d accès RBAC
Question discriminante
Comment implémentez-vous le principe du moindre privilège dans votre stack data ?
- Principe du moindre privilège — chaque service et utilisateur n a accès qu à ce dont il a strictement besoin
- Service accounts dédiés — un service account par pipeline. Jamais un compte admin partagé
- Rôles Snowflake/BigQuery — créer des rôles par fonction (INGESTION_ROLE, TRANSFORM_ROLE, BI_ROLE) avec des permissions précises
- Time-limited access — pour les accès temporaires (debug, audit), utiliser des tokens à durée de vie limitée
- Review des accès — auditer trimestriellement qui a accès à quoi. Révoquer les accès inactifs
4Anonymisation et pseudonymisation techniques
Question discriminante
Comment anonymisez-vous techniquement les données PII dans votre data warehouse ?
-- Pseudonymisation : hashage avec sel (réversible avec le sel)
SELECT
SHA256(email || 'sel_secret_2025') AS email_hash,
SHA256(phone || 'sel_secret_2025') AS phone_hash,
-- données non-PII conservées
age_bucket,
region
FROM users;
-- Masquage dynamique Snowflake : montrer selon le rôle
CREATE OR REPLACE MASKING POLICY email_mask AS
(val STRING) RETURNS STRING ->
CASE
WHEN CURRENT_ROLE() IN ('DATA_ANALYST_PII') THEN val
ELSE REGEXP_REPLACE(val, '.+@', '****@')
END;
ALTER TABLE users MODIFY COLUMN email
SET MASKING POLICY email_mask;
-- Généralisation : remplacer valeur précise par intervalle
SELECT
CASE
WHEN age < 25 THEN '18-24'
WHEN age < 35 THEN '25-34'
ELSE '35+'
END AS age_bracket
FROM users;
5Audit logs : tracer tous les accès
Question discriminante
Comment implémentez-vous les audit logs sur votre data warehouse ?
- Snowflake Access History — qui a accédé à quelle table, à quelle heure, quelles colonnes
- BigQuery Data Access audit logs — activés dans Cloud Audit Logs. Chaque requête BigQuery est loguée
- Rétention des logs — RGPD : conserver les logs d accès suffisamment longtemps pour auditer les incidents
- Alertes sur accès anormaux — alerter si un utilisateur accède à 100x plus de données que d habitude
6Secure by default : le principe
Question discriminante
Qu est-ce que 'secure by default' dans une architecture data ?
- Accès refusé par défaut — aucun accès sans grant explicite. Contraire d un bucket S3 public par défaut
- Chiffrement activé par défaut — activer le chiffrement at-rest sur tous les services dès la création
- Pas d accès internet direct — les pipelines data tournent dans un VPC sans accès internet. Utiliser des Private Endpoints
- Scanning automatique des secrets — git-secrets, truffleHog dans la CI pour détecter les credentials avant le push
from google.cloud import secretmanager
import os
# JAMAIS : credentials en dur
# conn = psycopg2.connect(password='motdepasse123') ← NON
# Bonne pratique 1 : Secret Manager (GCP)
def get_secret(project_id: str, secret_name: str) -> str:
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/{secret_name}/versions/latest"
response = client.access_secret_version(request={"name": name})
return response.payload.data.decode("UTF-8")
# Bonne pratique 2 : Workload Identity (zéro credential)
# Le pod K8s s'authentifie via son service account → accès GCS sans stocker de clé
# Configurer dans GKE : gcloud iam service-accounts add-iam-policy-binding ...
# Bonne pratique 3 : Variables d'environnement + secrets K8s
import os
db_password = os.environ.get("DB_PASSWORD") # injecté par K8s Secret ou HashiCorp Vault
# Scanning automatique des secrets dans Git
# Pre-commit hook avec detect-secrets :
# pip install detect-secrets
# detect-secrets scan > .secrets.baseline
# detect-secrets audit .secrets.baseline
- Workload Identity Federation — le standard moderne pour AWS/GCP : les services s'authentifient via leur identité cloud sans aucune clé à stocker. Elimine les rotation de secrets
- HashiCorp Vault — secrets dynamiques (credentials qui expirent après N minutes), audit complet des accès, multi-cloud. Standard en entreprise pour les secrets centralisés
- Dynamic masking Snowflake/BigQuery — masquer les colonnes PII (email, IBAN) selon le rôle de l'utilisateur au moment de la requête, sans toucher aux données stockées
- Column-level encryption — chiffrer individuellement les colonnes PII dans le data warehouse avec des clés gérées par le client (BYOK/CMEK). Protection même si la DB est compromise
- Audit logs obligatoires — BigQuery Data Access logs, Snowflake Access History, CloudTrail AWS. Rétention minimale 1 an pour la conformité RGPD et les audits de sécurité
7Grille par niveau
| Niveau | Maitrise | Signal GO | NO-GO |
|---|
| Confirmé | Secrets dans variables d env, TLS, RBAC basique | N a jamais de credentials en dur dans le code, utilise des variables d environnement | Stocke des mots de passe dans le code ou les logs |
| Senior | Secret Manager, Workload Identity, dynamic masking, audit logs | Utilise Workload Identity ou Secret Manager, a mis en place le dynamic masking | Ne sait pas ce qu est Workload Identity |
1Encryption at-rest and in-transit
Discriminating question
What is the difference between at-rest and in-transit encryption? How do you implement them?
- At-rest — data is encrypted when stored. S3 SSE-S3/SSE-KMS, BigQuery encryption, Snowflake BYOK
- In-transit — data is encrypted during transport. TLS 1.2+ required, HTTPS for APIs
- At-use (Confidential Computing) — data is encrypted even during processing. GCP Confidential VMs
- CMEK (Customer Managed Encryption Keys) — manage your own encryption keys in Cloud KMS for highly sensitive data
- PII column encryption — individually encrypt columns containing personal data (email, IBAN) in the data warehouse
2Secrets management: never hardcoded
Discriminating question
What are the absolute rules for secrets management in a data pipeline?
# NEVER : hardcoded credentials in code
conn = psycopg2.connect(password='motdepasse123') # NO
# Best practice 1 : environment variables
import os
conn = psycopg2.connect(password=os.environ['DB_PASSWORD'])
# Best practice 2 : Secret Manager (GCP/AWS)
from google.cloud import secretmanager
def get_secret(name: str) -> str:
client = secretmanager.SecretManagerServiceClient()
secret = client.access_secret_version(name=name)
return secret.payload.data.decode('UTF-8')
# Best practice 3 : Workload Identity (zero credential)
# The service authenticates via its cloud identity
# No secret to store or rotate
# Best practice 4 : strict .gitignore
# .env, *.pem, credentials.json, *_key.json
3RBAC access control
Discriminating question
How do you implement the principle of least privilege in your data stack?
- Principle of least privilege — each service and user only has access to what they strictly need
- Dedicated service accounts — one service account per pipeline. Never a shared admin account
- Snowflake/BigQuery roles — create roles by function (INGESTION_ROLE, TRANSFORM_ROLE, BI_ROLE) with precise permissions
- Time-limited access — for temporary access (debug, audit), use tokens with a limited lifetime
- Access review — quarterly audit of who has access to what. Revoke inactive access
4Anonymization and pseudonymization techniques
Discriminating question
How do you technically anonymize PII data in your data warehouse?
-- Pseudonymization : hashing with salt (reversible with the salt)
SELECT
SHA256(email || 'secret_salt_2025') AS email_hash,
SHA256(phone || 'secret_salt_2025') AS phone_hash,
-- non-PII data preserved
age_bucket,
region
FROM users;
-- Snowflake dynamic masking : display based on role
CREATE OR REPLACE MASKING POLICY email_mask AS
(val STRING) RETURNS STRING ->
CASE
WHEN CURRENT_ROLE() IN ('DATA_ANALYST_PII') THEN val
ELSE REGEXP_REPLACE(val, '.+@', '****@')
END;
ALTER TABLE users MODIFY COLUMN email
SET MASKING POLICY email_mask;
-- Generalization : replace exact value with range
SELECT
CASE
WHEN age < 25 THEN '18-24'
WHEN age < 35 THEN '25-34'
ELSE '35+'
END AS age_bracket
FROM users;
5Audit logs: tracking all access
Discriminating question
How do you implement audit logs on your data warehouse?
- Snowflake Access History — who accessed which table, at what time, which columns
- BigQuery Data Access audit logs — enabled in Cloud Audit Logs. Every BigQuery query is logged
- Log retention — GDPR: retain access logs long enough to audit incidents
- Alerts on abnormal access — alert if a user accesses 100x more data than usual
6Secure by default: the principle
Discriminating question
What does 'secure by default' mean in a data architecture?
- Access denied by default — no access without explicit grant. Opposite of a public S3 bucket by default
- Encryption enabled by default — enable at-rest encryption on all services upon creation
- No direct internet access — data pipelines run in a VPC without internet access. Use Private Endpoints
- Automatic secrets scanning — git-secrets, truffleHog in CI to detect credentials before push
from google.cloud import secretmanager
import os
# NEVER : hardcoded credentials
# conn = psycopg2.connect(password='motdepasse123') ← NO
# Best practice 1 : Secret Manager (GCP)
def get_secret(project_id: str, secret_name: str) -> str:
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/{secret_name}/versions/latest"
response = client.access_secret_version(request={"name": name})
return response.payload.data.decode("UTF-8")
# Best practice 2 : Workload Identity (zero credential)
# The K8s pod authenticates via its service account → GCS access without storing a key
# Configure in GKE : gcloud iam service-accounts add-iam-policy-binding ...
# Best practice 3 : Environment variables + K8s secrets
import os
db_password = os.environ.get("DB_PASSWORD") # injected by K8s Secret or HashiCorp Vault
# Automatic secrets scanning in Git
# Pre-commit hook with detect-secrets :
# pip install detect-secrets
# detect-secrets scan > .secrets.baseline
# detect-secrets audit .secrets.baseline
- Workload Identity Federation — the modern standard for AWS/GCP: services authenticate via their cloud identity with no key to store. Eliminates secret rotation
- HashiCorp Vault — dynamic secrets (credentials that expire after N minutes), full access audit, multi-cloud. Enterprise standard for centralized secrets
- Dynamic masking Snowflake/BigQuery — mask PII columns (email, IBAN) based on the user's role at query time, without touching stored data
- Column-level encryption — individually encrypt PII columns in the data warehouse with customer-managed keys (BYOK/CMEK). Protection even if the DB is compromised
- Mandatory audit logs — BigQuery Data Access logs, Snowflake Access History, AWS CloudTrail. Minimum 1-year retention for GDPR compliance and security audits
7Level grid
| Level | Mastery | GO signal | NO-GO |
|---|
| Mid-level | Secrets in environment variables, TLS, basic RBAC | Never has hardcoded credentials in code, uses environment variables | Stores passwords in code or logs |
| Senior | Secret Manager, Workload Identity, dynamic masking, audit logs | Uses Workload Identity or Secret Manager, has implemented dynamic masking | Does not know what Workload Identity is |