Skip to content

feat: add support for S3 SSE-C (customer-provided encryption keys) - #284

Open
schaurian wants to merge 2 commits into
cloudnative-pg:mainfrom
schaurian:feat/s3-sse-c
Open

feat: add support for S3 SSE-C (customer-provided encryption keys)#284
schaurian wants to merge 2 commits into
cloudnative-pg:mainfrom
schaurian:feat/s3-sse-c

Conversation

@schaurian

@schaurian schaurian commented Jul 19, 2026

Copy link
Copy Markdown

Summary

Adds support for S3 Server-Side Encryption with Customer-provided keys (SSE-C) to the barman-cloud library.

A new optional sseCustomerKey field on S3Credentials references a secret holding a base64-encoded 256-bit AES key. When set, the key is materialized to a file and passed to every barman-cloud command via the --sse-customer-key file:// option.

This is the library-side change needed to close cloudnative-pg/plugin-barman-cloud#646 — S3-compatible providers such as Hetzner Object Storage only support SSE-C for encryption at rest, so the existing bucket-managed encryption field (SSE-S3 / SSE-KMS) cannot be used with them.

What changed

File Change
pkg/api/config.go New SSECustomerKey *SecretKeySelector field on S3Credentials (+ generated deepcopy)
pkg/utils/constants.go SSECustomerKeyFileLocation — the on-disk path for the materialized key
pkg/credentials/env.go Materialize/remove the key file from the referenced secret (same pattern as the Google credentials file)
pkg/command/commandbuilder.go Inject --sse-customer-key file://… in the shared appendCloudProviderOptions
pkg/command/commandbuilder_test.go Unit tests for the AWS SSE-C option
pkg/api/webhooks/config.go Reject sseCustomerKey combined with data.encryption / wal.encryption (by @andrein, with tests)

Design notes

  • Single injection point. The flag is added in appendCloudProviderOptions, through which every command builder already routes (barman-cloud-backup, -wal-archive, -wal-restore, -restore, -backup-list, -backup-delete, -check-wal-archive). SSE-C requires the key on every read and write, so covering the shared chokepoint avoids the classic "backups succeed but restores fail because a read path was missed" footgun.
  • Key materialization mirrors the existing Google credentials handling (reconcileGoogleCredentials → a /controller/... file written atomically with 0600), so no new volume-mount plumbing is needed in consumers; the same code path serves both the operator and the plugin sidecar.
  • Mutually exclusive with encryption. barman-cloud rejects --sse-customer-key together with --encryption at run time, so ValidateBackupConfiguration now reports one error per offending field (data.encryption, wal.encryption) when sseCustomerKey is set, instead of letting the first backup fail.
  • Auth-method independent. The key is materialized before the auth branching in envSetAWSCredentials, so it works with explicit keys, session tokens, and inheritFromIAMRole.

Dependency / rollout

Runtime use requires Barman ≥ 3.20.0, which ships the --sse-customer-key option (EnterpriseDB/barman#973, released 2026-08-27). The plugin-barman-cloud sidecar pins Barman 3.20.0 since v0.15.0. The plugin side of this feature is cloudnative-pg/plugin-barman-cloud#1017.

Testing

  • Full task ci run locally (commitlint, spellcheck, golangci-lint v2.13.2, go test ./..., uncommitted-drift check): all green.
  • Field-tested by @andrein against a Ceph RGW store that supports only SSE-C, with CloudNativePG 1.30.0 and plugin-barman-cloud#1017 (WAL archiving, base backup, backup-list, retention via backup-delete, and recovery into a new Cluster all working with Encryption: SSE-C objects) — see the comments below.

🤖 Generated with Claude Code

@schaurian
schaurian requested a review from a team July 19, 2026 02:35
@schaurian
schaurian requested a review from a team as a code owner August 9, 2026 13:26
schaurian added a commit to schaurian/plugin-barman-cloud that referenced this pull request Aug 9, 2026
Surface the new `sseCustomerKey` field on `s3Credentials` through the
ObjectStore CRD so users can enable Server-Side Encryption with
Customer-provided keys (SSE-C). This is required by S3-compatible
providers that only support SSE-C for encryption at rest, such as
Hetzner Object Storage.

The field flows through the embedded BarmanObjectStoreConfiguration
from the barman-cloud library, so this change is limited to bumping the
dependency, regenerating the CRD and the consolidated manifest, and
documenting usage in the object stores guide.

Depends on cloudnative-pg/barman-cloud#284 (temporarily pinned via a
replace directive until that change is released).

