Skip to content

feat: self-contained identity webhook + collector price oracle and metering fixes#36

Merged
eliteprox merged 19 commits into
mainfrom
feat/identity-webhook
Jun 30, 2026
Merged

feat: self-contained identity webhook + collector price oracle and metering fixes#36
eliteprox merged 19 commits into
mainfrom
feat/identity-webhook

Conversation

@eliteprox

@eliteprox eliteprox commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Four related changes to the clearinghouse stack:

  1. Identity webhook — new in-compose Node.js service implementing go-livepeer's /authorize wire protocol in-repo, with API-key and OIDC (JWT/JWKS via jose) verifiers. No external SDK dependency.
  2. Live ETH/USD price oracle in the OpenMeter collector — replaces static ETH_USD_PRICE with a fetched-and-cached oracle price.
  3. Collector CloudEvents fixes — compound subject for Konnect customer attribution, billable_usd_micros passthrough, and a Benthos pipeline bugfix that silently dropped all events.
  4. Unified configuration — single root .env (from .env.example) for all Compose services; per-service .env.example files removed.

1. Identity webhook

  • identity-webhook/ — Node service at repo root. Implements the go-livepeer remote-signer webhook protocol (protocol.mjs) and pluggable end-user verifiers (verifiers.mjs): API keys (sk_* from DEMO_API_KEY / DEMO_API_KEYS) and optional OIDC JWTs (JWKS via jose). IDENTITY_AUTH_MODE (api_key | oidc) selects exactly one verifier — no fallback. Stateless — no local identity DB. 32 unit tests.
  • Compose wiringremote-signer depends_on kafka (healthcheck-gated) only; identity-webhook starts independently. This supports signer-only alive checks (docker compose up kafka remote-signer with REMOTE_SIGNER_WEBHOOK_URL unset). When the webhook is used, set REMOTE_SIGNER_WEBHOOK_URL=http://identity-webhook:8090/authorize (default in .env.example).
  • End users present Authorization: Bearer sk_… (API key mode) or Authorization: Bearer <jwt> (OIDC mode) to the signer; the webhook resolves credentials to auth_id = "{client_id}:{usage_subject}".
  • Signing port published as 127.0.0.1:8081 by default; use a Compose override to bind 0.0.0.0 only when the webhook is configured.

Note: leave REMOTE_SIGNER_WEBHOOK_URL empty for local alive checks only (inherited from main). Production deployments must set REMOTE_SIGNER_WEBHOOK_URL and WEBHOOK_SECRET.

2. ETH/USD price oracle (collector)

  • PRICE_ORACLE_URL (default Coinbase spot) and PRICE_ORACLE_REFRESH (default 5m) replace static ETH_USD_PRICE.
  • Price is warmed at startup via a Benthos sequence input that blocks Kafka consumption until the cache is populated, then refreshed on the configured interval. Refresh errors keep the last cached value; runtime events read from cache only (cache miss throws).
  • Oracle JSON accepted in three shapes: {"price":…}, {"ethereum":{"usd":…}} (CoinGecko), {"data":{"amount":"…"}} (Coinbase).

3. Collector CloudEvents fixes

  • Compound subject: OpenMeter attributes usage by exact subject match; customers are keyed by client_id:usage_subject. The collector now emits subject = auth_id (compound) instead of bare usage_subject, with data.client_id / data.usage_subject for per-tenant/user meter dimensions. Verified against live Konnect.
  • billable_usd_micros: emitted as interim passthrough equal to network_fee_usd_micros so the billable meter validates and accumulates; phase-2 markup rules come later.
  • Bugfix: the eth_usd price branch used root = @, overwriting the entire message body with the metadata map. Downstream mapping then read an empty this.data, parsed an empty auth_id, and silently dropped every create_signed_ticket — so no events reached OpenMeter/Konnect. Dropping root = @ leaves the original event intact.
  • Guard: events missing auth_id are dropped (protects against pre-0.8.11 go-livepeer builds that omit the field).

4. Unified configuration

  • Single .env.example at repo root; all Compose services read from .env via env_file or volume mount.
  • Removed per-service .env.example files (kafka/, remote-signer/, openmeter-collector/, identity-webhook/).

Stack

identity-webhook → remote-signer → Kafka → openmeter-collector → OpenMeter/Konnect

