Skip to content

Commit 0d298eb

Browse files
authored
Merge pull request #2 from hyperscale-stack/feature/scaleway-support
feat: add scaleway support
2 parents e4c5fdf + 92b5483 commit 0d298eb

15 files changed

Lines changed: 1411 additions & 33 deletions

File tree

README.md

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ Enigma is a pure Go library for high-level document and field encryption using m
1212
- Rewrap support without content re-encryption when a valid recipient can unwrap the DEK.
1313
- Separate compact field/value encryption API.
1414
- Local post-quantum recipient implementation using `crypto/mlkem` (ML-KEM-768 default, ML-KEM-1024 optional).
15-
- Cloud provider packages present as explicit capability-aware stubs (no fake crypto behavior).
15+
- Scaleway Key Manager backend for key lifecycle, recipient resolution, and runtime DEK wrap/unwrap using the official Scaleway SDK.
16+
- GCP/AWS/Azure provider packages present as explicit capability-aware stubs (no fake crypto behavior).
1617

1718
## Installation
1819

@@ -27,11 +28,14 @@ go get github.com/hyperscale-stack/enigma
2728
- `container`: strict parser/serializer for the binary envelope format.
2829
- `recipient`: recipient abstractions and capability model.
2930
- `recipient/localmlkem`: fully implemented local PQ recipient.
30-
- `recipient/{gcpkms,awskms,azurekv,scwkm}`: explicit cloud stubs for v1.
31+
- `recipient/scwkm`: Scaleway Key Manager runtime recipient (classical cloud wrapping).
32+
- `recipient/{gcpkms,awskms,azurekv}`: explicit cloud stubs for v1.
3133
- `keymgmt`: key lifecycle interfaces and domain types.
3234
- `keymgmt/localmlkem`: local ML-KEM key manager with filesystem-backed metadata persistence.
35+
- `keymgmt/scwkm`: Scaleway Key Manager lifecycle backend.
3336
- `resolver`: recipient resolver interfaces and backend registry.
3437
- `resolver/localmlkem`: resolves local key references into runtime recipients.
38+
- `resolver/scwkm`: resolves Scaleway key references into runtime recipients.
3539
- `mem`: best-effort memory hygiene helpers.
3640

3741
## Quick Start
@@ -102,6 +106,29 @@ _ = document.EncryptFile(context.Background(), "plain.txt", "plain.txt.enc",
102106
)
103107
```
104108

109+
### Scaleway KMS (classical cloud backend)
110+
111+
```go
112+
km, _ := keymgmtscwkm.NewManager(keymgmtscwkm.Config{
113+
Region: "fr-par",
114+
ProjectID: "<project-id>",
115+
})
116+
117+
desc, _ := km.CreateKey(context.Background(), keymgmt.CreateKeyRequest{
118+
Name: "org-primary",
119+
Purpose: keymgmt.PurposeKeyWrapping,
120+
Algorithm: keymgmt.AlgorithmAES256GCM,
121+
ProtectionLevel: keymgmt.ProtectionKMS,
122+
})
123+
124+
res, _ := resolverscwkm.New(resolverscwkm.Config{
125+
Region: "fr-par",
126+
ProjectID: "<project-id>",
127+
})
128+
runtimeRecipient, _ := res.ResolveRecipient(context.Background(), desc.Reference)
129+
_ = document.EncryptFile(context.Background(), "plain.txt", "plain.txt.enc", document.WithRecipient(runtimeRecipient))
130+
```
131+
105132
## Security Properties (Implemented)
106133

107134
- Confidentiality and authenticity of encrypted content when recipients and primitives are used correctly.
@@ -113,7 +140,8 @@ _ = document.EncryptFile(context.Background(), "plain.txt", "plain.txt.enc",
113140
## Important Limitations
114141

115142
- Go memory is not fully controllable; key wiping is best-effort only.
116-
- v1 cloud providers are stubs and return `ErrNotImplemented` for wrapping/unwrapping.
143+
- Scaleway backend is classical cloud wrapping only and does not provide PQ-native guarantees.
144+
- GCP/AWS/Azure backend packages are still stubs and return `ErrNotImplemented` for wrapping/unwrapping.
117145
- Key lifecycle mapping (for example one key per tenant or organization) is application-owned.
118146
- Recipient metadata (type/key references/capability labels) is inspectable by design and not encrypted.
119147
- No signatures in v1 (footer/signature area is an extension point only).
@@ -135,6 +163,8 @@ _ = document.EncryptFile(context.Background(), "plain.txt", "plain.txt.enc",
135163

136164
The active capability is explicit in recipient descriptors and metadata.
137165

166+
For Scaleway-specific details, see [`docs/backends/scaleway-kms.md`](docs/backends/scaleway-kms.md).
167+
138168
## Development
139169

140170
```bash

