Passer au contenu

Rotation de la clé principale et des clés de signature, et accès d’urgence

Faites tourner la clé principale qui protège les identifiants enregistrés et utilisez l’accès d’urgence.

Afficher en Markdown

Les contrôles de la section 14 de 21-compliance.md que les auditeurs demandent nommément. Cette page décrit la procédure ; les registres qu’elle produit constituent les preuves.

Les clés

Chaque identifiant enregistré est scellé avec une nouvelle clé de chiffrement des données (DEK). La clé principale (KEK) enveloppe la DEK, et sa référence est enregistrée à côté (key_ref, ou référence dans une valeur empaquetée). La rotation de la clé principale ré-enveloppe les DEK. Elle ne déchiffre ni ne rechiffre jamais un identifiant.

Paramètre Signification
QUIRE_MASTER_KEY Clé principale actuelle : 32 octets, en base64. Chaque nouveau secret est enveloppé avec cette clé
QUIRE_MASTER_KEY_VERSION Son étiquette de version. v1 si non définie. Incrémentez-la à chaque changement de clé
QUIRE_MASTER_KEY_RETIRED Clés antérieures susceptibles de protéger encore des secrets, sous la forme v1=<base64>,v0=<base64>. Elles sont lues, jamais modifiées

La couche Web, le worker et la commande bun run kek:rotate lisent les mêmes trois paramètres. Tous doivent avoir les mêmes valeurs, sinon l’un ne peut pas ouvrir ce qu’un autre a scellé.

Sans QUIRE_MASTER_KEY, chaque sous-système conserve la clé qu’il dérive de QUIRE_SECRET_KEY. Cela fonctionne ; la page Santé du système indique toutefois un état dégradé. Les données restent lisibles après la définition d’une clé principale, ce qui permet à la première rotation de tout déplacer. Toute personne pouvant lire l’environnement d’un processus peut déchiffrer tous les identifiants enregistrés ; une installation de production doit donc disposer d’une clé principale conservée dans un magasin de secrets, séparément de la sauvegarde de la base de données.

Rotation

L’ancienneté de la clé est visible dans Console de la plateforme, Sécurité, Clé principale, et dans la métrique quire.secrets.master_key.age (en jours). La planification quotidienne platform.key_age (03:41 UTC) ajoute un rappel à la chaîne d’audit de la plateforme lorsque la clé atteint 365 jours, puis tous les 30 jours jusqu’à sa rotation. Faites-la tourner au rappel et dès qu’elle risque d’avoir été exposée.

  1. Générez la nouvelle clé : openssl rand -base64 32.
  2. Définissez QUIRE_MASTER_KEY avec cette valeur et QUIRE_MASTER_KEY_VERSION avec l’étiquette suivante (v2). Déplacez l’ancienne clé dans QUIRE_MASTER_KEY_RETIRED sous la forme v1=<old base64>. Conservez une copie des deux clés ailleurs que sur cet hôte.
  3. Déployez la couche Web et le worker avec les nouveaux paramètres. Les nouveaux secrets sont alors enveloppés avec env:QUIRE_MASTER_KEY:v2 ; les anciens s’ouvrent encore avec la clé retirée.
  4. Demandez la rotation en indiquant le motif qui figurera dans la piste d’audit :
    • dans la console : Sécurité, Clé principale, Faire tourner la clé principale ; ou
    • dans un shell utilisant le même environnement : bun run kek:rotate request --reason "Annual rotation, ticket SEC-114".
  5. Le worker ré-enveloppe une partie chaque minute (selon la planification platform.key_rotation du scheduler) et reprend après un redémarrage. Pour tout terminer en une fois : bun run kek:rotate run. Suivez l’opération avec bun run kek:rotate status.
  6. Lorsque le registre indique une rotation terminée avec zéro valeur non résolue et zéro échec, retirez l’ancienne clé de QUIRE_MASTER_KEY_RETIRED et redéployez. Gardez-la jusque-là : les valeurs impossibles à déplacer sont encore enveloppées avec l’ancienne clé.

Éléments parcourus par le travail

Chaque magasin qui conserve une DEK enveloppée : ceux répertoriés dans SEALED_STORES (apps/worker/src/key-rotation.ts). Les magasins de la base de contrôle sont parcourus dans cette base ; les magasins d’organisation le sont une organisation à la fois, sous sécurité au niveau des lignes et dans la base qui contient l’organisation. Un locataire épinglé à une base dédiée y est donc soumis à la rotation. Un test échoue si le schéma reçoit une colonne avec une clé enveloppée qui ne figure pas dans la liste ; un autre échoue si l’examen des identifiants classe une colonne scellée que la liste ne comprend pas.

Registre

  • ops.key_rotation : une ligne par rotation, indiquant le motif, l’auteur de la demande, l’état et les totaux (ré-enveloppés, déjà à jour, non résolus, échecs).
  • ops.key_rotation_progress : une ligne par magasin et périmètre parcourus, avec les références de clés impossibles à lire et le nombre de valeurs protégées par chacune. Une rotation reprise ignore ces lignes.
  • Chaîne d’audit de la plateforme : platform/key_rotation_request (avec le motif), une entrée platform/key_rotation_store par magasin et ses décomptes, et platform/key_rotation_complete ou platform/key_rotation_fail ; platform/key_age_reminder pour le rappel.
  • Métriques : quire.secrets.master_key.age et quire.secrets.rewrap.outstanding (valeurs que la dernière rotation n’a pas pu déplacer).

