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

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

View File

@@ -1045,7 +1045,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

@@ -38,6 +38,7 @@
#include "test/lib/proc_utils.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"
@@ -794,6 +795,39 @@ static auto make_commitlog_config(const test_provider_args& args, const std::uno
return std::make_tuple(cfg, ext);
}
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 });
}
static future<> test_encrypted_commitlog(const test_provider_args& args, std::unordered_map<std::string, std::string> scopts = {}) {
fs::path clback = args.tmp.path() / "commitlog_back";