MISE EN PLACE DE CONJUR

1. Introduction

1.1. Présentation de Conjur

Conjur est une solution de gestion des secrets et des identités développée par CyberArk. Elle permet de stocker, gérer et distribuer des secrets de manière centralisée et sécurisée. Son intégration avec des environnements cloud, tels qu’OpenShift, renforce la sécurité des applications en leur permettant d’accéder aux secrets sans les stocker directement dans le cluster.

Principales fonctionnalités de Conjur

  • Stockage sécurisé des secrets avec un contrôle d’accès basé sur des politiques.
  • Authentification centralisée, permettant aux applications et aux services d’accéder aux secrets de manière sécurisée.
  • Audit et traçabilité des accès aux secrets.
  • Rotation et mise à jour dynamique des secrets sans interruption des services.

1.2. Problématique et justification de l’intégration avec OpenShift

Dans un cluster OpenShift, les applications ont souvent besoin d’accéder à des informations sensibles telles que des identifiants de bases de données, des clés API ou des certificats. Kubernetes propose nativement des objets Secret pour stocker ces informations, mais ils présentent plusieurs limites :

  • Absence de chiffrement natif des secrets au repos, à moins d’activer une couche de chiffrement spécifique.
  • Manque de contrôle d’accès avancé, les secrets étant accessibles à tout pod disposant des permissions appropriées.
  • Absence de mécanisme de rotation automatique, obligeant à redéployer les applications en cas de mise à jour d’un secret.

L’intégration de Conjur avec OpenShift permet de :

  • Renforcer la sécurité des secrets en les stockant hors du cluster Kubernetes.
  • Limiter les accès en utilisant un modèle d’autorisation basé sur des ServiceAccounts et des Namespaces.
  • Faciliter la rotation des secrets sans nécessiter de redéploiement des applications.
  • Garantir une meilleure traçabilité grâce à l’audit des accès aux secrets.

1.3. Architecture et fonctionnement général

L’intégration de Conjur avec OpenShift repose sur les composants suivants :

  • Un Conjur Follower qui agit comme un relais entre les applications OpenShift et le Conjur Master.
  • Un Secret Provider (CyberArk Secret Provider for Kubernetes) déployé dans chaque Namespace pour récupérer les secrets depuis Conjur.
  • Un ServiceAccount spécifique dans chaque Namespace, utilisé pour l’authentification auprès de Conjur via un jeton JWT.
  • Des objets Secret Kubernetes, mis à jour dynamiquement par le Secret Provider après récupération des valeurs depuis Conjur.

Schéma général du fonctionnement

  1. Un pod dans OpenShift requiert un secret (db-credentials).
  2. Le Secret Provider envoie une requête d’authentification JWT au Conjur Follower.
  3. Le Conjur Follower valide l’accès en fonction du Namespace et du ServiceAccount associé.
  4. Si l’accès est autorisé, Conjur retourne la valeur du secret.
  5. Le Secret Provider injecte la valeur récupérée dans un Secret Kubernetes.
  6. L’application consomme ce secret via une variable d’environnement ou un fichier monté.

1.4. Avantages de l’intégration

L’adoption de Conjur dans un environnement OpenShift offre plusieurs bénéfices :

AvantageDescription
Sécurité renforcéeLes secrets ne sont pas stockés directement dans Kubernetes, réduisant ainsi les risques d’exposition.
Contrôle d’accès avancéL’accès aux secrets est basé sur l’identité du ServiceAccount et du Namespace, limitant l’exposition aux seuls composants autorisés.
Rotation dynamique des secretsLes secrets peuvent être mis à jour sans nécessiter un redéploiement des applications.
Audit et conformitéToutes les actions liées aux secrets sont enregistrées et peuvent être auditées.

1.5. Objectif du guide

Ce guide a pour objectif de détailler l’implémentation de Conjur dans un environnement OpenShift. Il couvre l’ensemble des étapes, de la configuration initiale à l’utilisation des secrets dans les applications, en passant par les bonnes pratiques de sécurité et la gestion de la rotation des secrets.

Les prochaines sections aborderont :

  • Les prérequis techniques et l’architecture détaillée.
  • La mise en place des composants nécessaires dans OpenShift.
  • La récupération et l’utilisation des secrets au sein des pods.
  • Les stratégies avancées pour sécuriser les accès et optimiser la gestion des secrets.

2. Prérequis et Architecture

2.1. Composants nécessaires

L’intégration de Conjur avec OpenShift repose sur plusieurs éléments indispensables. Avant de procéder à la configuration, il est essentiel de s’assurer que l’environnement dispose des composants suivants :

