feat(scwkm): add native ML-KEM wrapping with ml-kem-1024 as default - #15
Merged
Merged
Conversation
Scaleway Key Manager gained a `key_encapsulation` usage (`ml_kem_768`,
`ml_kem_1024`) along with the `WrapKey`/`UnwrapKey` endpoints, so the
Scaleway backend can now wrap DEKs with a post-quantum KEM instead of
classical RSA/AES only.
- keymgmt/scwkm: map ML-KEM algorithms to the new key usage, default
CreateKey to ml-kem-1024 when no algorithm is pinned, accept
PurposeKeyEncapsulation for KEM algorithms only, derive SecurityLevel
from the key class (cloud_pq_native vs cloud_classical) and report
SupportsPQNatively.
- keymgmt/scwkm: carry the algorithm in the reference URI via a new
`alg` parameter so a resolved recipient picks the wrapping path with
no extra API round trip. BuildReference keeps its signature; the new
BuildReferenceWithAlgorithm is additive.
- recipient/scwkm: add the scwkm+mlkem-{768,1024}-wrap-v1 identifiers,
route WrapKey through the native endpoint for KEM keys, and dispatch
UnwrapKey on the stored wrap algorithm so containers wrapped before
this change keep resolving through Decrypt.
- internal/scwkmapi: expose WrapKey/UnwrapKey on the client interface.
ML-KEM landed on the SDK main branch after v1.0.0-beta.37 was tagged,
so go.mod pins a pseudo-version of that branch until v1.0.0-beta.38
ships. The diff against beta.37 is purely additive.
The local-pq profile still rejects cloud-pq-native recipients: it
asserts the private key never leaves the host, which a KMS-held ML-KEM
key does not satisfy. Scaleway ML-KEM recipients use cloud-balanced,
which is documented in docs/backends/scaleway-kms.md.
Claude-Session: https://claude.ai/code/session_01K5VTFstSmgvcXMZq5My3Fy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contexte
Scaleway a ajouté une 4ᵉ classe d'usage
key_encapsulationau Key Manager, avecml_kem_768etml_kem_1024, plus deux endpointsWrapKey/UnwrapKeyréservés aux clés ML-KEM.scaleway-sdk-go#3345split asymmetric Encryption and key encapsulationscaleway-sdk-go#3361complete doc for mlkemscaleway-cli#6077 / #6115add support for ml_kem/usage.key-encapsulationLe provider Scaleway peut donc passer de
cloud-classicalàcloud-pq-native. C'est exactement la primitive qu'il faut pour envelopper un DEK de 32 octets (l'endpoint wrap accepte jusqu'à 2 Ko).Changements
keymgmt/scwkmml-kem-1024/ml-kem-768mappés surKeyUsage{KeyEncapsulation}, classeasymmetric_kemCreateKeyavecAlgorithmvide →scwkm.DefaultAlgorithm=ml-kem-1024PurposeKeyEncapsulationaccepté, mais uniquement sur un algo KEM (purpose KEM + clé AES renvoie toujoursErrUnsupportedCapability)SecurityLeveldérivé de la classe de clé :cloud_pq_nativepour ML-KEM,cloud_classicalpour AES/RSASupportsPQNatively: truealg, pour que le recipient résolu choisisse le chemin de wrapping sans aller-retour API supplémentairerecipient/scwkmscwkm+mlkem-768-wrap-v1etscwkm+mlkem-1024-wrap-v1WrapKeyroute vers l'endpoint natif pour les clés KEM, gardeEncryptsinonUnwrapKeydispatche surwk.WrapAlgorithm, pas sur la configuration du recipientinternal/scwkmapi—WrapKey/UnwrapKeyexposés sur l'interfaceClient.Compatibilité
Le module est taggé
v1.2.0, l'API publique est préservée :BuildReferencegarde sa signature ;BuildReferenceWithAlgorithmest purement additifrecipient/scwkm.Newproduit une URI identique à l'octet près (aucun changement de comportement) ;NewWithAlgorithmest le nouveau constructeur explicitescwkm+encrypt-v1continuent de se déchiffrer viaDecrypt, y compris depuis un recipient ML-KEM — c'est le rôle du dispatch sur l'algorithme stockéalgrésolvent vers le chemin classiqueDépendance
ML-KEM est arrivé sur la branche
maindu SDK après le tagv1.0.0-beta.37(31 juillet), doncgo.modépingle une pseudo-version de cette branche. Le diffbeta.37 → mainsurkey_manager/v1alpha1est purement additif : 11 déclarations ajoutées, 0 supprimée, 0 modifiée. Le retour à un tag stable est suivi dansdocs/roadmap.md.Point d'attention à l'usage
Le profil
local-pq(défaut dedocument/field) continue de refuser les recipientscloud-pq-native: il affirme que la clé privée ne quitte jamais l'hôte, ce qu'une clé ML-KEM détenue par le KMS ne satisfait pas. Les recipients Scaleway ML-KEM utilisentcloud-balanced— documenté dansdocs/backends/scaleway-kms.md.Second point :
algfait partie de l'URI, donc dukeyRefcomparé à l'unwrap. Il faut persister laKeyReferencerenvoyée par le manager plutôt que la reconstruire à la main.Tests
go test -race -timeout 300s ./...vert sur les 27 paquets. Nouveaux tests : algo par défaut, ML-KEM-768 + purpose encapsulation, mapping usage↔algo dans les deux sens, aller-retour d'URI avecalget rejet d'unalginconnu, round-trip wrap/unwrap ML-KEM mocké, dispatch legacyencrypt-v1depuis un recipient KEM, mapping d'erreurs SDK, résolution de référence côté resolver.golangci-lint: la factorisation de la map de métadonnées derecipient/scwkmfait tomber 4 des 5 findingsgoconstpréexistants. Le dernier (recipient/localmlkem/localmlkem.go:161) est préexistant et hors périmètre.