encryption: cover system.raft table in system_info_encryption

Extend system_info_encryption to encrypt system.raft SSTables.
system.raft contains the Raft log, which may hold sensitive user data
(e.g. batched mutations), so it warrants the same treatment as
system.batchlog and system.paxos.

During upgrade, existing unencrypted system.raft SSTables remain
readable. Existing data is rewritten encrypted via compaction, or
immediately via nodetool upgradesstables -a.

Update the operator-facing system_info_encryption description to
mention system.raft and add a focused test that verifies the schema
extension is present on system.raft.

Fixes: CUSTOMER-268

Backport: 2026.1 - closes an encryption-at-rest coverage gap: system.raft may persist sensitive user-originated data unencrypted; backport to the current LTS.

Closes scylladb/scylladb#29242

(cherry picked from commit 91df3795fc)

Closes scylladb/scylladb#29526
This commit is contained in:
Emil Maskovsky
2026-03-27 08:25:05 +00:00
committed by Patryk Jędrzejczak
parent c4681d0975
commit 3836757486
3 changed files with 36 additions and 2 deletions

View File

@@ -1042,7 +1042,7 @@ future<seastar::shared_ptr<encryption_context>> register_extensions(const db::co
// Since we are in pre-init phase, this should be safe.
co_await smp::invoke_on_all([&opts, &exts] () mutable {
auto& f = exts.schema_extensions().at(encryption_attribute);
for (auto& s : { db::system_keyspace::paxos(), db::system_keyspace::batchlog(), db::system_keyspace::dicts() }) {
for (auto& s : { db::system_keyspace::paxos(), db::system_keyspace::batchlog(), db::system_keyspace::dicts(), db::system_keyspace::raft() }) {
exts.add_extension_to_schema(s, encryption_attribute, f(*opts));
}
});

View File

@@ -38,7 +38,7 @@ This directory should have 700 permissions and belong to the scylla user)foo")
R"foo(System information encryption settings
If enabled, system tables that may contain sensitive information (system.batchlog,
system.paxos), hints files and commit logs are encrypted with the
system.paxos, system.raft), hints files and commit logs are encrypted with the
encryption settings below.
When enabling system table encryption on a node with existing data, run

View File

@@ -41,6 +41,7 @@
#include "test/lib/azure_kms_fixture.hh"
#include "db/config.hh"
#include "db/extensions.hh"
#include "db/system_keyspace.hh"
#include "db/commitlog/commitlog.hh"
#include "db/commitlog/commitlog_replayer.hh"
#include "init.hh"
@@ -1075,6 +1076,39 @@ SEASTAR_FIXTURE_TEST_CASE(test_kms_network_error, local_aws_kms_wrapper, *check_
BOOST_AUTO_TEST_SUITE_END()
SEASTAR_TEST_CASE(test_system_info_encryption_includes_raft_tables) {
tmpdir tmp;
auto sysdir = tmp.path() / "system_keys";
auto syskey = sysdir / "system" / "system_table_keytab";
auto yaml = fmt::format("system_key_directory: {}", sysdir.string());
co_await create_key_file(syskey, { { "AES/CBC/PKCSPadding", 128 }});
test_provider_args args{
.tmp = tmp,
.extra_yaml = yaml,
};
auto [cfg, ext] = make_commitlog_config(args, {});
co_await do_with_cql_env_thread(
[](cql_test_env& env) {
auto check_has_encryption = [&](schema_ptr s) {
auto it = s->extensions().find("scylla_encryption_options");
BOOST_REQUIRE_MESSAGE(it != s->extensions().end(),
fmt::format("Expected encryption extension on {}.{}",
s->ks_name(), s->cf_name()));
BOOST_REQUIRE_MESSAGE(!it->second->is_placeholder(),
fmt::format("Encryption extension on {}.{} "
"should not be a placeholder",
s->ks_name(), s->cf_name()));
};
check_has_encryption(db::system_keyspace::raft());
},
cfg, {}, cql_test_init_configurables{ *ext });
}
SEASTAR_TEST_CASE(test_user_info_encryption) {
tmpdir tmp;
auto keyfile = tmp.path() / "secret_key";