Valeurs non résolues

Une valeur non résolue est enveloppée avec une référence de clé inconnue de cette installation ou n’a pas la forme promise par sa colonne. Le registre de progression indique la référence (par exemple env:QUIRE_MASTER_KEY:v0 (unreadable)). Restaurez cette clé dans QUIRE_MASTER_KEY_RETIRED et relancez une rotation ; si la clé est définitivement perdue, demandez à l’administrateur de l’organisation de saisir à nouveau l’identifiant, qui sera alors scellé avec la clé actuelle. Les rotations échouées affichent leur erreur dans le registre ; corrigez la cause et relancez la demande.

Clés de signature

Indépendamment de la clé principale, chaque organisation signe ses jetons OpenID Connect et ses messages LTI avec sa propre clé RSA, publiée dans /.well-known/jwks.json. Aucune intervention n’est nécessaire. La planification horaire platform.signing_keys publie une clé de remplacement sept jours avant l’expiration des 90 jours de la clé actuelle ; une semaine plus tard, la nouvelle clé commence à signer et l’ancienne passe à l’état « en cours de retrait » ; 90 jours après, l’ancienne clé est supprimée du jeu de clés. Chaque étape est consignée sous platform/signing_key_advance dans la chaîne d’audit de la plateforme.

Pour remplacer la clé d’une organisation avant l’échéance, par exemple après une exposition :

  • dans la console : Sécurité, Clé principale, Publier une nouvelle clé de signature (nécessite platform/keys_manage) ; ou
  • dans un shell utilisant l’environnement du worker : bun run kek:rotate signing-keys rotate --tenant <slug or id> --reason "Key exposed, INC-3310". bun run kek:rotate signing-keys status répertorie l’étape de la clé de chaque organisation.

La nouvelle clé est publiée immédiatement et commence à signer au bout de sept jours, lorsque l’ancienne est retirée. Ce délai d’une semaine est intentionnel : les parties utilisatrices mettent le jeu de clés en cache, et un chevauchement plus court interrompt tous les outils simultanément. La clé retirée reste dans le jeu pendant 90 jours supplémentaires afin que les jetons déjà signés continuent d’être vérifiés. Si l’exposition nécessite de cesser plus tôt de lui faire confiance, sa ligne peut être supprimée par l’opérateur depuis son propre accès à la base, avec un registre de modification (l’accès d’urgence est en lecture seule) ; les jetons signés par cette clé échoueront alors à la vérification. La rotation forcée est inscrite sous platform/signing_key_rotate dans la chaîne d’audit, avec le motif. Le worker a besoin des mêmes paramètres QUIRE_MASTER_KEY que la couche Web pour envelopper la nouvelle clé ; la commande bun run kek:rotate de la clé principale ré-enveloppe les clés de signature avec le reste (oauth_signing_key figure dans SEALED_STORES).

Accès d’urgence à la production

Personne ne dispose d’un accès permanent à la production. Lorsqu’une situation ne peut pas attendre, un propriétaire accorde une autorisation d’urgence : Console de la plateforme, Sécurité, Accès d’urgence.

  • Une autorisation définit un périmètre (une organisation ou le registre de la plateforme), un motif d’au moins 20 caractères faisant référence à l’incident ou au ticket, et une durée de 5 à 240 minutes. Elle expire automatiquement : l’heure est vérifiée à chaque instruction.
  • Elle peut être attribuée au propriétaire qui l’accorde ou à un autre propriétaire (mode à deux personnes). Seule la personne désignée peut l’utiliser. L’attribution nécessite platform/break_glass_issue et l’utilisation platform/break_glass_use ; par défaut, ces droits sont réservés aux propriétaires.
  • Les instructions passent par la passerelle, pas par une connexion à la base : lecture seule, une à la fois, limitée à l’organisation ou au registre de contrôle, avec un délai maximal de cinq secondes et 500 lignes. Les valeurs binaires sont représentées par leur taille.
  • La chaîne d’audit de la plateforme consigne l’attribution (avec le motif), la révocation, chaque instruction avant son exécution (platform/break_glass_statement, les refus avec le résultat denied) et chaque résultat (platform/break_glass_result). ops.break_glass_statement contient les identifiants des entrées d’audit afin de relier le registre d’attribution aux entrées correspondantes.
  • Aucune écriture n’est proposée. Un changement ne pouvant attendre une version utilise l’accès propre de l’opérateur à la base, sous son propre registre de modification et hors de ce produit ; le registre doit citer la référence d’incident indiquée ici.

Pourquoi ne pas fournir d’identifiants de base de données ? Une connexion Postgres reste valide au-delà de la session qui l’a demandée, contourne la sécurité au niveau des lignes dont dépend l’application et ne peut pas écrire dans la chaîne d’audit de ce produit. Les instructions ne seraient donc auditées que si quelqu’un publiait le journal du serveur. La passerelle fait de la piste d’audit une propriété de l’accès, plutôt qu’une pratique à appliquer autour de celui-ci.

Pour répondre à une demande d’audit : répertoriez les autorisations de la période (Accès d’urgence), consultez l’historique d’une autorisation pour voir ses instructions et les identifiants des entrées d’audit, puis lisez ces entrées dans la chaîne d’audit de la plateforme (bun run audit:verify --platform confirme son intégrité).

Navigation

Saisissez votre recherche…

↑↓ naviguer↵ sélectionnerÉchap fermer