From: Christian Ebner <c.ebner@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [PATCH proxmox-backup 07/20] api: config: add endpoints for encryption key manipulation
Date: Wed, 1 Apr 2026 09:55:08 +0200 [thread overview]
Message-ID: <20260401075521.176354-8-c.ebner@proxmox.com> (raw)
In-Reply-To: <20260401075521.176354-1-c.ebner@proxmox.com>
Defines the api endpoints for listing existing keys as defined in the
config and create new keys.
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
src/api2/config/encryption_keys.rs | 115 +++++++++++++++++++++++++++++
src/api2/config/mod.rs | 2 +
2 files changed, 117 insertions(+)
create mode 100644 src/api2/config/encryption_keys.rs
diff --git a/src/api2/config/encryption_keys.rs b/src/api2/config/encryption_keys.rs
new file mode 100644
index 000000000..bc3ee2908
--- /dev/null
+++ b/src/api2/config/encryption_keys.rs
@@ -0,0 +1,115 @@
+use anyhow::{format_err, Error};
+use serde_json::Value;
+
+use proxmox_router::{Permission, Router, RpcEnvironment};
+use proxmox_schema::api;
+
+use pbs_api_types::{
+ Authid, EncryptionKey, ENCRYPTION_KEY_ID_SCHEMA, PRIV_SYS_AUDIT, PRIV_SYS_MODIFY,
+};
+
+use pbs_config::encryption_keys::{self, ENCRYPTION_KEYS_CFG_TYPE_ID};
+use pbs_config::CachedUserInfo;
+
+use pbs_key_config::KeyConfig;
+
+#[api(
+ input: {
+ properties: {},
+ },
+ returns: {
+ description: "List of configured encryption keys.",
+ type: Array,
+ items: { type: EncryptionKey },
+ },
+ access: {
+ permission: &Permission::Anybody,
+ description: "List configured encryption keys filtered by Sys.Audit privileges",
+ },
+)]
+/// List configured encryption keys.
+pub fn list_keys(
+ _param: Value,
+ rpcenv: &mut dyn RpcEnvironment,
+) -> Result<Vec<EncryptionKey>, Error> {
+ let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
+ let user_info = CachedUserInfo::new()?;
+
+ let (config, digest) = encryption_keys::config()?;
+
+ let list: Vec<EncryptionKey> = config.convert_to_typed_array(ENCRYPTION_KEYS_CFG_TYPE_ID)?;
+ let list = list
+ .into_iter()
+ .filter(|key| {
+ let privs = user_info.lookup_privs(&auth_id, &["system", "encryption-keys", &key.id]);
+ privs & PRIV_SYS_AUDIT != 0
+ })
+ .collect();
+
+ rpcenv["digest"] = hex::encode(digest).into();
+
+ Ok(list)
+}
+
+#[api(
+ protected: true,
+ input: {
+ properties: {
+ id: {
+ schema: ENCRYPTION_KEY_ID_SCHEMA,
+ },
+ key: {
+ description: "Use provided key instead of creating new one.",
+ type: String,
+ optional: true,
+ },
+ },
+ },
+ access: {
+ permission: &Permission::Privilege(&["system", "encryption-keys"], PRIV_SYS_MODIFY, false),
+ },
+)]
+/// Create new encryption key instance or use the provided one.
+pub fn create_key(
+ id: String,
+ key: Option<String>,
+ _rpcenv: &mut dyn RpcEnvironment,
+) -> Result<KeyConfig, Error> {
+ let key_config = if let Some(key) = &key {
+ serde_json::from_str(key)
+ .map_err(|err| format_err!("failed to parse provided key: {err}"))?
+ } else {
+ let mut raw_key = [0u8; 32];
+ proxmox_sys::linux::fill_with_random_data(&mut raw_key)?;
+ KeyConfig::without_password(raw_key)?
+ };
+
+ encryption_keys::store_key(&id, &key_config)?;
+
+ Ok(key_config)
+}
+
+#[api(
+ protected: true,
+ input: {
+ properties: {
+ id: {
+ schema: ENCRYPTION_KEY_ID_SCHEMA,
+ },
+ },
+ },
+ access: {
+ permission: &Permission::Privilege(&["system", "encryption-keys", "{id}"], PRIV_SYS_MODIFY, false),
+ },
+)]
+/// Remove encryption key (makes the key unusable, but keeps a backup).
+pub fn delete_key(id: String, _rpcenv: &mut dyn RpcEnvironment) -> Result<(), Error> {
+ encryption_keys::delete_key(&id).map_err(|err| format_err!("failed to delete key: {err}"))
+}
+
+const ITEM_ROUTER: Router = Router::new().delete(&API_METHOD_DELETE_KEY);
+
+pub const ROUTER: Router = Router::new()
+ .get(&API_METHOD_LIST_KEYS)
+ .post(&API_METHOD_CREATE_KEY)
+ .match_all("id", &ITEM_ROUTER);
diff --git a/src/api2/config/mod.rs b/src/api2/config/mod.rs
index 1cd9ead76..0281bcfae 100644
--- a/src/api2/config/mod.rs
+++ b/src/api2/config/mod.rs
@@ -9,6 +9,7 @@ pub mod acme;
pub mod changer;
pub mod datastore;
pub mod drive;
+pub mod encryption_keys;
pub mod media_pool;
pub mod metrics;
pub mod notifications;
@@ -28,6 +29,7 @@ const SUBDIRS: SubdirMap = &sorted!([
("changer", &changer::ROUTER),
("datastore", &datastore::ROUTER),
("drive", &drive::ROUTER),
+ ("encryption-keys", &encryption_keys::ROUTER),
("media-pool", &media_pool::ROUTER),
("metrics", &metrics::ROUTER),
("notifications", ¬ifications::ROUTER),
--
2.47.3
next prev parent reply other threads:[~2026-04-01 7:55 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-01 7:55 [PATCH proxmox{,-backup} 00/20] fix #7251: implement server side encryption support for push sync jobs Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox 01/20] pbs-api-types: define encryption key type and schema Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox 02/20] pbs-api-types: sync job: add optional encryption key to config Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 03/20] pbs-key-config: introduce store_with() for KeyConfig Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 04/20] pbs-config: implement encryption key config handling Christian Ebner
2026-04-01 23:27 ` Thomas Lamprecht
2026-04-02 7:09 ` Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 05/20] pbs-config: acls: add 'encryption-keys' as valid 'system' subpath Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 06/20] ui: expose 'encryption-keys' as acl subpath for 'system' Christian Ebner
2026-04-01 7:55 ` Christian Ebner [this message]
2026-04-01 7:55 ` [PATCH proxmox-backup 08/20] api: config: allow encryption key manipulation for sync job Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 09/20] sync: push: rewrite manifest instead of pushing pre-existing one Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 10/20] sync: add helper to check encryption key acls and load key Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 11/20] fix #7251: api: push: encrypt snapshots using configured encryption key Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 12/20] ui: define and expose encryption key management menu item and windows Christian Ebner
2026-04-01 23:09 ` Thomas Lamprecht
2026-04-03 8:35 ` Dominik Csapak
2026-04-01 23:10 ` Thomas Lamprecht
2026-04-03 12:16 ` Dominik Csapak
2026-04-01 7:55 ` [PATCH proxmox-backup 13/20] ui: expose assigning encryption key to sync jobs Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 14/20] sync: pull: load encryption key if given in job config Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 15/20] sync: expand source chunk reader trait by crypt config Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 16/20] sync: pull: introduce and use decrypt index writer if " Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 17/20] sync: pull: extend encountered chunk by optional decrypted digest Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 18/20] sync: pull: decrypt blob files on pull if encryption key is configured Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 19/20] sync: pull: decrypt chunks and rewrite index file for matching key Christian Ebner
2026-04-01 7:55 ` [PATCH proxmox-backup 20/20] sync: pull: decrypt snapshots with matching encryption key fingerprint Christian Ebner
2026-04-02 0:25 ` [PATCH proxmox{,-backup} 00/20] fix #7251: implement server side encryption support for push sync jobs Thomas Lamprecht
2026-04-02 7:37 ` Christian Ebner
2026-04-03 8:39 ` Dominik Csapak
2026-04-03 8:50 ` Christian Ebner
2026-04-03 9:00 ` Dominik Csapak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260401075521.176354-8-c.ebner@proxmox.com \
--to=c.ebner@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox