Skip to content

Add Signer trait - #340

Open
wbourne0 wants to merge 3 commits into
eclipse-biscuit:mainfrom
wbourne0:signer-trait
Open

Add Signer trait#340
wbourne0 wants to merge 3 commits into
eclipse-biscuit:mainfrom
wbourne0:signer-trait

Conversation

@wbourne0

@wbourne0 wbourne0 commented Aug 2, 2026

Copy link
Copy Markdown

Another attempt at allowing for private keys which are not in-memory (e.g. for HSMs, TPMs, KMS). This is a minimal implementation to add an interface for arbitrary signers. Currently only supports root keys.

In the future, an async version of this trait could be added (which would be great for KMS and similar). For now this is considered out of scope, as async versions of the rest of the code would need to be added.

Closes

The closest other PR to this is #334, but it's adding a lot more at once and seems to be incomplete. This PR aims to be as simple as possible and to be non-breaking.

#320 may be closed by this too, depending on whether first party AWS support is desired or not.

Comment on lines +450 to 454
/// A signature of a [Biscuit](crate::Biscuit) block.
///
/// May be constructed via [Into] from [ed25519_dalek::Signature] or
/// from [ecdsa::Signature] with the [NistP256](::p256::NistP256) curve.
pub struct Signature(pub(crate) Vec<u8>);

@wbourne0 wbourne0 Aug 2, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Previously this was implicitly public as a return type; now it's explicit (hence the added comment) and addressable.

There may be some merit with regards to changing this into an enum type, although this may technically be a breaking change.

Comment on lines -435 to -438
pub fn from_bytes(data: &[u8]) -> Result<Self, error::Format> {
Ok(Signature(data.to_owned()))
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This was never usable before as Signature wasn't exposed publicly. I've opted to remove it since it's fairly unsafe. Happy to add it back.

Comment on lines +11 to +18
pub trait Signer {
/// The algorithm used. Must match the signature returned via [sign](Self::sign).
fn algorithm(&self) -> Algorithm;
/// Sign a series of bytes, returning a signature. This signature must match
/// what [self.algorithm()](Self::algorithm) returns. Any incorrect values
/// will likely result in invalid tokens.
fn sign(&self, data: &[u8]) -> Result<Signature, error::Format>;
}

@wbourne0 wbourne0 Aug 2, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I don't super like this API, but it should do fine. The other option would be to have sign (or the Signer trait itself) take an algorithm type as an argument, where that type must impl Algorithm or similar.

Also, this may be better named as try_sign to follow the convention used in the ed25519_dalek and ecdsa crates.

Could also add an associated Error type, although then we'd have to pass it back.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Notably we want this separate from a potential later PrivateKey trait, as root keys don't actually need to provide public keys. At most they may optionally have an ID.

Comment on lines +573 to +574
match (block_keypair.algorithm(), next_keypair.algorithm()) {
(Algorithm::Ed25519, SchemaAlgorithm::Ed25519) => {}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Kinda gross here (the SchemaAlgorithm) but I think it's a little neater than relying on the underlying enum structure.

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.

1 participant