Closes cloudnative-pg#646

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Florian Schauer <florian@schauer.to>
@fkammer

fkammer commented Sep 2, 2026

Copy link
Copy Markdown

FYI: barman release is out: https://github.com/EnterpriseDB/barman/releases/tag/release%2F3.20.0

@andrein

andrein commented Sep 8, 2026

Copy link
Copy Markdown

Tested at a300841 against a Ceph RGW object store that supports only SSE-C
(no SSE-S3 or SSE-KMS), with CloudNativePG 1.30.0 and the Barman Cloud plugin
from cloudnative-pg/plugin-barman-cloud#1017 with main merged in for
Barman 3.20.0.

  • WAL archiving continuous; objects under wals/ report Encryption: SSE-C
    and return 400 when read without the key
  • base backup completed; Backup.status populated by barman-cloud-backup-list
    reading the SSE-C backup.info
  • ObjectStore.status.serverRecoveryWindow populated
  • retention policy applied on the primary via barman-cloud-backup-delete
  • recovery into a new Cluster through externalClusters[].plugin reproduced
    the source database: same row counts, table count and size

--sse-customer-key together with --encryption is rejected by Barman at run
time; schaurian#1 against this branch adds the corresponding check
to ValidateBackupConfiguration.

schaurian and others added 2 commits September 8, 2026 16:27
Add an `sseCustomerKey` field to the S3 credentials that references a
secret holding a base64-encoded 256-bit AES key. When set, the key is
materialized to a file and passed to every barman-cloud command through
the `--sse-customer-key file://` option, enabling Server-Side Encryption
with Customer-provided keys (SSE-C).

This is required by S3-compatible providers that only support SSE-C for
encryption at rest (e.g. Hetzner Object Storage). The option is injected
in the shared `appendCloudProviderOptions` chokepoint, so it applies to
all barman-cloud-* commands (backup, wal-archive, wal-restore, restore,
backup-list, backup-delete, check-wal-archive), and is orthogonal to the
existing bucket-managed `encryption` (SSE-S3/SSE-KMS) option. The key is
materialized before the auth-method branching so it works with every
authentication method, including inheritFromIAMRole.

Requires a barman release that ships the `--sse-customer-key` option
(EnterpriseDB/barman#973).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Florian Schauer <florian@schauer.to>
The barman-cloud commands refuse --sse-customer-key together with
--encryption, so a configuration setting both fails on the first backup.
Reject it at validation time instead, on the data and wal encryption
fields.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Andrei Nistor <andrei@nistor.tech>
schaurian added a commit to schaurian/plugin-barman-cloud that referenced this pull request Sep 8, 2026
Surface the new `sseCustomerKey` field on `s3Credentials` through the
ObjectStore CRD so users can enable Server-Side Encryption with
Customer-provided keys (SSE-C). This is required by S3-compatible
providers that only support SSE-C for encryption at rest, such as
Hetzner Object Storage.

The field flows through the embedded BarmanObjectStoreConfiguration
from the barman-cloud library, so this change is limited to bumping the
dependency, regenerating the CRD and the consolidated manifest, and
documenting usage in the object stores guide.

Depends on cloudnative-pg/barman-cloud#284 (temporarily pinned via a
replace directive until that change is released).

Closes cloudnative-pg#646

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Florian Schauer <florian@schauer.to>
@schaurian

Copy link
Copy Markdown
Author

Thanks for the test run and the validation change, @andrein — merged schaurian#1 into this branch.

Updated the branch (14f89b6):

  • Rebased onto main (v0.6.0); the SSE-C commit and the validation commit are now separate commits on top of it.
  • Reworded the body of the validation commit to start with a capital letter: this repo's commitlint enforces body-case: sentence-case, and that was the one task ci failure on the previous head. Author and sign-off are unchanged.
  • The SSECustomerKey API comment used to say the field is "orthogonal" to encryption; it now states that the two cannot be combined, matching the validation. Description updated accordingly.

Full task ci (commitlint, spellcheck, golangci-lint v2.13.2, go test ./..., uncommitted-drift check) passes locally on this head.

For the record, Barman 3.20.0 with --sse-customer-key is released, and cloudnative-pg/plugin-barman-cloud#1017 is rebased on a main whose sidecar pins it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature request] Support for S3 SSE-C - Server-Side Encryption with Customer-provided keys

3 participants