Aller au contenu

Sécurité et exploitation de NextPDF Connect

NextPDF Connect authentifie les transports réseau au moyen d’un jeton de type bearer (clé API). Il isole le transport MCP local comme sous-processus de confiance et place chaque outil à haut risque derrière une confirmation humaine explicite. Cette page décrit le modèle d’authentification, la sécurité des transports et le modèle de menace.

Fenêtre de terminal
composer require nextpdf/server

Le serveur définit trois frontières de confiance, une par transport.

Le transport stdio MCP est un sous-processus lancé par un client local. Il lit le JSON-RPC depuis l’entrée standard et écrit ses réponses sur la sortie standard. Ce transport n’a aucun écouteur réseau ni clé API. La confiance est héritée de la frontière de processus du système d’exploitation, ce qui correspond au modèle de confiance que la spécification MCP définit pour stdio. Les journaux sont écrits sur la sortie d’erreur standard, de sorte qu’ils ne corrompent jamais le flux du protocole.

Le transport REST et le transport gRPC sont en réseau. Tous deux exigent un jeton bearer (clé API) sur chaque requête, sauf pour les sondes de santé non authentifiées. Les deux transports utilisent le même magasin de clés, le même format de clé et la même validation à temps constant. Le transport gRPC lit le jeton depuis les métadonnées de l’appel, tandis que REST le lit depuis l’en-tête Authorization.

Une authentification mal mise en œuvre est précisément la défaillance que l’OWASP API Security Top 10 signale sous API2:2023 Broken Authentication. Les failles d’implémentation à cet endroit compromettent la capacité de l’API à identifier l’appelant, et donc la sécurité de l’API dans son ensemble (OWASP API Security Top 10, API2:2023). Les jetons faibles ou prévisibles sont explicitement cités comme un anti-modèle d’authentification cassée (même source, liste des vulnérabilités). La conception décrite ci-dessous se prémunit contre l’une comme l’autre.

Une clé a la forme npk_live_{kid}_{secret}. Le kid est un identifiant de huit caractères utilisé pour une recherche d’enregistrement en O(1) ; c’est le secret qui porte l’entropie. Le magasin ne conserve jamais la clé brute. Il stocke une empreinte SHA-256 de l’intégralité du matériel de clé. À chaque requête, le serveur hache le jeton présenté et le compare à l’empreinte stockée au moyen d’une comparaison à temps constant (hash_equals), de sorte qu’une mauvaise clé ne révèle aucune information par le timing. Une clé désactivée ou expirée est rejetée après la vérification de l’empreinte, et non avant.

Les validateurs REST et gRPC partagent cette logique. L’intergiciel REST lit Authorization: Bearer npk_live_…. L’authentificateur gRPC lit le même jeton bearer depuis les métadonnées d’appel gRPC authorization, transportées sous forme d’en-têtes HTTP/2. Il rejette l’appel avec le statut gRPC UNAUTHENTICATED.

Les deux transports appliquent aussi une limitation contre l’automatisation sur le trafic de pré-authentification : les tentatives excessives provenant d’une même identité client sont soumises à une limitation de débit et rejetées — 429 Too Many Requests sur REST, le statut gRPC RESOURCE_EXHAUSTED sur gRPC. Ce contrôle est actif par défaut : il protège donc un déploiement qui n’a pas configuré séparément un magasin de limitation de débit ; les clients devraient temporiser plutôt que de réessayer immédiatement.

Une requête REST qui présente une clé manquante, mal formée, désactivée ou expirée reçoit 401 Unauthorized avec un corps problem-details et un en-tête de réponse WWW-Authenticate: Bearer. Cela correspond à l’exigence HTTP selon laquelle une réponse 401 doit comporter un champ d’en-tête WWW-Authenticate avec au moins un challenge (RFC 9110 §11.6.1). Cette exigence découle elle-même de la règle selon laquelle une requête qui omet des identifiants ou présente des identifiants invalides doit recevoir en réponse 401 assorti d’un challenge WWW-Authenticate (RFC 9110 §11.6).

Chaque enregistrement de clé porte un niveau produit maximal. Le pipeline REST attache à la requête l’identité et le niveau du client authentifié, afin que l’autorisation en aval puisse appliquer les plafonds de capacité et de charge utile propres à chaque niveau. Une clé de niveau Core ne peut pas piloter une opération Pro ou Enterprise, même quand ces packages sont installés.

  • Le transport MCP n’a pas de clé API. C’est intentionnel et correct pour un sous-processus local. N’expose pas le serveur MCP via un shim réseau. Si un agent en réseau a besoin des outils, place-le devant le transport REST ou gRPC, qui authentifient.

  • Les sondes de santé sont anonymes à dessein. /healthz et /readyz contournent l’authentification afin que les orchestrateurs puissent sonder la vivacité et la disponibilité sans identifiants. Elles ne renvoient qu’un statut. Elles n’exposent aucune donnée d’outil ni de document.

  • Un jeton de confirmation est à usage unique et à durée de vie courte. Le contrôle de validation humaine émet un jeton lié au nom de l’outil, d’une durée de vie de 300 secondes. Le jeton est consommé dès la première utilisation. Ce n’est pas un identifiant d’authentification et il ne remplace pas une clé API.