2.1.1. OpenShift et ses ressources

  • Un cluster OpenShift opérationnel (version 4.x recommandée).
  • Un Namespace dédié pour chaque application nécessitant l’accès aux secrets.
  • Un ServiceAccount dans chaque Namespace, utilisé pour l’authentification auprès de Conjur.
  • Un mécanisme de RBAC (Role-Based Access Control) pour restreindre l’accès aux secrets.
  • Le CyberArk Secret Provider for Kubernetes, qui récupère les secrets depuis Conjur et les injecte dans Kubernetes.

2.1.2. Conjur et ses composants

  • Un Conjur Master (gestion des secrets et des policies d’accès).
  • Un Conjur Follower, accessible depuis OpenShift, qui sert les requêtes de récupération des secrets.
  • Une policy Conjur définissant quels ServiceAccounts et Namespaces sont autorisés à accéder aux secrets.
  • Un certificat TLS valide pour sécuriser les communications entre OpenShift et Conjur.

2.1.3. Outils nécessaires

  • oc (OpenShift CLI) : pour interagir avec le cluster OpenShift.
  • curl ou kubectl : pour tester l’accès aux services et vérifier l’état des ressources.
  • CyberArk CLI (summon ou conjur) : pour administrer Conjur et gérer les secrets.

2.2. Schéma de l’architecture

L’intégration repose sur un modèle où chaque Namespace dispose d’un Secret Provider dédié, tandis qu’un Conjur Follower unique est utilisé pour gérer l’authentification et la récupération des secrets.

2.2.1. Description de l’architecture

  1. Un pod dans OpenShift requiert un secret (db-credentials).
  2. Le Secret Provider, exécuté sous forme de Job ou CronJob, contacte le Conjur Follower.
  3. Le Conjur Follower valide l’identité du ServiceAccount et du Namespace à l’aide d’un jeton JWT.
  4. Si l’accès est autorisé, les valeurs des secrets sont retournées.
  5. Le Secret Provider met à jour un Secret Kubernetes, rendant les secrets accessibles aux pods.
  6. L’application consomme ces secrets via des variables d’environnement ou des volumes montés.

2.3. Prérequis techniques

2.3.1. Configuration réseau

  • OpenShift doit pouvoir atteindre le Conjur Follower (via un service interne ou une URL externe).
  • L’authentification JWT doit être activée dans Conjur pour OpenShift.
  • Un certificat TLS valide doit être utilisé pour sécuriser les échanges.

2.3.2. Permissions et authentification

  • Chaque ServiceAccount doit être lié à une policy Conjur permettant l’accès aux secrets.
  • Un Role et un RoleBinding doivent être créés pour permettre au Secret Provider de mettre à jour les Secrets Kubernetes.

2.3.3. Configuration Conjur

  • Définition des policies pour autoriser l’accès aux secrets par Namespace et ServiceAccount.
  • Vérification que le Conjur Follower est accessible depuis OpenShift.
  • Configuration du mécanisme d’authentification JWT.

3. Déploiement et Configuration

3.1. Création des ServiceAccounts et permissions RBAC

L’accès aux secrets Conjur repose sur une authentification basée sur les ServiceAccounts OpenShift et un modèle de permissions via RBAC (Role-Based Access Control). Cette section détaille les étapes pour configurer ces éléments.

3.1.1. Création du ServiceAccount

Chaque namespace nécessitant un accès aux secrets Conjur doit disposer d’un ServiceAccount dédié. Ce ServiceAccount sera utilisé par le Secret Provider pour s’authentifier auprès de Conjur.

Commande pour créer un ServiceAccount dans un namespace spécifique (app-namespace) :

Equivalent en YAML :

👉 Ce ServiceAccount sera utilisé pour générer un jeton JWT, qui servira à l’authentification auprès de Conjur.


3.1.2. Création des permissions RBAC

Le ServiceAccount conjur-sa doit disposer des permissions nécessaires pour accéder et modifier les secrets dans OpenShift.

Définition du Role pour la gestion des secrets

Ce rôle permet au ServiceAccount de créer, mettre à jour et lire les secrets.


Association du Role au ServiceAccount via un RoleBinding


👉 Le ServiceAccount conjur-sa peut désormais gérer les secrets Kubernetes dans son namespace.

3.2. Configuration du Secret Kubernetes (conjur-map-secret)

Le conjur-map-secret est un objet Secret Kubernetes qui contient un mapping entre les clés des secrets et leurs chemins réels dans Conjur.

3.2.1. Définition du conjur-map-secret

👉 Ce fichier indique au Secret Provider où récupérer les secrets dans Conjur.

Application du Secret Kubernetes :


3.3. Création du ConfigMap Conjur

Un ConfigMap est nécessaire pour stocker les informations de connexion au Conjur Follower.

Application du ConfigMap :

👉 Ce ConfigMap est utilisé par le Secret Provider pour interagir avec Conjur.


3.4. Déploiement du CyberArk Secret Provider