docs/architecture.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@ Enigma is structured into five layers:
77
1. Key lifecycle and resolution layer
88
- `keymgmt`: key lifecycle interfaces and domain types.
99
- `keymgmt/localmlkem`: local ML-KEM key manager implementation.
10+
- `keymgmt/scwkm`: Scaleway Key Manager lifecycle backend.
1011
- `resolver`: recipient resolution interfaces and registry.
1112
- `resolver/localmlkem`: resolves stored local key references into runtime recipients.
13+
- `resolver/scwkm`: resolves stored Scaleway key references into runtime recipients.
1214
- Separates key provisioning from runtime wrapping semantics.
1315

1416
2. Recipient / key wrapping layer
1517
- Defines recipient interface.
1618
- Wraps and unwraps a random DEK.
17-
- Supports local PQ recipient (ML-KEM) and cloud-provider stubs with explicit capabilities.
19+
- Supports local PQ recipient (ML-KEM), Scaleway KMS classical recipient, and cloud-provider stubs with explicit capabilities.
1820

1921
3. Symmetric encryption layer
2022
- Uses one DEK per encrypted object.
@@ -57,6 +59,15 @@ Enigma is structured into five layers:
5759
- `KeyReference` is stable, serializable metadata that never includes private key material.
5860
- Application key ownership mapping (for example per tenant or per organization) is handled by the application, not by Enigma.
5961

62+
### Scaleway Backend Notes
63+
64+
- Backend ID: `scaleway_kms`.
65+
- Security capability: `cloud-classical`.
66+
- Uses Scaleway Key Manager as root of trust for DEK wrapping and unwrapping.
67+
- Enigma still performs local content encryption (`XChaCha20-Poly1305` or `AES-256-GCM`).
68+
- Wrapped DEKs and encrypted payloads are stored and managed by the application.
69+
- No PQ-native guarantee for this backend.
70+
6071
### Rotation versus Rewrap
6172

6273
- Rotation creates or selects successor keys at lifecycle level.

