Skip to content

ref(service): Generalize encryption util - #615

Open
lcian wants to merge 2 commits into
mainfrom
ref/generalize-encryption-cipher
Open

ref(service): Generalize encryption util#615
lcian wants to merge 2 commits into
mainfrom
ref/generalize-encryption-cipher

Conversation

@lcian

@lcian lcian commented Sep 8, 2026

Copy link
Copy Markdown
Member

Authenticated encryption is now moved from resumable.rs to a reusable objectstore-service::encryption::Cipher struct whose encrypt and decrypt methods work with any serde type.

resumable_token_encryption has been renamed to cipher/encryption throughout, so configuration now happens as follows:

service:
  encryption: ...

Move authenticated encryption into a reusable Cipher with method-level serde generics while preserving the existing envelope format.

BREAKING CHANGE: Rename service.resumable_token_encryption to service.encryption.
@codecov

This comment has been minimized.

@lcian lcian changed the title ref(service)!: Generalize encryption cipher ref(service): Generalize encryption cipher Sep 8, 2026
@lcian lcian changed the title ref(service): Generalize encryption cipher ref(service): Generalize encryption util Sep 8, 2026
@lcian

This comment has been minimized.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 28141dd. Configure here.

@lcian
lcian marked this pull request as ready for review September 8, 2026 13:07
@lcian
lcian requested a review from a team as a code owner September 8, 2026 13:07
@lcian
lcian requested a review from jan-auer September 8, 2026 13:07
///
/// Returns `None` if the envelope is malformed, cannot be authenticated, or does not contain
/// the requested type.
pub(crate) fn decrypt<T>(&self, envelope: &[u8]) -> Option<T>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is right or if we should rather return a Result here.
Option can still be mapped externally and has the advantage of not exposing the source Error in case anything fails, which could provide some info to an attacker.
So perhaps Option is the right fit here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is useful to keep the source error here for internal error tracking and rather restrict sources in the public API.

/// persistent keyring for sessions that must survive restarts. Keep old keys configured while
/// their sessions may still be active; removing a key intentionally invalidates those sessions.
/// Values must be raw AES-256 key bytes.
/// This is used to instantiate [`Cipher`] which can encrypt/decrypt arbitrary payloads for

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This should better be directed at an operator rather than engineer, hence describe what functionality this is used for and how it changes objectstore's behavior, rather than the code-level constructs.

We can put relevant code comments onto the cipher method.

/// Currently, this is only used for session tokens of the Resumable Uploads API.
///
/// When this config is absent, Objectstore generates a fresh in-memory key at startup.
/// This might not work for requests that need to survive a deployment or multi-instance

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not work for certain.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For resumable uploads it will not work, for other things that we use this in the future, it might...

///
/// Returns `None` if the envelope is malformed, cannot be authenticated, or does not contain
/// the requested type.
pub(crate) fn decrypt<T>(&self, envelope: &[u8]) -> Option<T>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is useful to keep the source error here for internal error tracking and rather restrict sources in the public API.

/// File-backed secrets should use `${file:PATH}` so they are loaded during configuration
/// deserialization.
#[serde(default)]
pub keys: BTreeMap<String, Bytes>,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's nice that this works with Bytes, but if we need exactly 32 raw key bytes we can:

  • Implement our own newtype that performs the deserialization
  • Consider to store the bytes inline as [u8; 32].

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point!

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.

2 participants