Le CyberArk Secret Provider est un pod qui interroge Conjur pour récupérer les secrets et les injecter dans Kubernetes. Il peut être déployé sous forme de Job ou de CronJob.

3.4.1. Déploiement en tant que Job (exécution unique)





👉 Ce Job interroge Conjur et injecte les secrets récupérés dans Kubernetes.

Déploiement du Job :

3.4.2. Déploiement en tant que CronJob (rafraîchissement automatique)

Si les secrets doivent être mis à jour régulièrement, un CronJob peut être utilisé.

👉 Ce CronJob rafraîchit automatiquement les secrets toutes les 5 minutes.

Déploiement du CronJob :


3.5. Détails des ConfigMaps et du Secret Provider

L’intégration de Conjur avec OpenShift repose sur deux composants essentiels : les ConfigMaps et le Secret Provider. Cette section détaille leur rôle, leur configuration et leur interaction avec les autres éléments du cluster.


3.5.1. Qu’est-ce qu’un ConfigMap et pourquoi est-il utilisé dans Conjur ?

Un ConfigMap est un objet Kubernetes qui permet de stocker des données de configuration sous forme de paires clé-valeur. Contrairement aux Secrets Kubernetes, un ConfigMap n’est pas destiné à contenir des informations sensibles, mais il est utile pour stocker des paramètres de connexion ou de configuration.

Pourquoi un ConfigMap est nécessaire pour Conjur ?

Dans le cadre de l’intégration avec Conjur, le ConfigMap est utilisé pour :

  1. Stocker les informations de connexion au Conjur Follower (URL du serveur, compte Conjur utilisé, méthode d’authentification, etc.).
  2. Fournir le certificat TLS permettant de sécuriser les échanges entre OpenShift et Conjur.
  3. Éviter de coder en dur ces valeurs dans le déploiement du Secret Provider, garantissant ainsi une plus grande flexibilité.

Exemple de ConfigMap conjur-connect

Le ConfigMap suivant contient les paramètres nécessaires à l’authentification auprès de Conjur :


Explication des paramètres

CléDescription
CONJUR_ACCOUNTIndique le compte Conjur utilisé pour l’authentification.
CONJUR_APPLIANCE_URLDéfinit l’URL du Conjur Follower qui servira les requêtes.
CONJUR_AUTHN_URLSpécifie l’URL du service d’authentification JWT dans Conjur.
CONJUR_SSL_CERTIFICATEContient le certificat TLS utilisé pour sécuriser les échanges entre OpenShift et Conjur.



3.5.2. Explication détaillée du Secret Provider et son rôle dans OpenShift

Le CyberArk Secret Provider for Kubernetes est un conteneur chargé de récupérer les secrets stockés dans Conjur et de les injecter dans Kubernetes sous forme de Secrets Kubernetes.

Rôle du Secret Provider

  1. S’authentifie auprès de Conjur en utilisant un jeton JWT basé sur le ServiceAccount OpenShift.
  2. Demande les valeurs des secrets stockés dans Conjur en utilisant les chemins définis dans le conjur-map-secret.
  3. Met à jour les Secrets Kubernetes dans le namespace de l’application pour les rendre accessibles aux pods.

Modes d’exécution du Secret Provider

Le Secret Provider peut fonctionner de deux manières :

  • Job Kubernetes : Exécute une requête unique vers Conjur, récupère les secrets et les injecte dans Kubernetes.
  • CronJob Kubernetes : Effectue cette action à intervalles réguliers pour garantir que les secrets restent à jour.

3.5.3. Analyse des principales variables d’environnement du Secret Provider

Le comportement du Secret Provider est contrôlé par plusieurs variables d’environnement.

Exemple de déploiement du Secret Provider avec les variables clés





Explication des variables

VariableDescription
JWT_TOKEN_PATHSpécifie l’emplacement du token JWT utilisé pour l’authentification auprès de Conjur.
SECRETS_DESTINATIONIndique où doivent être stockés les secrets récupérés (k8s_secrets pour Kubernetes, file pour un stockage en fichier).
K8S_SECRETSSpécifie le nom du Secret Kubernetes où les valeurs des secrets seront injectées.
envFrom: configMapRefCharge les paramètres de connexion depuis le ConfigMap conjur-connect.

3.5.4. Flux détaillé du fonctionnement du Secret Provider

Le Secret Provider suit un processus en plusieurs étapes pour extraire et injecter les secrets.

1️⃣ Authentification auprès de Conjur

  • Le Secret Provider utilise le ServiceAccount OpenShift pour obtenir un token JWT.
  • Il envoie une requête d’authentification au Conjur Follower.
POST https://conjur-follower.conjur.svc.cluster.local/authn-jwt/openshift-cluster/login
Authorization: Bearer <JWT-TOKEN>

Si l’authentification réussit, Conjur retourne un token temporaire qui sera utilisé pour récupérer les secrets.


