Skip to content

Add $hmac JSONata function - #525

Merged
aeberhart merged 3 commits into
masterfrom
feature/hmac-function
Nov 6, 2026
Merged

aeberhart merged 3 commits into
masterfrom
feature/hmac-function

Conversation

@uw4

@uw4 uw4 commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a generic $hmac(keyId, message, algorithm?, encoding?) JSONata function. It signs a message with the secret of a Credentials function and never returns the secret.

  • Access: the roles of the Credentials record decide who may sign. No roles means admin only. Apps can let normal users sign through an Invoke function with runas, so those users never get the key role themselves.
  • Secret: read like any Credentials password, from dashjoin.function.<ID>.password (e.g. an environment variable) or from the stored encrypted value.
  • Options: HmacSHA256 (default), HmacSHA384, HmacSHA512; output base64 (default), base64url without padding, or hex.
  • Use case: short-lived signed CDN URLs checked by Cloudflare is_timed_hmac_valid_v0, built entirely in app JSONata with no app-specific Java.

Changes

  • Hmac.java, registered in META-INF/services/org.dashjoin.function.Function
  • HmacTest.java: RFC example values, role checks, only-Credentials check, invalid arguments
  • Docs: appendix-jsonata.md, developer-reference.md

Testing

  • HmacTest passes (4 tests).
  • Checked end to end on a local server as admin with a test secret: an Invoke runas function produced a URL whose MAC verifies the way Cloudflare checks it.
  • Not tried live: a non-admin calling $hmac directly. The unit test covers that case.

🤖 Generated with Claude Code

$hmac(keyId, message, algorithm?, encoding?) signs a message with the
secret of a Credentials function, without ever returning the secret.
The Credentials roles decide who may sign (no roles = admin only), so
apps can expose signing to users through an Invoke function with runas.
Supports HmacSHA256/384/512 and base64, base64url or hex output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@uw4
uw4 requested a review from aeberhart November 6, 2026 14:59
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"diff" : "diff --git a/dashjoin-demo.db b/dashjoin-demo.db\nindex 6fdb4ce..d29b8f1 100644\n--- a/dashjoin-demo.db\n+++ b/dashjoin-demo.db\nBinary files differ\n"
} ]
```
### hmac

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this must go in /dashjoin-base/dashjoin-docs/llms/jsonata.json
also, we need to add this to Action.ts to make the function available on the client (proxied to backend if client jsonata engine)

The appendix and llms.txt are generated by LLMs.java. Regenerating also
picks up gitCheckout and use, which were in jsonata.json but not yet in
the generated files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aeberhart
aeberhart merged commit 16b9216 into master Nov 6, 2026
1 check passed
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