Auto-hébergement
Exploitation et dépannage
Exécutez Keyright auto-hébergé en production : tâches planifiées, observabilité, durcissement de la sécurité, mise à l'échelle et répartition de charge, sauvegarde et restauration, mises à niveau, fonctionnement totalement isolé (air-gapped), et un dépannage/FAQ pour ce qui survient lors d'un premier déploiement.
Tout ce dont vous avez besoin une fois l’instance en marche : la garder saine, la mettre à l’échelle, la sauvegarder, la mettre à niveau, la faire tourner en isolation (air-gapped) et réparer ce qui n’est pas passé au vert. Si vous êtes encore en train de la mettre en place, commencez par le guide de déploiement.
Exploitation
Tâches planifiées
L’analyse quotidienne des expirations/sièges et la livraison des webhooks s’exécutent sur des minuteurs in-process. Sur les hôtes qui mettent en veille les minuteurs d’arrière-plan (certaines plateformes serverless), pilotez-les plutôt depuis un planificateur externe — définissez KEYRIGHT_CRON_SECRET et appelez :
curl -X POST -H "X-Cron-Secret: $SECRET" $BASE/internal/notifications/run
curl -X POST -H "X-Cron-Secret: $SECRET" $BASE/internal/webhooks/deliver
Observabilité
- Liveness :
GET /health(200 statique — ne retire jamais un nœud à cause d’un incident passager de la base de données). Readiness :GET /health/ready(vérifie aussi la connectivité à la base de données — 503 lorsqu’elle est injoignable). - Journaux : JSON structuré sur stdout (pilotes Docker/K8s, ou le journal des événements Windows via ANCM). Surveillez les lignes de démarrage confirmant l’application des migrations et le statut de l’auto-licence.
- Surveillez : le
/healthde l’application, la disponibilité/les connexions/le disque de PostgreSQL, et l’expiration du certificat sur le répartiteur de charge.
Diagnostics (2.2.0)
-
GET /admin/self-diagnostics(jeton admin) — un instantané de santé en un seul appel pour le triage : version, accessibilité de la base de données + migrations en attente, phase de l’auto-licence, fonctionnalités activées, configuration ou non de SMTP/des alertes, et temps de fonctionnement. Comme/admin/self-license, il reste accessible même lorsque l’instance est verrouillée, pour que vous puissiez diagnostiquer un arrêt lié à la licence.{ "version": "2.2.0", "uptimeSeconds": 3600, "database": { "reachable": true, "error": null, "pendingMigrations": 0 }, "selfLicense": { "status": "valid", "phase": "active", "isTrial": false, "daysUntilExpiry": 320, "runtimeBlocked": false }, "features": { "operatorMode": false, "sso": true, "whitelabel": true, "airgap": true }, "smtpConfigured": true, "alerts": { "rulesEnabled": 3, "errorsAlerted24h": 0 } } -
Identifiants de corrélation d’erreur — chaque erreur serveur non gérée (HTTP 500) est journalisée une seule fois avec un identifiant court, renvoyé à l’appelant dans l’en-tête de réponse
X-Keyright-Error-Id(et dans un champerrorIddu corps). Lorsqu’un client signale une erreur, cet identifiant relie son signalement à exactement une ligne de journal.
Alertes par e-mail (2.2.0)
Recevez un e-mail lorsque quelque chose se produit — à configurer dans le tableau de bord → Settings → Email alerts (ou via l’API) :
- SMTP — définissez votre propre hôte/port/utilisateur/mot de passe/expéditeur SMTP dans le tableau de bord (
POST /admin/alerts/smtp) ; le mot de passe est stocké chiffré sous la KEK et est en écriture seule (jamais renvoyé). Si vous ne le définissez pas, les alertes se rabattent sur la configuration d’environnementKEYRIGHT_SMTP_*. - Règles par événement — activez exactement les événements que vous voulez et donnez à chacun sa propre liste de destinataires (
POST /admin/alerts/rules), de sorte que des événements différents soient acheminés vers des adresses différentes. Un bouton « send test email » vérifie vos réglages. - Les événements couvrent le côté client (licence sur le point d’expirer/expirée, limite de sièges atteinte, révoquée) et, point important pour l’auto-hébergement, la licence de votre propre instance qui approche de l’expiration, entre en grâce ou se verrouille — pour qu’une instance fail-closed ne s’arrête jamais à l’improviste — ainsi que les événements système (erreur serveur, erreur de base de données, échec d’une tâche planifiée). Les conditions récurrentes sont dédupliquées pour n’envoyer qu’un e-mail par fenêtre, et non à chaque analyse.
Durcissement de la sécurité
- Conservez
KEYRIGHT_ADMIN_TOKEN,KEYRIGHT_KEKetKEYRIGHT_SIGNING_KEYdans un gestionnaire de secrets — jamais dans une image ni dans le contrôle de source. - N’exposez publiquement que
:443(via le répartiteur de charge)./admin/*et/internal/*ne devraient être joignables que par vous/votre réseau ; le chemin client/v1/*est le seul dont vos clients ont besoin. - Restreignez l’accès réseau à la base de données aux nœuds applicatifs, et exigez TLS vers la base de données.
Mise à l’échelle et répartition de charge
L’application est légère en CPU et sans état ; la mise à l’échelle concerne la redondance et la capacité de la base de données, pas le débit de l’application.
| Échelle | Licences actives | Nœuds applicatifs | PostgreSQL | Répartiteur de charge |
|---|---|---|---|---|
| Évaluation | quelconque | 1 (0,5 vCPU / 512 Mo) | embarqué | aucun |
| Petite | jusqu’à ~50k | 1 (1 vCPU / 1 Go) | 2 vCPU / 2 Go managé | proxy TLS facultatif |
| HA standard | jusqu’à ~500k | 2–3 (1 vCPU / 1 Go) | HA (primaire+secondaire) | oui |
| Grande | 1M+ | 3–5+ avec autoscaling | 4–8 vCPU / 16 Go+ HA + PgBouncer | oui |
Exécutez 2 nœuds applicatifs ou plus derrière n’importe quel répartiteur de charge HTTP. Comme l’application est sans état et que les clients vérifient hors ligne, aucune affinité de session n’est nécessaire — envoyez n’importe quelle requête à n’importe quel nœud. Terminez TLS au niveau du répartiteur et transmettez X-Forwarded-For (l’IP réelle du client) et X-Forwarded-Proto (pour que le tableau de bord/portail génèrent des URL en https) ; l’application honore les deux. La concurrence est sûre entre nœuds — les crédits et les sièges utilisent une vérification-et-déduction sérialisable, de sorte que deux nœuds ne peuvent jamais dépenser deux fois un solde ou un siège.
Sauvegarde et restauration
Tout est dans PostgreSQL — pg_dump / pg_restore standard. Sauvegardez aussi KEYRIGHT_KEK et KEYRIGHT_SIGNING_KEY séparément et de manière sécurisée : sans la KEK, les clés de signature chiffrées dans la base de données ne peuvent pas être récupérées.
Mises à niveau
- Sauvegardez la base de données (et confirmez que vous disposez de la KEK/clé de signature).
- Récupérez la nouvelle version (
docker compose pull/ incrémentez l’image.tagHelm / déposez le nouveau bundle Windows). - Redémarrez. Les migrations s’appliquent automatiquement au démarrage — une seule étape, pas de SQL manuel.
curl /health(vérifiezversion) et confirmez que/admin/self-licensesignale toujours votre licence.
Les mises à niveau sont rétrocompatibles au sein d’une même ligne mineure ; avec 2 nœuds ou plus, vous pouvez les mettre à niveau un par un sans interruption. Les retours en arrière après l’exécution d’une migration ne sont pas pris en charge — d’où l’importance de l’étape 1.
Fonctionnement isolé (air-gapped)
Rien ici n’a besoin d’Internet à l’exécution. Votre licence et celles de vos clients sont vérifiées hors ligne avec des clés publiques embarquées ; les crédits des machines déconnectées utilisent des blocs de crédits isolés (air-gapped) signés (une fonctionnalité Enterprise) : émettez un bloc signé, consommez-le hors ligne, réconciliez à la reconnexion. Deux points pour un fonctionnement isolé propre :
- Désactivez GeoIP : définissez
KEYRIGHT_GEOIP_URL=(vide) pour que la recherche de localisation des machines du tableau de bord ne tente aucune connexion sortante. - Importez les images : sur un hôte connecté, exportez
docker save ghcr.io/delta1-labs/keyright:2.2.2(etpostgres:16si vous utilisez la base de données embarquée) dans une archive tar, puisdocker loadà l’intérieur du réseau isolé.
Dépannage et FAQ
Le conteneur s’arrête au démarrage en se plaignant que la KEK doit être définie. Définissez KEYRIGHT_KEK sur une valeur de 32 octets en base64 (openssl rand -base64 32). Notez que l’application se connecte d’abord à la base de données et exécute les migrations, donc une erreur de connexion à la base de données apparaît avant celle-ci.
Erreur au démarrage lors de la connexion à la base de données / « relation does not exist ». Vérifiez KEYRIGHT_DB (hôte, port, base de données, identifiants, SSL Mode). Le rôle doit pouvoir créer des tables (Configuration → Base de données) ; confirmez que la base de données est vide au premier démarrage et que le rôle en est propriétaire (ou dispose de CREATE ON SCHEMA public sur PG15+).
Le pod est en CrashLoopBackOff / le conteneur redémarre en boucle, les journaux montrent un Name or service not known / connection refused / un délai d’attente dépassé Npgsql. L’application exécute ses migrations au démarrage, elle s’arrête donc (et redémarre) si elle ne peut pas joindre la base de données à son lancement — vous n’obtiendrez pas un pod en marche-mais-pas-prêt. Sur une installation d’évaluation neuve avec Postgres embarqué, quelques redémarrages sont attendus pendant que Postgres passe à Ready, et se résorbent d’eux-mêmes. Sinon, c’est presque toujours un problème de connectivité, pas un bug : (1) l’hôte de la base de données ne se résout pas ou n’est pas joignable depuis le nœud applicatif (vérifiez le DNS/la sortie réseau, et toute règle NSG/pare-feu ou « autoriser les services Azure » sur une base de données managée) ; (2) incompatibilité TLS — la plupart des Postgres managés exigent SSL Mode=Require (ajoutez ;Trust Server Certificate=true si vous ne validez pas l’AC) ; (3) identifiants/nom de base de données incorrects. Vérification préalable avant le déploiement : depuis un pod sur le même réseau, confirmez que l’application peut résoudre et joindre l’hôte et le port de la base de données. Une fois la base de données joignable, le pod passe à Ready de lui-même.
Chaque requête renvoie 402. Votre instance est verrouillée — aucune clé de licence/d’essai valide (Licence). Vérifiez /admin/self-license ; installez une clé via KEYRIGHT_SELF_LICENSE et redémarrez.
/admin/* renvoie 401. Envoyez X-Admin-Token: $KEYRIGHT_ADMIN_TOKEN. Le chemin client /v1/* n’en a jamais besoin.
L’image inclut-elle une base de données ? Non — elle ne contient que l’application. Exécutez PostgreSQL à côté (voir la vue d’ensemble de l’architecture et Configuration → Base de données).
Les applications de mes clients ne parviennent pas à s’activer. Confirmez que l’URL de service du SDK pointe vers votre instance (Connecter votre produit) et que le slug du produit + la clé publique embarquée correspondent au produit pour lequel vous émettez des clés.
Ma licence a expiré — que se passe-t-il ? Une licence payante bénéficie d’une grâce de 15 jours en lecture seule (le runtime + les lectures continuent de fonctionner) ; un essai s’arrête immédiatement. Après la grâce, l’instance s’arrête entièrement jusqu’à ce que vous installiez une clé renouvelée (Licence).
Ai-je besoin d’un répartiteur de charge ? Seulement pour 2 nœuds applicatifs ou plus (Mise à l’échelle). Un nœud unique n’en a pas besoin (vous pouvez tout de même vouloir un proxy de terminaison TLS devant).
Prêt à exécuter Keyright dans votre propre environnement ? Contactez l’équipe commerciale pour un essai ou une licence Standard/Enterprise, ou consultez les tarifs.