2️⃣ Demande des secrets auprès de Conjur

Une fois authentifié, le Secret Provider envoie une requête GET pour chaque secret à récupérer.

Exemple de requête pour récupérer un secret :

GET https://conjur-follower.conjur.svc.cluster.local/secrets/cyberark/variable/vault/Database/Credentials/username
Authorization: Token token="<CONJUR-TOKEN>"

Si l’accès est autorisé, Conjur renvoie la valeur du secret sous forme JSON :


3️⃣ Injection des secrets dans Kubernetes

Le Secret Provider injecte ensuite ces valeurs dans un Secret Kubernetes.

Exemple de Secret Kubernetes après mise à jour :


👉 Les pods peuvent désormais consommer ces secrets sous forme de variables d’environnement.

Validation

À ce stade, l’environnement OpenShift est configuré pour récupérer les secrets depuis Conjur.
Points de vérification :

  • Le ServiceAccount conjur-sa est bien créé.
  • Les permissions RBAC (Role et RoleBinding) sont en place.
  • Le conjur-map-secret et le ConfigMap conjur-connect sont correctement appliqués.
  • Le Job ou CronJob Secret Provider fonctionne sans erreur.

4. Vérifications et Validation

Une fois le déploiement terminé, il est essentiel de s’assurer que tous les composants fonctionnent correctement et que les secrets sont bien injectés dans OpenShift. Cette section détaille les différentes vérifications à effectuer pour valider l’intégration de Conjur avec OpenShift.


4.1. Vérification de la présence du Conjur Follower

Le Conjur Follower est un composant central de l’architecture. Il doit être accessible depuis OpenShift pour que les requêtes d’authentification et de récupération de secrets aboutissent.

4.1.1. Vérification des services Conjur dans OpenShift

La première étape consiste à vérifier que le service Conjur est bien exposé dans OpenShift.

Commande pour lister les services dans le namespace conjur:

Résultat attendu :

Si le service conjur-follower n’apparaît pas, il faut vérifier :

  • Que le déploiement du Follower est bien actif (oc get pods -n conjur).
  • Que les logs du Follower ne contiennent pas d’erreurs (oc logs <nom-du-pod> -n conjur).

4.1.2. Test d’accessibilité du Conjur Follower depuis OpenShift

Depuis un pod OpenShift, il est possible de tester l’accès au Conjur Follower avec curl.

Dans le shell du pod :


Résultat attendu :

Si la réponse est différente ou absente, il faut :

  • Vérifier les règles de Network Policy.
  • Confirmer que le DNS Kubernetes résout correctement le service conjur-follower.

4.2. Vérification du Secret Provider

Le Secret Provider est responsable de la récupération et de l’injection des secrets dans Kubernetes. Plusieurs vérifications permettent de s’assurer qu’il fonctionne correctement.

4.2.1. Vérification des pods du Secret Provider

Commande pour lister les pods exécutant le Secret Provider :

Résultat attendu :

Si le pod est en erreur (CrashLoopBackOff, Error), il est nécessaire de consulter les logs pour identifier le problème.

4.2.2. Vérification des logs du Secret Provider





Résultat attendu (exemple) :


Si les logs affichent des erreurs d’authentification (403 Forbidden), il faut :

  • Vérifier que le ServiceAccount est correctement lié à la policy Conjur.
  • Vérifier que le ConfigMap conjur-connect contient bien l’URL correcte du Follower.

4.3. Vérification des Secrets dans Kubernetes

Une fois que le Secret Provider a récupéré les secrets depuis Conjur, il doit les stocker sous forme de Secret Kubernetes.

4.3.1. Vérification de la présence du Secret Kubernetes

Commande pour lister les Secrets Kubernetes dans le namespace :

Résultat attendu :


Le secret db-credentials est bien créé.


4.3.2. Vérification du contenu du Secret Kubernetes

Les valeurs des secrets stockées dans Kubernetes sont encodées en Base64. Il est possible de les afficher en décodant leur contenu.

Commande pour afficher les clés disponibles dans le Secret :

Résultat attendu (exemple) :

Commande pour décoder la valeur d’un secret :

oc get secret db-credentials -n app-namespace -o jsonpath='{.data.username}' | base64 --decode

Résultat attendu :

my-database-username

Si la valeur retournée est vide ou incorrecte :

  • Vérifier les logs du Secret Provider (oc logs secrets-provider-xyz123 -n app-namespace).
  • Vérifier la correspondance entre les chemins définis dans conjur-map-secret et ceux stockés dans Conjur.

4.4. Validation finale avec une application

Une fois le secret injecté dans Kubernetes, il peut être consommé par un pod OpenShift.

4.4.1. Déploiement d’un pod de test utilisant le secret


Déploiement du pod :
oc apply -f secret-test-pod.yaml