docs/backends/scaleway-kms.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Scaleway Key Manager Backend
2+
3+
## Scope
4+
5+
Enigma provides a production-grade Scaleway backend in three separate layers:
6+
7+
- `keymgmt/scwkm`: key lifecycle (`CreateKey`, `GetKey`, `RotateKey`, `DeleteKey`, `Capabilities`).
8+
- `recipient/scwkm`: runtime DEK wrap/unwrap (`WrapKey`, `UnwrapKey`).
9+
- `resolver/scwkm`: resolve a stored `KeyReference` to a runtime recipient.
10+
11+
This backend uses the official Scaleway Go SDK:
12+
13+
- `github.com/scaleway/scaleway-sdk-go`
14+
15+
## Security Model
16+
17+
- Scaleway Key Manager is used as a root of trust for envelope encryption key custody.
18+
- Enigma still encrypts document/field plaintext locally with AEAD.
19+
- Enigma wraps and unwraps DEKs through Scaleway Key Manager operations.
20+
- Wrapped DEKs are stored by the application in Enigma containers/value blobs.
21+
- DEKs are not stored by Scaleway Key Manager for the application lifecycle.
22+
23+
This backend is classical cloud cryptography:
24+
25+
- `SecurityLevel`: `cloud_classical`
26+
- `SupportsPQNatively`: `false`
27+
- No post-quantum guarantee is provided by this backend.
28+
29+
## Supported Algorithms
30+
31+
Current lifecycle/runtime mapping:
32+
33+
- `aes-256-gcm` -> Scaleway key usage `symmetric_encryption/aes_256_gcm`
34+
- `rsa-oaep-3072-sha256` -> Scaleway key usage `asymmetric_encryption/rsa_oaep_3072_sha256`
35+
36+
Not supported in this backend:
37+
38+
- `ml-kem-768`
39+
- `ml-kem-1024`
40+
41+
Use `localmlkem` backend for local PQ workflows.
42+
43+
## Configuration
44+
45+
Shared config shape:
46+
47+
```go
48+
type Config struct {
49+
Region string
50+
AccessKey string
51+
SecretKey string
52+
APIURL string
53+
ProjectID string
54+
}
55+
```
56+
57+
Notes:
58+
59+
- `Region` is required for deterministic key reference resolution.
60+
- If `AccessKey`/`SecretKey` are omitted, SDK environment/profile resolution is used.
61+
- `APIURL` is optional (useful for controlled environments/tests).
62+
- `ProjectID` is used for key creation context.
63+
64+
## KeyReference Format
65+
66+
Scaleway references are serialized as generic Enigma `KeyReference` values:
67+
68+
- `Backend`: `scaleway_kms`
69+
- `ID`: Scaleway key ID
70+
- `Version`: key rotation count string
71+
- `URI`: `enigma-scwkm://key/<key-id>?region=<region>&project_id=<project-id>&version=<n>`
72+
73+
`KeyReference` never stores credentials or private key material.
74+
75+
## Usage Pattern
76+
77+
### 1) Create key and persist reference
78+
79+
```go
80+
km, _ := keymgmtscwkm.NewManager(keymgmtscwkm.Config{Region: "fr-par", ProjectID: "<project-id>"})
81+
desc, _ := km.CreateKey(ctx, keymgmt.CreateKeyRequest{
82+
Name: "org-a-primary",
83+
Purpose: keymgmt.PurposeKeyWrapping,
84+
Algorithm: keymgmt.AlgorithmAES256GCM,
85+
ProtectionLevel: keymgmt.ProtectionKMS,
86+
})
87+
88+
// Store desc.Reference in your application database.
89+
_ = desc.Reference
90+
```
91+
92+
### 2) Resolve recipient at runtime
93+
94+
```go
95+
res, _ := resolverscwkm.New(resolverscwkm.Config{Region: "fr-par", ProjectID: "<project-id>"})
96+
runtimeRecipient, _ := res.ResolveRecipient(ctx, storedRef)
97+
```
98+
99+
### 3) Encrypt/decrypt with existing document/field APIs
100+
101+
```go
102+
_ = document.EncryptFile(ctx, "plain.txt", "plain.txt.enc", document.WithRecipient(runtimeRecipient))
103+
_ = document.DecryptFile(ctx, "plain.txt.enc", "plain.dec.txt", document.WithRecipient(runtimeRecipient))
104+
```
105+
106+
## Rotation vs Rewrap
107+
108+
- `KeyManager.RotateKey` rotates backend key material/provider version.
109+
- `document.Rewrap` updates recipient entries in existing encrypted containers.
110+
111+
These are distinct operations and must be orchestrated explicitly by the application.
112+
113+
## Capability Set
114+
115+
Scaleway backend reports:
116+
117+
- `CanCreateKeys = true`
118+
- `CanDeleteKeys = true`
119+
- `CanRotateProviderNative = true`
120+
- `CanExportPublicKey = true` (backend capability)
121+
- `CanResolveRecipient = true`
122+
- `SupportsPQNatively = false`
123+
- `SupportsClassicalWrapping = true`
124+
- `SupportsRewrapWorkflow = true`
125+
126+
## Current Limitations
127+
128+
- No PQ-native wrapping.
129+
- Only explicitly mapped algorithms are accepted.
130+
- Live cloud integration tests are optional and not required for standard CI runs.