Quick start

cp .env.example .env
$EDITOR .env
# WEBHOOK_SECRET is shared between identity-webhook and remote-signer

docker compose up -d --build kafka identity-webhook remote-signer

Signer-only alive check (no identity webhook):

# In .env: REMOTE_SIGNER_WEBHOOK_URL=
docker compose up -d --build kafka remote-signer

Validate webhook authentication response:

docker compose exec identity-webhook \
  curl -sS -X POST http://localhost:8090/authorize \
    -H "Authorization: Bearer dev-webhook-secret-change-me" \
    -H "Content-Type: application/json" \
    -d '{"headers":{"Authorization":["Bearer sk_demo_local_key"]}}'
# expected: "status":200, "auth_id":"demo-client:demo-user"

Test plan

  • Fresh clone: cp .env.example .envdocker compose up succeeds
  • kafka healthy; identity-webhook healthy (when started); remote-signer Up
  • /authorize curl returns auth_id: demo-client:demo-user
  • remote-signer logs show Using remote signer webhook URL http://identity-webhook:8090/authorize
  • Signer port 127.0.0.1:8081 published; CLI port 4935 not published
  • cd identity-webhook && npm test passes (32 tests)
  • Collector warms ETH/USD price at startup before consuming Kafka
  • Collector emits normalized CloudEvents with compound subject (output_sent > 0, output_error = 0)
  • billable_usd_micros and network_fee_usd_micros meters accumulate on live Konnect

Closes #2
Closes #4

@eliteprox eliteprox changed the title feat(deploy): in-compose Auth0 identity webhook feat(deploy): Add Auth0 identity webhook Jun 17, 2026
@eliteprox
eliteprox force-pushed the feat/deploy-stack-go-bootstrap branch 4 times, most recently from f45f9be to f176e2e Compare June 18, 2026 22:16
@eliteprox eliteprox changed the title feat(deploy): Add Auth0 identity webhook feat(deploy): API-key identity webhook and demo UI Jun 18, 2026
@eliteprox
eliteprox force-pushed the feat/identity-webhook branch 3 times, most recently from 3deb669 to 5b683d8 Compare June 18, 2026 22:33
@eliteprox eliteprox changed the title feat(deploy): API-key identity webhook and demo UI feat(deploy): API-key identity webhook for remote signer Jun 18, 2026
@eliteprox
eliteprox requested a review from rickstaa June 19, 2026 01:01
@eliteprox eliteprox linked an issue Jun 22, 2026 that may be closed by this pull request
@linear-code

linear-code Bot commented Jun 23, 2026

Copy link
Copy Markdown

ENG-115

ENG-116

ENG-114

@eliteprox eliteprox linked an issue Jun 23, 2026 that may be closed by this pull request
@eliteprox
eliteprox changed the base branch from feat/deploy-stack-go-bootstrap to main June 24, 2026 22:02
@eliteprox eliteprox changed the title feat(deploy): API-key identity webhook for remote signer feat(identity-webhook): API-key identity webhook for remote signer Jun 24, 2026
@eliteprox

Copy link
Copy Markdown
Collaborator Author

@rickstaa This PR is now ready for review

@eliteprox

Copy link
Copy Markdown
Collaborator Author

Need to bump to 0.5.0

eliteprox and others added 4 commits June 29, 2026 11:59
- Updated the README to reflect changes in the OpenMeter collector's environment variables, replacing `ETH_USD_PRICE` with `PRICE_ORACLE_URL` and `PRICE_ORACLE_REFRESH`.
- Enhanced the collector's configuration to fetch ETH/USD prices from the specified oracle URL, with improved error handling and caching mechanisms.
- Clarified the parsing of `auth_id` to accommodate new usage semantics, ensuring compatibility with existing systems while normalizing CloudEvents emitted by the collector.
…ation

Updated the collector.yaml file to set the default interval for price refresh to 5 minutes, ensuring proper functionality of the price oracle refresh mechanism.
Adds the Node.js identity webhook for remote signer authentication using
builder-sdk's API-key provider (@pymthouse/builder-sdk@0.5.0), wires the
remote-signer to depend on it via REMOTE_SIGNER_WEBHOOK_URL, and adds the
Docker Compose stack for runtime services.