Attente de l’exécution :

oc logs secret-test-pod -n app-namespace

Résultat attendu :

my-database-username

Si aucune valeur n’est affichée :

  • Vérifier que le secret est bien référencé dans la spécification du pod.
  • Vérifier que le nom de la clé dans secretKeyRef correspond bien à celle stockée dans Kubernetes.

4.5. Résolution des erreurs courantes

ProblèmeCause possibleSolution
403 Forbidden lors de l’authentification à ConjurLe ServiceAccount n’a pas les permissions requisesVérifier la policy Conjur associée au ServiceAccount.
Le Secret Provider ne récupère pas les secretsMauvaise configuration du conjur-map-secretVérifier que les chemins dans conjur-map-secret correspondent aux secrets Conjur.
Le pod de test ne récupère pas le secretLe Secret Kubernetes n’est pas injecté correctementVérifier la présence du secret avec oc get secrets -n app-namespace.

Validation

À l’issue de ces vérifications : ✅ Le Conjur Follower est bien accessible.
Le Secret Provider s’authentifie correctement et injecte les secrets dans Kubernetes.
Les pods OpenShift peuvent consommer les secrets sans erreur.

Peux-tu valider cette section ? Si elle est conforme, nous poursuivrons avec la section 5 sur la sécurisation des secrets.

5. Sécurisation des Secrets

L’intégration de Conjur avec OpenShift permet d’améliorer la gestion des secrets, mais sans mesures de sécurité adaptées, ces secrets restent exposés à des risques potentiels. Cette section détaille les meilleures pratiques pour protéger l’accès aux secrets à chaque niveau de l’architecture.


5.1. Limitation des accès via RBAC

Le contrôle d’accès basé sur les rôles (RBAC) est essentiel pour s’assurer que seuls les pods autorisés peuvent accéder aux secrets.

5.1.1. Restrictions sur l’accès aux Secrets Kubernetes

Par défaut, tout pod dans un namespace peut potentiellement lire les secrets s’il dispose des bonnes permissions RBAC. Il est donc crucial de limiter cet accès.

Création d’un Role restreignant l’accès aux secrets :

👉 Ce rôle permet uniquement la lecture (get) du secret db-credentials.

Association à un RoleBinding spécifique à un ServiceAccount :

👉 Seuls les pods exécutés avec le ServiceAccount app-sa pourront accéder au secret.


5.1.2. Restriction des accès dans Conjur

Dans Conjur, les accès sont définis via des policies. Il est recommandé de limiter les accès aux secrets au strict minimum.

Exemple de policy Conjur :


👉 Seuls les pods exécutés avec ServiceAccount app-sa dans app-namespace pourront lire le secret.


5.2. Chiffrement des Secrets Kubernetes

Par défaut, les secrets Kubernetes sont stockés en clair dans etcd, ce qui représente un risque si un attaquant accède à cette base de données.

5.2.1. Activation du chiffrement des secrets

Kubernetes permet de chiffrer les secrets au repos en configurant kube-apiserver avec un fichier EncryptionConfiguration.

Exemple de fichier de chiffrement (EncryptionConfiguration.yaml) :


👉 Ce fichier indique que les secrets seront chiffrés avec AES-CBC.

Une fois configuré, il faut redémarrer kube-apiserver pour appliquer les changements.


5.3. Alternative : Récupération directe en mémoire

Si les secrets ne doivent jamais être stockés dans Kubernetes, il est possible d’utiliser un Init Container pour récupérer les secrets directement depuis Conjur sans les injecter dans un Secret Kubernetes.

5.3.1. Utilisation d’un Init Container pour récupérer les secrets



👉 Le secret est récupéré en mémoire par l’Init Container et transmis au container applicatif, sans jamais être stocké dans Kubernetes.

5.4. Protection des communications réseau

Les communications entre OpenShift et Conjur doivent être sécurisées.

5.4.1. Vérification des certificats TLS

Tous les échanges entre OpenShift et Conjur doivent être chiffrés via TLS. Pour cela :

  • Vérifier que le ConfigMap conjur-connect contient bien un certificat TLS valide.
  • Tester la connexion avec curl en mode sécurisé :




👉 Si le certificat est invalide, il doit être mis à jour.

6. Utilisation des Secrets dans un Pod

Une fois que les secrets sont stockés dans Kubernetes via le Secret Provider, il est essentiel de savoir comment les consommer dans les applications OpenShift. Cette section couvre les différentes méthodes d’utilisation des secrets dans un pod.


6.1. Accès aux secrets via les variables d’environnement

L’un des moyens les plus courants d’utiliser un secret dans une application consiste à le monter sous forme de variable d’environnement.

6.1.1. Définition d’un pod consommant un secret

Le Secret Kubernetes injecté par le Secret Provider peut être référencé dans la spécification d’un pod.

