Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ Enigma is a pure Go library for high-level document and field encryption using m
- Rewrap support without content re-encryption when a valid recipient can unwrap the DEK.
- Separate compact field/value encryption API.
- Local post-quantum recipient implementation using `crypto/mlkem` (ML-KEM-768 default, ML-KEM-1024 optional).
- Cloud provider packages present as explicit capability-aware stubs (no fake crypto behavior).
- Scaleway Key Manager backend for key lifecycle, recipient resolution, and runtime DEK wrap/unwrap using the official Scaleway SDK.
- GCP/AWS/Azure provider packages present as explicit capability-aware stubs (no fake crypto behavior).

## Installation

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

## Quick Start
Expand Down Expand Up @@ -102,6 +106,29 @@ _ = document.EncryptFile(context.Background(), "plain.txt", "plain.txt.enc",
)
```

### Scaleway KMS (classical cloud backend)

```go
km, _ := keymgmtscwkm.NewManager(keymgmtscwkm.Config{
Region: "fr-par",
ProjectID: "<project-id>",
})

desc, _ := km.CreateKey(context.Background(), keymgmt.CreateKeyRequest{
Name: "org-primary",
Purpose: keymgmt.PurposeKeyWrapping,
Algorithm: keymgmt.AlgorithmAES256GCM,
ProtectionLevel: keymgmt.ProtectionKMS,
})

res, _ := resolverscwkm.New(resolverscwkm.Config{
Region: "fr-par",
ProjectID: "<project-id>",
})
runtimeRecipient, _ := res.ResolveRecipient(context.Background(), desc.Reference)
_ = document.EncryptFile(context.Background(), "plain.txt", "plain.txt.enc", document.WithRecipient(runtimeRecipient))
```

## Security Properties (Implemented)

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

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

The active capability is explicit in recipient descriptors and metadata.

For Scaleway-specific details, see [`docs/backends/scaleway-kms.md`](docs/backends/scaleway-kms.md).

## Development

```bash
Expand Down
13 changes: 12 additions & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ Enigma is structured into five layers:
1. Key lifecycle and resolution layer
- `keymgmt`: key lifecycle interfaces and domain types.
- `keymgmt/localmlkem`: local ML-KEM key manager implementation.
- `keymgmt/scwkm`: Scaleway Key Manager lifecycle backend.
- `resolver`: recipient resolution interfaces and registry.
- `resolver/localmlkem`: resolves stored local key references into runtime recipients.
- `resolver/scwkm`: resolves stored Scaleway key references into runtime recipients.
- Separates key provisioning from runtime wrapping semantics.

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

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

### Scaleway Backend Notes

- Backend ID: `scaleway_kms`.
- Security capability: `cloud-classical`.
- Uses Scaleway Key Manager as root of trust for DEK wrapping and unwrapping.
- Enigma still performs local content encryption (`XChaCha20-Poly1305` or `AES-256-GCM`).
- Wrapped DEKs and encrypted payloads are stored and managed by the application.
- No PQ-native guarantee for this backend.

### Rotation versus Rewrap

- Rotation creates or selects successor keys at lifecycle level.
Expand Down
130 changes: 130 additions & 0 deletions docs/backends/scaleway-kms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Scaleway Key Manager Backend

## Scope

Enigma provides a production-grade Scaleway backend in three separate layers:

- `keymgmt/scwkm`: key lifecycle (`CreateKey`, `GetKey`, `RotateKey`, `DeleteKey`, `Capabilities`).
- `recipient/scwkm`: runtime DEK wrap/unwrap (`WrapKey`, `UnwrapKey`).
- `resolver/scwkm`: resolve a stored `KeyReference` to a runtime recipient.

This backend uses the official Scaleway Go SDK:

- `github.com/scaleway/scaleway-sdk-go`

## Security Model

- Scaleway Key Manager is used as a root of trust for envelope encryption key custody.
- Enigma still encrypts document/field plaintext locally with AEAD.
- Enigma wraps and unwraps DEKs through Scaleway Key Manager operations.
- Wrapped DEKs are stored by the application in Enigma containers/value blobs.
- DEKs are not stored by Scaleway Key Manager for the application lifecycle.

This backend is classical cloud cryptography:

- `SecurityLevel`: `cloud_classical`
- `SupportsPQNatively`: `false`
- No post-quantum guarantee is provided by this backend.

## Supported Algorithms

Current lifecycle/runtime mapping:

- `aes-256-gcm` -> Scaleway key usage `symmetric_encryption/aes_256_gcm`
- `rsa-oaep-3072-sha256` -> Scaleway key usage `asymmetric_encryption/rsa_oaep_3072_sha256`

Not supported in this backend:

- `ml-kem-768`
- `ml-kem-1024`

Use `localmlkem` backend for local PQ workflows.

## Configuration

Shared config shape:

```go
type Config struct {
Region string
AccessKey string
SecretKey string
APIURL string
ProjectID string
}
```

Notes:

- `Region` is required for deterministic key reference resolution.
- If `AccessKey`/`SecretKey` are omitted, SDK environment/profile resolution is used.
- `APIURL` is optional (useful for controlled environments/tests).
- `ProjectID` is used for key creation context.

