[PATCH proxmox-backup v3 12/30] api: config: check sync owner has access to en-/decryption keys

Christian Ebner
2026-04-14T12:59:45Z

So a sync job can not be configured with a non existing or non
accessible key for given sync owner/local-user.

Key access is checked by loading the key from the keyfile.
When setting the active encryption key for push sync jobs it is
further assured that the key is not archived yet.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
changes since version 2:
- fix check for key access when setting active encryption key. It must fail for archived keys.

src/api2/config/sync.rs | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)

diff --git a/src/api2/config/sync.rs b/src/api2/config/sync.rs
index 67fa3182c..75b99c2a7 100644
--- a/src/api2/config/sync.rs
+++ b/src/api2/config/sync.rs
@@ -62,6 +62,22 @@ fn is_correct_owner(auth_id: &Authid, job: &SyncJobConfig) -> bool {
}
}

+// Check access and test key loading works as expected for sync job owner/user.
+fn sync_user_can_access_optional_key(
+ key_id: Option<&str>,
+ owner: &Authid,
+ fail_on_archived: bool,
+) -> Result<(), Error> {
+ if let Some(key_id) = key_id {
+ if crate::server::sync::check_privs_and_load_key_config(key_id, owner, fail_on_archived)
+ .is_err()
+ {
+ bail!("no such key or cannot access key '{key_id}'");
+ }
+ }
+ Ok(())
+}
+
/// checks whether user can run the corresponding sync job, depending on sync direction
///
/// namespace creation/deletion ACL and backup group ownership checks happen in the pull/push code
@@ -251,6 +267,19 @@ pub fn create_sync_job(
}
}

+ let owner = config
+ .owner
+ .as_ref()
+ .unwrap_or_else(|| Authid::root_auth_id());
+
+ if sync_direction == SyncDirection::Push {
+ sync_user_can_access_optional_key(config.active_encryption_key.as_deref(), owner, true)?;
+ } else {
+ for key in config.associated_key.as_deref().unwrap_or(&[]) {
+ sync_user_can_access_optional_key(Some(key), owner, false)?;
+ }
+ }
+
let (mut section_config, _digest) = sync::config()?;

if section_config.sections.contains_key(&config.id) {
--
2.47.3