Exemple de déploiement utilisant un secret sous forme de variable d’environnement :


6.1.2. Explication des paramètres

CléDescription
env.nameNom de la variable d’environnement utilisée dans le conteneur (DB_USERNAME).
valueFrom.secretKeyRef.nameNom du Secret Kubernetes (db-credentials).
valueFrom.secretKeyRef.keyClé spécifique à récupérer dans le secret (username).

6.1.3. Validation de l’injection du secret

Une fois le pod déployé, il est possible de vérifier que la variable est bien injectée.

Commande pour récupérer les logs du pod :

oc logs secret-env-pod -n app-namespace

Résultat attendu :

my-database-username

Si la variable est vide, il faut vérifier que :

  • Le secret db-credentials existe (oc get secrets -n app-namespace).
  • La clé username est bien présente dans le secret (oc get secret db-credentials -n app-namespace -o jsonpath='{.data.username}' | base64 --decode).

6.2. Montage des secrets dans un conteneur

Une autre approche consiste à monter les secrets sous forme de fichiers dans un volume Kubernetes. Cette méthode est utile si l’application attend les secrets sous forme de fichiers de configuration.

6.2.1. Définition d’un pod avec un volume de secrets


6.2.2. Explication des paramètres

CléDescription
volumes.secret.secretNameNom du Secret Kubernetes (db-credentials).
volumeMounts.mountPathEmplacement où les secrets sont montés (/etc/secrets).
volumeMounts.readOnlyEmpêche la modification des fichiers secrets par le conteneur (true).

6.2.3. Validation de l’accès aux fichiers secrets

Une fois le pod déployé, les fichiers doivent être présents dans /etc/secrets.

Commande pour interagir avec le pod et lister les fichiers secrets :

oc exec secret-volume-pod -n app-namespace -- ls /etc/secrets

Résultat attendu :

password
username

Commande pour afficher le contenu du fichier username :

oc exec secret-volume-pod -n app-namespace -- cat /etc/secrets/username

Résultat attendu :

my-database-username

Si les fichiers ne sont pas présents :

  • Vérifier que le secret db-credentials est bien créé (oc get secrets -n app-namespace).
  • Vérifier la syntaxe du volumes et volumeMounts dans la définition du pod.

6.3. Meilleures pratiques pour l’utilisation des secrets

Bonnes pratiquesExplication
Utiliser des ServiceAccounts restreintsNe donner accès aux secrets qu’aux applications qui en ont besoin via RBAC.
Éviter de stocker les secrets dans des logsVérifier que l’application ne journalise pas les valeurs des secrets accidentellement.
Utiliser des secrets en mémoirePréférer des Init Containers pour récupérer les secrets au lieu de les stocker dans des fichiers persistants.
Activer la rotation automatiqueSi l’application supporte la mise à jour dynamique des secrets, configurer un CronJob pour rafraîchir les valeurs.

7. Gestion des Coffres-Forts et des Habilitations dans Conjur

L’un des aspects fondamentaux de l’intégration de Conjur avec OpenShift est la gestion des coffres-forts (vaults) et des habilitations (permissions d’accès). Cette section décrit en détail les procédures à suivre côté Conjur pour configurer ces éléments de manière sécurisée.


7.1. Gestion des Coffres-Forts dans Conjur

Dans Conjur, un coffre-fort (vault) est un espace sécurisé où sont stockés les secrets. Chaque coffre est organisé en arborescence avec des variables correspondant aux secrets.

7.1.1. Création d’un coffre-fort

La gestion des secrets dans Conjur repose sur une policy, un fichier YAML qui définit :

  • La hiérarchie des secrets (chemins des variables).
  • Les entités autorisées à accéder aux secrets.

Exemple de policy pour un coffre-fort contenant des identifiants de base de données


Cette policy crée deux variables dans le coffre-fort database-secrets :

  • database-secrets/username
  • database-secrets/password

7.1.2. Ajout des secrets dans le coffre-fort

Une fois le coffre-fort créé, il faut y stocker les valeurs des secrets.

Commande pour ajouter un secret dans Conjur :

conjur variable set -i database-secrets/username -v my-database-user
conjur variable set -i database-secrets/password -v my-secure-password

Vérification des valeurs stockées :

conjur variable get -i database-secrets/username

👉 Si l’authentification et les permissions sont correctes, la valeur du secret sera affichée.


7.2. Gestion des Habilitations et des Accès aux Secrets

Les accès aux secrets dans Conjur sont strictement contrôlés via des policies. L’objectif est de limiter l’accès aux secrets aux seuls pods et services autorisés.

7.2.1. Définition des rôles et permissions

Les rôles Conjur permettent d’attribuer des permissions d’accès aux secrets.

Exemple de policy définissant un rôle app-role autorisé à lire les secrets


