keria icon indicating copy to clipboard operation
keria copied to clipboard

feat: ESSR protected client APIs

Open iFergal opened this issue 11 months ago • 3 comments

This PR adds an alternative mechanism to authenticate with the KERIA API from a Signify client, and leaves the current RFC-9421 signed headers in place too. Beyond confidentiality, it also resolves other issues from before such as unsigned query params and bodies. (#287)

The unsigned HTTP request from the client is converted to a HTTP bytestream and embedded in an ESSR payload. This payload becomes the body of a wrapper HTTP request for the "/" path - so tunneled via ESSR. The wrapper could be handled by pure TCP but for now this works quite nicely in the Falcon middlewares with minimal changes.

Because nothing else uses "/" as the path, the authentication type is determined based on the path. A cleaner approach in a TCP world would just to have a CESR based command signed and optionally encrypted following ESSR, rather than complicating things with managing headers, or embedding HTTP requests within each other.

I have written the corresponding code in Signify and all integration tests pass.


Flow for generating request from Signify:

  1. Create HTTP request - e.g. POST /identifiers <body>
  2. Add Signify-Resource header (Encrypt Sender)
  3. Serialize HTTP request as a HTTP string
  4. crypto_box_seal(http_request_string, public_key_of_keria_agent)
  5. Create a new HTTP request to POST / where the body of the request is the sealed box bytes (application/octet-stream)
  6. Add Signify-Resource, Signify-Timestamp and Signify-Receiver headers (receiver is Sign Receiver)
  7. Sign the request and add as a header

Note: Like the keripy ESSR parser, the commitment to unsigned HTTP request is done by taking a digest:

payload = dict(
    src=<sender>,
    dest=<receiver>,
    d=coring.Diger(ser=cipher, code=MtrDex.Blake3_256).qb64,
    dt=dt,
)

A signature is created over this dict. I'm re-using the signature style of the signed headers.

ESSR drawio

iFergal avatar Jan 15 '25 23:01 iFergal

https://github.com/WebOfTrust/signify-ts/pull/304 created on Signify side

iFergal avatar Jan 17 '25 12:01 iFergal

Codecov Report

Attention: Patch coverage is 98.39572% with 6 lines in your changes missing coverage. Please review.

Project coverage is 93.99%. Comparing base (676d7e8) to head (1d83e66). Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/keria/core/authing.py 97.51% 4 Missing :warning:
src/keria/app/aiding.py 66.66% 1 Missing :warning:
tests/core/test_authing.py 99.51% 1 Missing :warning:
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #351      +/-   ##
==========================================
+ Coverage   93.80%   93.99%   +0.18%     
==========================================
  Files          37       37              
  Lines        8462     8704     +242     
==========================================
+ Hits         7938     8181     +243     
+ Misses        524      523       -1     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Jan 23 '25 00:01 codecov[bot]

Updated PR to allow both signed headers and ESSR. I'm leaving this as draft as I still have the edge case I need to test for in the comment I left on the PR above, and I need to update my Signify PR.

iFergal avatar Jun 18 '25 17:06 iFergal