No description
  • Scheme 56.7%
  • Shell 30.5%
  • Makefile 6.2%
  • C 3.6%
  • Python 2.7%
  • Other 0.3%
Find a file
ober 6ef4b8249b
All checks were successful
required-ci / required (push) Successful in 18m10s
Merge pull request #5
2026-09-12 21:21:24 -04:00
.forgejo Use FreeBSD Forgejo CI runner 2026-08-03 14:46:21 -06:00
.jerboa Set up Forgejo CI/CD policy 2026-08-03 12:55:30 -06:00
docs Harden edge runtime and release verification 2026-07-11 17:22:04 -06:00
scripts fix: retain edge replay claims through accepted skew 2026-09-05 13:05:58 -06:00
support Harden edge runtime and release verification 2026-07-11 17:22:04 -06:00
test fix: retain edge replay claims through accepted skew 2026-09-05 13:05:58 -06:00
.gitignore jpkg: complete binary package setup 2026-07-30 15:08:56 -06:00
.gitsafeignore Set up Forgejo CI/CD policy 2026-08-03 12:55:30 -06:00
.jerbuild fix: retain edge replay claims through accepted skew 2026-09-05 13:05:58 -06:00
.jerbuild-test fix: retain edge replay claims through accepted skew 2026-09-05 13:05:58 -06:00
.jpkgignore Add jpkg packaging exclusions 2026-08-01 16:34:32 -06:00
AGENTS.md docs(agents): add checkout hygiene policy (work dirs under ~/work, cleanup when done) 2026-09-12 19:10:48 -06:00
bench-edge.sh Harden edge runtime and release verification 2026-07-11 17:22:04 -06:00
edge-main.ss Harden edge runtime and release verification 2026-07-11 17:22:04 -06:00
edge.ss fix: retain edge replay claims through accepted skew 2026-09-05 13:05:58 -06:00
jpkg.lock jpkg: complete binary package setup 2026-07-30 15:08:56 -06:00
jpkg.policy.sexp jpkg: complete binary package setup 2026-07-30 15:08:56 -06:00
jpkg.sexp Use FreeBSD Forgejo CI runner 2026-08-03 14:46:21 -06:00
LICENSE Switch to MIT license 2026-07-21 13:41:55 -06:00
Makefile fix: retain edge replay claims through accepted skew 2026-09-05 13:05:58 -06:00
README.md Harden edge runtime and release verification 2026-07-11 17:22:04 -06:00
SECURITY.md Harden edge runtime and release verification 2026-07-11 17:22:04 -06:00
test-edge.sh Harden edge runtime and release verification 2026-07-11 17:22:04 -06:00
VERSION fix: retain edge replay claims through accepted skew 2026-09-05 13:05:58 -06:00

jerboa-edge

jerboa-edge is a Jerboa webhook processing daemon. It binds to loopback by default, accepts plain HTTP from a trusted ingress, verifies versioned webhook envelopes with freshness and replay protection, runs event filters and hot handlers in Jerboa restricted execution, persists bounded state and replay claims through jsqlite, and exposes health, metrics, event query, dead-letter, and dashboard endpoints.

This daemon is not its own internet TLS endpoint. Production deployments must put it behind an external mTLS terminator or service mesh and expose the daemon only on a private listener. External ingress is defense in depth: every route except /health also has an application authentication boundary.

Build

JERBUILD=/path/to/jerbuild make build

The static binary is written to ./jerboa-edge. The build uses Jerboa native features crypto,wasm,http; the http feature contains only the bounded HTTP parser/writev shim, while TLS native code is intentionally not linked.

Production runtime target is Linux. The static fiber HTTP server uses Jerboa's Linux epoll-native backend; macOS can build the binary but does not provide the runtime epoll symbols needed to execute it.

Run

EDGE_SECRET='replace-with-webhook-secret' \
EDGE_READ_TOKEN='independent-read-capability' \
EDGE_OPERATOR_TOKEN='independent-operator-capability' \
EDGE_CODE_TOKEN='independent-code-capability' \
EDGE_PORT=8080 \
EDGE_DB_PATH=/var/lib/jerboa-edge/events.db \
./jerboa-edge

All four secrets must contain at least 32 UTF-8 bytes and be distinct. EDGE_DB_PATH is mandatory because the bounded replay window must survive a daemon restart. There is no unsigned mode. A non-loopback EDGE_BIND also requires EDGE_ALLOW_NON_LOOPBACK_BIND=1 so exposure is never accidental.

Webhook clients sign this canonical UTF-8 envelope with HMAC-SHA256 and send the lowercase hex MAC in x-edge-signature:

jerboa-edge-v1\n
POST\n
/hooks/<type>\n
<unix timestamp>\n
<source id>\n
<event id>\n
<nonce>\n
<lowercase SHA-256 of exact body bytes>

The timestamp, source, event ID, and nonce are supplied in x-edge-timestamp, x-edge-source, x-edge-event-id, and x-edge-nonce. The JSON body's string id must equal the signed ID. API callers use Authorization: Bearer <role token>; read, operator, and code-management tokens are intentionally not interchangeable.

Useful endpoints:

  • POST /hooks/:type
  • GET /health
  • GET /metrics
  • GET /api/stats
  • GET /api/events/:id
  • GET /api/dead-letter
  • POST /api/dead-letter/:id/replay
  • GET /dashboard

The daemon enforces body, connection, request-rate, queue, retry, watcher, filter, handler, replay, event, dead-letter, count, and TTL bounds internally. Ingress limits remain an additional outer layer.

Security

Release gates:

JERBUILD=/path/to/jerbuild make verify
JERBUILD=/path/to/jerbuild make release-evidence

Release evidence includes Linux runtime/load status under dist/release-evidence/soak/. On non-Linux hosts this records the runtime and load gates as blocked; production release requires Linux release-host smoke and sustained load evidence. A Linux release host can record sustained load with JEDGE_RUN_RELEASE_SOAK=1 JEDGE_RUN_PRODUCTION_LOAD=1; externally captured runtime/load proof can be attached with JEDGE_TARGET_RUNTIME_PROOF_FILE and JEDGE_TARGET_LOAD_PROOF_FILE.

CI executable bootstrap now fails closed unless a signed Jerboa manifest, pinned digest, and pinned release identity are all present. The checked lock is currently blocked-awaiting-authenticated-upstream-release; publishing and pinning that upstream artifact is a release blocker, not a reason to restore the former unverified download.

The security posture is documented in:

  • SECURITY.md
  • docs/threat-model.md
  • docs/deployment-security.md
  • docs/ffi-boundary.md
  • docs/release-evidence.md

License

Apache-2.0, matching the Jerboa and Chez Scheme license posture. See LICENSE.