👉 Ce fichier définit :

  • Un rôle app-host qui représente les pods utilisant le ServiceAccount app-sa dans le namespace app-namespace.
  • Une permission read, execute sur les secrets database-secrets/username et database-secrets/password.

7.2.2. Application de la policy

Pour appliquer cette policy à Conjur, il faut exécuter la commande :

conjur policy load -f app-policy.yaml -b root

Si la policy est chargée correctement, les entités définies auront accès aux secrets selon les permissions configurées.


7.2.3. Vérification des permissions

Il est possible de tester si un ServiceAccount donné peut accéder à un secret.

Commande pour tester l’accès :

conjur authn authenticate -H "Authorization: Token token=<TOKEN>" | conjur variable get -i database-secrets/username

Si l’accès est autorisé, la valeur du secret sera retournée. Sinon, un message 403 Forbidden sera affiché, indiquant un problème de permissions.


7.3. Association des Permissions avec OpenShift

7.3.1. Configuration de l’authentification JWT dans Conjur

Pour permettre aux pods OpenShift de s’authentifier avec Conjur, l’authentification JWT doit être configurée.

Dans le ConfigMap de connexion à Conjur, l’URL d’authentification JWT doit être spécifiée :

data:
CONJUR_AUTHN_URL: "https://conjur-follower.conjur.svc.cluster.local/authn-jwt/openshift-cluster"

Cela permet à Conjur de reconnaître les identités basées sur les ServiceAccounts Kubernetes.


7.3.2. Attribution des rôles dans OpenShift

Dans OpenShift, les pods doivent être associés au ServiceAccount défini dans la policy Conjur.

Exemple de Deployment avec le ServiceAccount app-sa :


👉 Ce ServiceAccount est reconnu par Conjur et permet aux pods de s’authentifier et d’accéder aux secrets.


7.4. Résolution des Erreurs Courantes

ProblèmeCause PossibleSolution
403 Forbidden lors de la récupération d’un secretLe ServiceAccount n’a pas les permissions requisesVérifier la policy Conjur et les permissions RBAC OpenShift.
Impossible d’ajouter un secretL’utilisateur n’a pas les droits pour modifier ConjurVérifier les permissions de l’utilisateur sur Conjur.
401 Unauthorized lors de l’authentification JWTLe token JWT n’est pas reconnu par ConjurVérifier que l’authentification JWT est bien activée et configurée.

8. Gestion de la Rotation des Secrets

L’un des avantages majeurs de l’intégration de Conjur avec OpenShift est la possibilité de mettre à jour dynamiquement les secrets sans redéployer les applications. Cette section couvre les mécanismes permettant d’assurer la rotation automatique des secrets et de garantir que les applications consomment toujours des informations à jour.


8.1. Nécessité de la Rotation des Secrets

La rotation des secrets est essentielle pour :

  • Réduire la fenêtre d’exposition en cas de fuite d’un secret.
  • Se conformer aux exigences de sécurité et aux bonnes pratiques de gestion des identités.
  • Automatiser les mises à jour pour éviter les interventions manuelles et les erreurs humaines.

8.1.1. Types de rotation des secrets

Type de rotationDescription
Rotation manuelleL’administrateur met à jour le secret dans Conjur et relance les services impactés.
Rotation automatique via ConjurUn processus automatise le changement du secret dans Conjur et propage la mise à jour.
Mise à jour périodique avec KubernetesUn CronJob Kubernetes rafraîchit régulièrement les valeurs dans les Secrets Kubernetes.

8.2. Rotation Automatique des Secrets dans Conjur

Conjur prend en charge la rotation automatique des secrets grâce aux CyberArk Dynamic Access Providers (DAP) ou via des intégrations avec des outils comme AWS Secrets Manager ou HashiCorp Vault.

8.2.1. Mise à jour manuelle d’un secret dans Conjur

Si un secret doit être mis à jour manuellement, il peut être modifié via la CLI :

conjur variable set -i database-secrets/password -v new-secure-password

8.2.2. Validation de la mise à jour

conjur variable get -i database-secrets/password

Si la nouvelle valeur apparaît, la mise à jour est effective dans Conjur.


8.3. Synchronisation des Secrets dans Kubernetes

Une fois un secret mis à jour dans Conjur, il doit être propagé aux pods OpenShift.

8.3.1. Mise à jour automatique avec le Secret Provider

Si un CronJob Kubernetes est utilisé pour exécuter régulièrement le Secret Provider, les secrets seront mis à jour automatiquement.

Exemple de CronJob pour rafraîchir les secrets toutes les 5 minutes :


👉 Ce CronJob met à jour les Secrets Kubernetes en récupérant les nouvelles valeurs de Conjur.


8.4. Validation de la Rotation des Secrets