docs/key-management.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,22 @@ The local backend is implemented in:
5252
- protect the configured root path with strict OS permissions
5353
- if host compromise is in scope, local software key storage may be insufficient
5454

55+
## Scaleway Key Manager Backend
56+
57+
The Scaleway backend is implemented in:
58+
- `keymgmt/scwkm`
59+
- `resolver/scwkm`
60+
- `recipient/scwkm`
61+
62+
Properties:
63+
- cloud classical security level (`cloud_classical`)
64+
- no native PQ guarantee
65+
- provider-native key rotation support via Key Manager
66+
- runtime recipient resolution from stored `KeyReference`
67+
68+
Reference documentation:
69+
- `docs/backends/scaleway-kms.md`
70+
5571
## Rotation and Rewrap
5672

5773
Rotation and rewrap are intentionally distinct operations:

docs/roadmap.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
- Local ML-KEM recipient implementation
77
- Key lifecycle abstraction (`keymgmt`) and recipient resolution abstraction (`resolver`)
88
- Local ML-KEM key manager and resolver implementation
9+
- Scaleway Key Manager backend:
10+
- `keymgmt/scwkm` lifecycle implementation
11+
- `recipient/scwkm` runtime DEK wrap/unwrap
12+
- `resolver/scwkm` key-reference resolution
913
- Chunked document encryption and stream APIs
1014
- Rewrap path without content re-encryption
1115
- Field encryption compact format
@@ -14,23 +18,27 @@
1418

1519
## Planned Next
1620

17-
1. Provider lifecycle backends
18-
- Add `KeyManager` and `RecipientResolver` implementations for cloud backends.
21+
1. Remaining provider lifecycle backends
22+
- Add `KeyManager` and `RecipientResolver` implementations for GCP/AWS/Azure.
1923
- Keep capability reporting explicit for native rotation versus successor workflows.
20-
- Add live integration test matrix behind opt-in configuration.
24+
- Keep unsupported capabilities explicit; no fake cloud behavior.
2125

22-
2. Stronger policy controls
26+
2. Scaleway integration hardening
27+
- Add opt-in live integration tests (credential-gated) for create/get/rotate/delete and wrap/unwrap flows.
28+
- Add operational guidance for key policies and production rollout checks.
29+
30+
3. Stronger policy controls
2331
- Optional stricter profile/policy validation helpers.
2432
- Explicit compliance constraints for algorithm and recipient mixes.
2533

26-
3. Signature extension
34+
4. Signature extension
2735
- Add optional signed footer extension for authenticity provenance.
2836

29-
4. Advanced rewrap tooling
37+
5. Advanced rewrap tooling
3038
- CLI improvements for inspection/rewrap automation.
3139
- Batch workflows that combine successor-key rotation and explicit rewrap execution.
3240

33-
5. Hardening and observability
41+
6. Hardening and observability
3442
- Additional fuzzing corpora.
3543
- Performance profiling on large object streams.
3644
- More fault-injection tests.

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/hyperscale-stack/enigma
33
go 1.25.0
44

55
require (
6+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36
67
github.com/stretchr/testify v1.11.1
78
golang.org/x/crypto v0.49.0
89
)
@@ -11,5 +12,6 @@ require (
1112
github.com/davecgh/go-spew v1.1.1 // indirect
1213
github.com/pmezard/go-difflib v1.0.0 // indirect
1314
golang.org/x/sys v0.42.0 // indirect
15+
gopkg.in/yaml.v2 v2.4.0 // indirect
1416
gopkg.in/yaml.v3 v3.0.1 // indirect
1517
)

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
22
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
33
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
44
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36 h1:ObX9hZmK+VmijreZO/8x9pQ8/P/ToHD/bdSb4Eg4tUo=
6+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36/go.mod h1:LEsDu4BubxK7/cWhtlQWfuxwL4rf/2UEpxXz1o1EMtM=
57
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
68
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
79
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
@@ -10,5 +12,7 @@ golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
1012
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
1113
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
1214
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
15+
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
16+
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
1317
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
1418
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 commit comments

Comments
 (0)