---
title: "Rotation de la clé principale et des clés de signature, et accès d’urgence"
description: "Faites tourner la clé principale qui protège les identifiants enregistrés et utilisez l’accès d’urgence."
image: "https://docs.quirelms.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.quirelms.com/fr/llms.txt
> Use this file to discover all available pages before exploring further.

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

<span id="master-key-and-signing-key-rotation-and-break-glass-access"></span>

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 <!--quire:the-keys-->

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 <!--quire:rotating-->

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 <!--quire:what-the-job-walks-->

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 <!--quire:the-record-->

- `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 <!--quire:when-values-are-unresolved-->

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 <!--quire:signing-keys-->

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 <!--quire:break-glass-production-access-->

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é).

Source: https://docs.quirelms.com/fr/ops/key-rotation/index.mdx