Une fois le processus en place, il est nécessaire de vérifier que :

  1. Le secret est bien mis à jour dans Kubernetes après une modification dans Conjur.
  2. Les pods consomment automatiquement les nouvelles valeurs.

8.4.1. Vérification des valeurs dans Kubernetes

Après exécution du CronJob, vérifier que le secret a bien été mis à jour :

oc get secret db-credentials -n app-namespace -o jsonpath='{.data.password}' | base64 --decode

Si la valeur correspond à la mise à jour effectuée dans Conjur, la synchronisation fonctionne.


8.4.2. Rechargement des secrets dans les applications

Certaines applications nécessitent un redémarrage pour prendre en compte les nouvelles valeurs des secrets.

Mécanisme de rechargement des pods

Une annotation sur le déploiement permet de forcer un redémarrage automatique des pods en cas de mise à jour du secret.


👉 Avec cet opérateur (stakater/Reloader), les pods sont redémarrés automatiquement lorsqu’un secret est mis à jour.


8.5. Meilleures Pratiques pour la Rotation des Secrets

PratiqueExplication
Automatiser la mise à jour avec un CronJobÉvite les erreurs humaines et garantit la mise à jour régulière des secrets.
Configurer les pods pour redémarrer en cas de mise à jourAssure que les applications consomment toujours les secrets à jour.
Utiliser un stockage en mémoire pour éviter les fuitesPrivilégier des Init Containers au lieu de secrets stockés en clair.

9. Conclusion

9.1. Récapitulatif de l’implémentation

Ce guide a détaillé l’intégration de Conjur avec OpenShift afin d’assurer une gestion sécurisée et centralisée des secrets pour les applications Kubernetes. À travers les différentes sections, les principales étapes de mise en place ont été couvertes :

Résumé des étapes clés

ÉtapeObjectif
Déploiement des composants ConjurInstallation du Conjur Follower pour gérer les requêtes d’authentification et de récupération des secrets.
Configuration des accès OpenShiftCréation des ServiceAccounts et permissions RBAC pour restreindre l’accès aux secrets.
Déploiement du Secret ProviderMise en place du CyberArk Secret Provider for Kubernetes pour extraire et injecter les secrets dans Kubernetes.
Validation et testsVérification du fonctionnement du Secret Provider et de la synchronisation des secrets.
Sécurisation des accèsImplémentation de policies Conjur, RBAC et chiffrement des secrets Kubernetes.
Utilisation des secrets dans les podsMontage des secrets via variables d’environnement ou volumes Kubernetes.
Gestion des coffres-forts et habilitationsDéfinition des policies Conjur pour restreindre les accès en fonction des Namespaces et ServiceAccounts.
Rotation et mise à jour automatique des secretsDéploiement d’un CronJob Kubernetes pour assurer la mise à jour des secrets.

9.2. Meilleures pratiques à adopter

L’intégration Conjur-OpenShift repose sur plusieurs bonnes pratiques pour garantir un niveau de sécurité optimal et un fonctionnement efficace.

Sécurité et gestion des accès

Utiliser des ServiceAccounts dédiés pour chaque application accédant aux secrets.
Restreindre l’accès aux secrets via RBAC et policies Conjur pour éviter toute exposition accidentelle.
Activer l’authentification JWT pour l’intégration OpenShift-Conjur, et limiter les accès par Namespace.
Appliquer le chiffrement des secrets Kubernetes pour éviter leur stockage en clair dans etcd.

Utilisation et mise à jour des secrets

Favoriser l’utilisation des secrets en mémoire plutôt que leur stockage en fichiers persistants.
Mettre en place un CronJob Kubernetes pour rafraîchir les secrets de manière automatique.
Surveiller les logs du Secret Provider et du Conjur Follower pour détecter d’éventuelles erreurs d’accès.


9.3. Perspectives d’évolution

L’intégration actuelle peut être améliorée en adoptant des stratégies avancées de gestion des secrets :

  • Intégration avec des solutions de monitoring (Prometheus, Grafana) pour auditer les accès aux secrets.
  • Automatisation de la gestion des secrets via CyberArk AIM pour la rotation dynamique et la distribution avancée.
  • Utilisation de technologies Serverless pour éviter totalement le stockage des secrets dans Kubernetes et privilégier des requêtes dynamiques à Conjur.

9.4. Conclusion générale

L’intégration de Conjur avec OpenShift permet d’améliorer considérablement la sécurité des secrets en adoptant une approche centralisée et conforme aux meilleures pratiques DevSecOps. Grâce aux mécanismes détaillés dans ce guide, les applications peuvent bénéficier d’un accès sécurisé, audité et automatisé aux secrets tout en garantissant leur mise à jour dynamique.

En suivant ces recommandations, il est possible d’assurer une gestion efficace des secrets dans OpenShift tout en minimisant les risques d’exposition et d’erreurs humaines.