Squashed from 15 commits on feat/identity-webhook (PR #36). Closes #2, #4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Brings in OpenMeter collector price-oracle config (PRICE_ORACLE_URL/REFRESH)
and auth_id parsing updates for local testing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

# Conflicts:
#	README.md

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 18 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • identity-webhook/package-lock.json: Generated file

Comment thread README.md Outdated
Comment thread openmeter-collector/collector.yaml
Comment thread identity-webhook/verifiers.mjs Outdated
Copilot AI review requested due to automatic review settings June 30, 2026 20:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 18 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • identity-webhook/package-lock.json: Generated file

Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread identity-webhook/verifiers.mjs Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 30, 2026 20:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 18 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • identity-webhook/package-lock.json: Generated file

Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
eliteprox and others added 2 commits June 30, 2026 16:19
- Expanded the identity contract section to clarify the roles of `client_id` and `usage_subject` across three layers: go-livepeer, Clearinghouse, and OpenMeter/Konnect.
- Updated the description of how `auth_id` is parsed and emitted in CloudEvents, including a new example egress event for better understanding.
- Ensured consistency in terminology and provided additional context for the compound `auth_id` format to aid developers in implementation.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 30, 2026 20:22
- Updated the identity webhook to utilize a single verifier based on the new `IDENTITY_AUTH_MODE` environment variable, eliminating the previous fallback mechanism between OIDC and API key verifiers.
- Enhanced the README to clarify the configuration of identity and authentication, including the new `IDENTITY_AUTH_MODE` setting and its implications for verifier selection.
- Simplified the server implementation by removing redundant functions and improving logging for the identity webhook's operational modes.
- Added tests to ensure correct behavior of the new verifier logic, validating both API key and OIDC modes independently.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 18 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • identity-webhook/package-lock.json: Generated file

Comment thread identity-webhook/verifiers.mjs Outdated
Comment thread openmeter-collector/collector.yaml
Comment thread openmeter-collector/collector.yaml Outdated
Comment thread docker-compose.yml
- Renamed `OPENMETER_INGEST_URL` to `OPENMETER_URL` in `.env.example` and updated related documentation to reflect this change.
- Modified `collector.yaml` to use the new `OPENMETER_URL` for event ingestion, ensuring consistency across configurations.
- Enhanced `entrypoint.sh` to validate the `OPENMETER_URL` and append the appropriate events path based on the URL format.
- Updated README to clarify the new configuration for OpenMeter and its integration with the collector.
Copilot AI review requested due to automatic review settings June 30, 2026 20:32
- Eliminated the empty interval field in the price_warm generation configuration within collector.yaml, ensuring cleaner and more accurate configuration.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 4 comments.

Files not reviewed (1)
  • identity-webhook/package-lock.json: Generated file

Comment thread identity-webhook/verifiers.mjs
Comment thread openmeter-collector/collector.yaml Outdated
Comment thread identity-webhook/verifiers.test.mjs Outdated
Comment thread identity-webhook/server.mjs Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 19 changed files in this pull request and generated 2 comments.

Files not reviewed (1)
  • identity-webhook/package-lock.json: Generated file

Comment thread openmeter-collector/collector.yaml Outdated
Comment thread openmeter-collector/collector.yaml
…r handling

- Introduced a maximum payload size limit of 64KB in the identity webhook server to prevent excessive data processing.
- Enhanced the readBody function to reject requests exceeding the size limit with a 413 status code.
- Updated OIDC verification error handling to log warnings instead of exposing error messages, improving security.
- Renamed a test case for clarity regarding OIDC verification behavior when required scopes are missing.
@eliteprox
eliteprox merged commit 12c83d1 into main Jun 30, 2026
@eliteprox
eliteprox deleted the feat/identity-webhook branch June 30, 2026 21:21
eliteprox added a commit that referenced this pull request Jul 1, 2026
Adds the Node.js identity webhook for remote signer authentication using
builder-sdk's API-key provider (@pymthouse/builder-sdk@0.5.0), wires the
remote-signer to depend on it via REMOTE_SIGNER_WEBHOOK_URL, and adds the
Docker Compose stack for runtime services.

Squashed from 15 commits on feat/identity-webhook (PR #36). Closes #2, #4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

Add API-key and custom end-user verifier examples NodeJS auth webhook — scaffold + /authorize route (API-key)

3 participants