## KeyReference Format

Scaleway references are serialized as generic Enigma `KeyReference` values:

- `Backend`: `scaleway_kms`
- `ID`: Scaleway key ID
- `Version`: key rotation count string
- `URI`: `enigma-scwkm://key/<key-id>?region=<region>&project_id=<project-id>&version=<n>`

`KeyReference` never stores credentials or private key material.

## Usage Pattern

### 1) Create key and persist reference

```go
km, _ := keymgmtscwkm.NewManager(keymgmtscwkm.Config{Region: "fr-par", ProjectID: "<project-id>"})
desc, _ := km.CreateKey(ctx, keymgmt.CreateKeyRequest{
Name: "org-a-primary",
Purpose: keymgmt.PurposeKeyWrapping,
Algorithm: keymgmt.AlgorithmAES256GCM,
ProtectionLevel: keymgmt.ProtectionKMS,
})

// Store desc.Reference in your application database.
_ = desc.Reference
```

### 2) Resolve recipient at runtime

```go
res, _ := resolverscwkm.New(resolverscwkm.Config{Region: "fr-par", ProjectID: "<project-id>"})
runtimeRecipient, _ := res.ResolveRecipient(ctx, storedRef)
```

### 3) Encrypt/decrypt with existing document/field APIs

```go
_ = document.EncryptFile(ctx, "plain.txt", "plain.txt.enc", document.WithRecipient(runtimeRecipient))
_ = document.DecryptFile(ctx, "plain.txt.enc", "plain.dec.txt", document.WithRecipient(runtimeRecipient))
```

## Rotation vs Rewrap

- `KeyManager.RotateKey` rotates backend key material/provider version.
- `document.Rewrap` updates recipient entries in existing encrypted containers.

These are distinct operations and must be orchestrated explicitly by the application.

## Capability Set

Scaleway backend reports:

- `CanCreateKeys = true`
- `CanDeleteKeys = true`
- `CanRotateProviderNative = true`
- `CanExportPublicKey = true` (backend capability)
- `CanResolveRecipient = true`
- `SupportsPQNatively = false`
- `SupportsClassicalWrapping = true`
- `SupportsRewrapWorkflow = true`

## Current Limitations

- No PQ-native wrapping.
- Only explicitly mapped algorithms are accepted.
- Live cloud integration tests are optional and not required for standard CI runs.
16 changes: 16 additions & 0 deletions docs/key-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,22 @@ The local backend is implemented in:
- protect the configured root path with strict OS permissions
- if host compromise is in scope, local software key storage may be insufficient

## Scaleway Key Manager Backend

The Scaleway backend is implemented in:
- `keymgmt/scwkm`
- `resolver/scwkm`
- `recipient/scwkm`

Properties:
- cloud classical security level (`cloud_classical`)
- no native PQ guarantee
- provider-native key rotation support via Key Manager
- runtime recipient resolution from stored `KeyReference`

Reference documentation:
- `docs/backends/scaleway-kms.md`

## Rotation and Rewrap

Rotation and rewrap are intentionally distinct operations:
Expand Down
22 changes: 15 additions & 7 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
- Local ML-KEM recipient implementation
- Key lifecycle abstraction (`keymgmt`) and recipient resolution abstraction (`resolver`)
- Local ML-KEM key manager and resolver implementation
- Scaleway Key Manager backend:
- `keymgmt/scwkm` lifecycle implementation
- `recipient/scwkm` runtime DEK wrap/unwrap
- `resolver/scwkm` key-reference resolution
- Chunked document encryption and stream APIs
- Rewrap path without content re-encryption
- Field encryption compact format
Expand All @@ -14,23 +18,27 @@

## Planned Next

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

2. Stronger policy controls
2. Scaleway integration hardening
- Add opt-in live integration tests (credential-gated) for create/get/rotate/delete and wrap/unwrap flows.
- Add operational guidance for key policies and production rollout checks.

3. Stronger policy controls
- Optional stricter profile/policy validation helpers.
- Explicit compliance constraints for algorithm and recipient mixes.

3. Signature extension
4. Signature extension
- Add optional signed footer extension for authenticity provenance.

4. Advanced rewrap tooling
5. Advanced rewrap tooling
- CLI improvements for inspection/rewrap automation.
- Batch workflows that combine successor-key rotation and explicit rewrap execution.

5. Hardening and observability
6. Hardening and observability
- Additional fuzzing corpora.
- Performance profiling on large object streams.
- More fault-injection tests.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/hyperscale-stack/enigma
go 1.25.0

require (
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36
github.com/stretchr/testify v1.11.1
golang.org/x/crypto v0.49.0
)
Expand All @@ -11,5 +12,6 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.42.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36 h1:ObX9hZmK+VmijreZO/8x9pQ8/P/ToHD/bdSb4Eg4tUo=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36/go.mod h1:LEsDu4BubxK7/cWhtlQWfuxwL4rf/2UEpxXz1o1EMtM=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
Expand All @@ -10,5 +12,7 @@ golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Loading