# JWT Signing endpoint for ACA-Py ### Author - Daniel Bluhm <daniel@indicio.tech> - Adam Burdett <adam@indicio.tech> ### Introduction Add an endpoint for signing arbitrary payloads as JWTs. ### Context - signing a governance payload (JSON) as a JWT - signing a governance JSON data and storing it in a file with possible configuration to find public keys for decryption - public DID keys if we can? Example of the signed governance JWT ``` eyJhbGciOiJFZERTQSJ9.eyJhdXRob3IiOiJkaWQ6ZXhhbXBsZTp2aWFjaGVzbGF2bmF6YXJlbmtvIiwiZGVzY3JpcHRpb24iOiJUaGlzIGRvY3VtZW50IGRlc2NyaWJlcyBlbWFpbCBhbmQgZW1wbG95bWVudCBnb3Zlcm5hbmNlIGluIGEgbWFjaGluZSByZWFkYWJsZSB3YXkiLCJkb2NzX3VyaSI6Imh0dHBzOi8vdXJsLWZvci1kb2NzLi4uIiwiZm9ybWF0IjoiMS4wIiwiaWQiOiJjNjQ4NDZkMS1jZjYwLTRhYzUtODM1ZS1jYmQyNTU2OWYyZmEiLCJsYXN0X3VwZGF0ZWQiOjE2ODM4MzA2OTQsIm5hbWUiOiJQcm92ZW4gRWNvc3lzdGVtIEdvdmVybmFuY2UiLCJ2ZXJzaW9uIjoiMC4xIiwiQGNvbnRleHQiOlsiaHR0cHM6Ly9naXRodWIuY29tL2h5cGVybGVkZ2VyL2FyaWVzLXJmY3MvYmxvYi9tYWluL2NvbmNlcHRzLzA0MzAtbWFjaGluZS1yZWFkYWJsZS1nb3Zlcm5hbmNlLWZyYW1ld29ya3MvY29udGV4dC5qc29ubGQiXSwic2NoZW1hcyI6W3siaWQiOiJCWHR6WVB5UGRpVktHQWprcXRQZXhzOjI6RW1haWw6MS4wIiwibmFtZSI6IkVtYWlsIENyZWRlbnRpYWwifSx7ImlkIjoiUUhxdGp5d3hmUDN5WXNGclJIRkxRbToyOkVtcGxveW1lbnQ6MS4wIiwibmFtZSI6IkVtcGxveW1lbnQgQ3JlZGVudGlhbCJ9XSwicGFydGljaXBhbnRzIjp7ImlkIjoiMWU3NjIzMjQtNmE0NS00ZjZhLWIxMjQtZWNiMjExOTBmZTA5IiwiYXV0aG9yIjoiZGlkOmV4YW1wbGU6dmlhY2hlc2xhdm5hemFyZW5rbyIsImNyZWF0ZWQiOjE2ODM4MzA2OTQsInZlcnNpb24iOiIyLjAiLCJ0b3BpYyI6InVyaTp0by1tdWx0aS10b3BpYy1zY2hlbWEiLCJlbnRyaWVzIjp7Imh0dHBzOi8vZXhhbXBsZS5jb20vcm9sZXMuc2NoZW1hLmpzb24iOnsiOThuVnVDbmdqN1JlRVNQckg3c2twRiI6eyJyb2xlcyI6WyJyb2xlXzEiLCJyb2xlXzIiXX0sIldkdmdKUDdmd2Z2Q3JLdXBSUmhERXUiOnsicm9sZXMiOlsicm9sZV8zIiwicm9sZV80Il19fSwiaHR0cHM6Ly9leGFtcGxlLmNvbS9kZXNjcmlwdGlvbi5zY2hlbWEuanNvbiI6eyI5OG5WdUNuZ2o3UmVFU1BySDdza3BGIjp7ImVtYWlsIjoiY3JlZGVudGlhbF9tYW5hZ2VyQGlzc3Vpbmdnb3Zlcm5tZW50c2l0ZS5vcmciLCJuYW1lIjoiUHJvdmVuIGlzc3VlciBhZ2VuY3kiLCJwaG9uZSI6IjEyMy00NTYtNjc4MCIsIndlYnNpdGUiOiJpc3N1aW5nZ292ZXJubWVudHNpdGUub3JnIn0sIldkdmdKUDdmd2Z2Q3JLdXBSUmhERXUiOnsiZW1haWwiOiJjcmVkZW50aWFsX21hbmFnZXJAdmVyaWZ5aW5nbGFic2l0ZS5jb20iLCJuYW1lIjoiUHJvdmVuIHZlcmlmaWVyIGFnZW5jeSIsInBob25lIjoiMDk4LTc2NS00MzIxIiwid2Vic2l0ZSI6InZlcmlmeWluZ2xhYnNpdGUuY29tIn19fX0sInJvbGVzIjp7InJvbGVfMSI6eyJpc3N1ZSI6WyJRSHF0anl3eGZQM3lZc0ZyUkhGTFFtOjI6RW1wbG95bWVudDoxLjAiXX0sInJvbGVfMiI6eyJpc3N1ZSI6WyJCWHR6WVB5UGRpVktHQWprcXRQZXhzOjI6RW1haWw6MS4wIl19LCJyb2xlXzMiOnsidmVyaWZ5IjpbIlFIcXRqeXd4ZlAzeVlzRnJSSEZMUW06MjpFbXBsb3ltZW50OjEuMCJdfSwicm9sZV80Ijp7InZlcmlmeSI6WyJCWHR6WVB5UGRpVktHQWprcXRQZXhzOjI6RW1haWw6MS4wIl19fX0.ZJU-e38x3rf_jMCsMvpz60WBLiluTOZXEcRwgpRs9GNWZYO-BdzLFYNxKG5Z5yBvzoUx50_zjTsLgeIGvJyXAg ``` ### User stories *Walk through a high level example flow to illustrate how users interact with this system and/or how data flow through it.* ### Goals - describe the user-driven impact of your project - specify how to measure success using metrics ### Non-Goals - Define here what's out of scope ### Proposed Solution (Technical Architecture) `POST wallet/jwt/sign` ```json { "headers": { ... }, "payload": { ... }, "did": "did:example:123", "verification_method": "did:example:123#keys-1" } ``` - Create a DID URL for the key that signed the payload, insert as `kid` into the headers Example output in expanded form: ``` {"alg": "EdDSA", "typ": "JWT", "kid": "did:example:123#keys-1"} . { "author": "did:example:viacheslavnazarenko", "description": "This document describes email and employment governance in a machine readable way", "docs_uri": "https://url-for-docs...", "format": "1.0", "id": "c64846d1-cf60-4ac5-835e-cbd25569f2fa", "last_updated": 1683830694, "name": "Proven Ecosystem Governance", ... } . <Signature over "{headers}.{payload}"> ``` The compact form is: ``` <headers, base64 url safe, unpadded>.<payload, base64 url safe, unpadded>.<signature> ``` ```python did_info = await wallet.get_local_did(did) headers = { ... } payload = { ... } ... signature = await wallet.sign_message( f"{headers}.{payload}".encode(), did_info.verkey ) sig = bytes_to_b64(signature, pad=False) # messaging.util return f"{headers}.{payload}.sig" ``` `POST wallet/jwt/verify` ```json { "jwt": { ... } } ``` - Resolve `kid` from headers using the DID Resolver - Use resolved key to verify the jwt #### Alternative Solutions *Other solutions that you have consider during your evaluation. Pros and cons, etc...* ### Open Questions ### Glossary