L’authentification se résume à un seul hachage et à une comparaison à temps constant par requête. Ce coût est négligeable face au coût d’un rendu. Le magasin de clés à rechargement à chaud relit le fichier de clés lorsqu’il change, de sorte que la rotation ne nécessite pas de redémarrage et n’ajoute aucun coût par requête.

Chaque outil déclare un niveau de risque. Les outils du niveau le plus élevé, ApprovalRequired, ne s’exécutent pas au premier appel. Le contrôle de confirmation renvoie un challenge contenant un jeton à usage unique. L’agent doit présenter le challenge à un humain et réinvoquer l’outil avec le jeton. C’est un contrôle délibéré, placé là où l’action automatisée introduit du risque. C’est précisément le point que l’IEC 31010 identifie pour maîtriser le risque introduit par l’action humaine (ici, celle de l’agent), au point d’introduction ou à proximité (IEC 31010:2019). Le contrôle ne peut pas être affaibli par configuration : une surcharge de configuration peut uniquement élever le risque d’un outil, jamais abaisser un outil ApprovalRequired. Voir /connect/hitl-risk-tiers/.

Les transports en réseau ne terminent pas TLS eux-mêmes ; TLS relève du déploiement. Le déploiement combiné de référence exécute le transport gRPC avec TLS mutuel, la clé, le certificat et l’autorité de certification cliente étant fournis comme secrets de déploiement. Sous TLS mutuel, le serveur présente un certificat, puis exige et vérifie un certificat client. Exécute le transport REST derrière un terminateur TLS (proxy inverse ou maillage de services) et n’expose jamais d’écouteur en clair sur un réseau non fiable. Les détails de configuration sont dans /connect/deployment/ ; il s’agit d’un énoncé de posture, pas d’une garantie clés en main, et un transport sécurisé exige une configuration de déploiement correcte.

Les outils d’écriture de fichiers résolvent le chemin demandé par rapport au répertoire de base configuré, le canonisent et rejettent les octets nuls, les wrappers de protocole et la traversée ... Ils refusent tout chemin qui se résout en dehors de cette base. Garde le répertoire de base sur un volume dédié, avec des permissions de système de fichiers au plus faible privilège.

Résidence des données et mesures de protection des données personnelles

Section intitulée « Résidence des données et mesures de protection des données personnelles »

Le serveur ne conserve les documents que dans le magasin de documents en mémoire, pendant la durée de vie configurée (1800 secondes par défaut) et dans la limite d’un nombre borné (50 par défaut). Il ne persiste pas le contenu des documents sur le disque, sauf lorsqu’un outil d’écriture de fichiers est explicitement invoqué et que le chemin passe le confinement. Le serveur n’effectue aucun appel réseau sortant pour rendre ou inspecter un document, de sorte que les octets des documents ne quittent pas le déploiement, à moins qu’un outil ne soit explicitement configuré pour récupérer une ressource distante. Pour des déploiements sans état et sensibles à la résidence, désactive l’écriture de fichiers (allow_file_output: false) et restreins enabled_tools à l’ensemble minimal.

La journalisation d’audit consigne les exécutions d’outils dont le niveau de risque est Caution ou supérieur, ainsi que chaque challenge de confirmation émis. L’enregistrement d’audit porte le nom de l’outil, le niveau de risque et l’indicateur de réussite. Traite les arguments d’outil comme potentiellement sensibles : achemine les journaux vers une destination assortie de contrôles d’accès, et n’élève pas le niveau de journalisation global à une verbosité qui réémettrait les charges utiles des arguments dans les environnements partagés. Le transport MCP écrit ses journaux sur la sortie d’erreur standard, précisément pour que le contenu des journaux n’entre jamais dans le flux du protocole sur la sortie standard.

AffirmationSourcereference_id
Une authentification cassée compromet la sécurité de l’APIOWASP API Security Top 10, API2:2023
Les jetons faibles ou prévisibles sont un anti-modèle d’authentification casséeOWASP API Security Top 10, API2:2023
401 doit porter un en-tête WWW-Authenticate de challengeRFC 9110 §11.6.1
Identifiants manquants/invalides → 401 + challengeRFC 9110 §11.6
Maîtriser le risque au point d’introduction (humaine)IEC 31010:2019

Le modèle de confiance stdio du Model Context Protocol suit la spécification officielle MCP, révision 2025-06-18. Celle-ci est consignée avec son URL sur /transports/mcp/ parce que la spécification MCP ne fait pas partie du corpus de normes sous accès contrôlé.

Les outils de signature, de caviardage, de conformité et d’investigation forensique ne sont présents que lorsque nextpdf/premium est installé aux côtés du serveur. Leur présence ne change pas le modèle d’authentification. Leur niveau de risque place malgré tout les outils destructeurs derrière le contrôle de validation humaine.

  • /connect/hitl-risk-tiers/ — le modèle de risque et l’enveloppe de confirmation en détail
  • /connect/deployment/ — TLS, TLS mutuel, secrets et réglage des workers
  • /transports/rest/ — le pipeline d’intergiciels REST et le schéma de sécurité OpenAPI
  • /transports/grpc/ — l’authentification par métadonnées gRPC et les codes de statut
  • /connect/configuration/ — enabled_tools, sélection du magasin de clés, surcharges de risque