Signed call from frontend browser to a server via http request

I want a user to make a signed call to my server via a http request. on the server side all i care about doing is verifying that the user’s principal Id who made a call to the server was actually who they say they were

I’m building an application where users make HTTP requests to my server endpoint, and I need to verify that the principal ID included in the request actually belongs to the caller.

Here’s what I’m trying to achieve:

curl example.com/check/user/icon/{principal}
-H "Authorization: {some-signed-key}"

My main questions:

  1. What’s the recommended way to generate a signed key from the user’s principal that I can verify on the server side?
  2. How can I securely verify on the server that the key in the Authorization header matches the principal ID in the URL path?

I’ve seen references to Ed25519 signatures but I’m unsure about the best implementation pattern. Any code examples or links to documentation would be really helpful. I have no idea if this is the right route to take so please correct me and put me on a different path if so.

Thanks in advance!

Hi @jake-beardo

  1. What’s the recommended way to generate a signed key from the user’s principal that I can verify on the server side?

I would suggest using self-authenticating principals. That way, there is a binding by construction from the public key to the principal. However, the construction is in a different order: generate key pair → derive principal.

As a second step, I would include some header, as you suggested, but containing a signature: -H Request-Sig: {signature}, {pubkey}. The public key is also included in the header because it cannot be reconstructed from the principal.

Finally, sign the request using the private key that belongs to the public key which was used to derive the principal. Make sure, to include all relevant parts of the request in the signature:

  • Method
  • URL
  • Headers, except the Request-Sig header
  • Body

On the server side, you can then validate:

  1. the request is correctly signed
  2. the principal is derived from the public key

This scheme works for any asymmetric signature scheme. If you make the requests from the browser I would suggest using ECDSA simply because SubtleCrypto allows to use non-extractable keys.

I hope this helps.