Skip to content

feat(feeds): add dormant catalog signing foundation#3005

Open
giodl73-repo wants to merge 9 commits into
openclaw:mainfrom
giodl73-repo:user/giodl/clawhub-signed-openclaw-feed
Open

feat(feeds): add dormant catalog signing foundation#3005
giodl73-repo wants to merge 9 commits into
openclaw:mainfrom
giodl73-repo:user/giodl/clawhub-signed-openclaw-feed

Conversation

@giodl73-repo

@giodl73-repo giodl73-repo commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add an optional DSSE/Ed25519 representation for the stored clawhub-official catalog publication
  • preserve the existing unsigned JSON representation as the default on /api/v1/feeds/plugins
  • sign the exact immutable stored payload bytes and expose representation-specific validators
  • provide a tested prepare/activate rotation script and operator runbook

Merge and activation contract

Merging this PR does not enable signing and does not require production keys.

The route selects DSSE only when a client explicitly sends Accept: application/vnd.dsse+json. Without that opt-in, the existing unsigned response remains available even when CLAWHUB_FEED_SIGNING_CONFIG is missing or malformed. An opted-in signed request fails closed with 503 no-store until a valid signer is installed.

This is the dormant signing foundation for the large-feed stack. Production activation is a later operator action after the matching OpenClaw trust anchor is released.

Review order

  1. This PR — signing foundation and activation boundary
  2. feat(feeds): add catalog distribution state #3149 — durable revision/change history
  3. feat(feeds): serve signed catalog queries and changes #3160 — signed paged query and delta transport
  4. feat(feeds): publish sharded catalog snapshots #3163 — sharded full snapshots
  5. feat(feeds): consume signed sharded catalogs openclaw#110250 — verified sharded-feed consumer

OpenClaw trust-anchor work in openclaw/openclaw#101981 can be reviewed and landed in parallel, but must ship before production signing is activated.

Signing configuration

ClawHub owns one atomic Convex secret:

  • CLAWHUB_FEED_SIGNING_CONFIG: strict JSON containing exactly keyId and PKCS#8 Ed25519 privateKey

OpenClaw receives only the matching public PEM and key id. There is intentionally no feed-adjacent public-key bootstrap endpoint. The complete provisioning, activation, rotation, and emergency-revocation runbook is in specs/hosted-catalog-feed.md.

Cache behavior

The signed representation uses its envelope ETag as the conditional validator and deliberately omits Last-Modified; signer rotation changes envelope bytes without changing the stored publication timestamp. The unsigned representation retains its existing validators. Responses include Vary: Accept.

Validation

  • bun x vitest run convex/httpApiV1.catalogFeedSigning.test.ts scripts/provision-catalog-feed-signing-key.test.ts — 25 tests passed
  • regression coverage proves missing or malformed signer config cannot break ordinary unsigned requests
  • exact stored bytes and DSSE Ed25519 signatures verified with generated key pairs
  • matching ETag returns 304; signed responses omit Last-Modified
  • git diff --check origin/main...HEAD
  • direct codex review --uncommitted — no actionable findings

bun run ci:static now clears the dependency audit after upstream #3234; it currently stops on formatting errors in two files already present on main (.agents/skills/autoreview/CLAUDE.md and CLAUDE.md). Production key provisioning and public-endpoint proof are intentionally deferred to activation.

@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Someone is attempting to deploy a commit to the OpenClaw Foundation Team on Vercel.

A member of the Team first needs to authorize it.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. labels Jul 8, 2026
@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 22, 2026, 1:33 AM ET / 05:33 UTC.

Summary
The branch signs stored catalogFeedPublications bytes into a DSSE Ed25519 envelope, routes /api/v1/feeds/plugins through that handler, adds signing tests, and documents key provisioning and rotation.

Reproducibility: not applicable. as a feature PR. Source and the supplied diff do establish the compatibility concern: the existing canonical handler is replaced with a DSSE-only handler that can return 503 before serving the stored feed.

Review metrics: 3 noteworthy metrics.

  • Changed surface: 5 files; 523 added, 35 removed. The change is focused, but it crosses the public HTTP route, signing implementation, tests, and the hosted-feed operational contract.
  • Canonical route changes: 1 existing GET handler replaced. A single handler substitution changes the representation and availability behavior for all callers of the established feed URL.
  • New signing prerequisite: 1 atomic deployment secret. The canonical endpoint becomes unavailable until the signing configuration is correctly provisioned in each serving deployment.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦪 silver shellfish
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Obtain a maintainer decision on preserving versus replacing the existing public representation.
  • [P1] Post redacted real endpoint evidence that verifies the DSSE signature and shows missing-config recovery behavior.
  • [P1] Add compatibility coverage for the retained existing route and the selected signed representation.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR describes generated-key unit/source-harness verification, but it explicitly leaves production secret provisioning and public endpoint behavior unproven; add redacted live endpoint output showing a verified DSSE response and missing-config behavior. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Replacing the established JSON feed at the same URL can break existing consumers that do not negotiate or parse application/vnd.dsse+json.
  • [P1] A missing or invalid production signing secret turns the canonical route into 503 no-store, creating an availability regression during rollout or recovery.
  • [P1] The public-key, key-id, rotation, and OpenClaw consumer deployment must be coordinated; signing changes the client trust boundary even though the private key remains in Convex secret storage.

Maintainer options:

  1. Stage a compatibility-preserving signed response (recommended)
    Retain the existing feed media type and payload for existing callers, then expose DSSE through an approved negotiated or versioned path with tests for both paths.
  2. Accept a deliberate canonical-route replacement
    Approve the DSSE-only route only after maintainers document the OpenClaw upgrade, public-key distribution, rotation, and missing-secret recovery plan.
  3. Pause the producer change
    Keep the branch open without merging until the dependent OpenClaw consumer and operational signing rollout are ready for coordinated review.

Next step before merge

  • [P1] A maintainer must choose the stable public-route and trust-rollout contract before a mechanical repair can safely proceed; the contributor must also supply real endpoint proof.

Maintainer decision needed

  • Question: Should /api/v1/feeds/plugins immediately replace its established unsigned JSON representation with DSSE, or should ClawHub retain that representation while introducing an explicitly negotiated or versioned signed response until the OpenClaw trust rollout lands?
  • Rationale: This choice defines a public client compatibility and trust boundary; the patch can mechanically preserve the existing route, but maintainers must choose the permanent rollout contract and deployment order.
  • Likely owner: vincentkoc — They own the merged hosted-feed contract whose public representation and rollout boundary this PR changes.
  • Options:
    • Stage a compatible DSSE rollout (recommended): Keep the current JSON response available and add a negotiated or versioned DSSE representation with focused compatibility and production-path proof.
    • Approve an immediate replacement: Accept the DSSE-only response and required signing configuration on the canonical route, with explicit ownership of breaking old clients and rollout operations.
    • Pause until the consumer rollout is ready: Defer producer changes until the public key, OpenClaw consumer, and production provisioning sequence can land as one reviewed rollout.

Security
Needs attention: The implementation keeps private signing material in Convex configuration, but replacing the canonical catalog route creates a new client-trust boundary without a demonstrated coordinated key and consumer rollout.

Review findings

  • [P1] Preserve the existing feed during the signed rollout — convex/http.ts:168
Review details

Best possible solution:

Preserve the existing response as the default until maintainers approve a versioned or content-negotiated DSSE rollout and the matching OpenClaw consumer/trust profile is merged and deployed; then prove both the compatibility path and the production signed path with redacted endpoint evidence.

Do we have a high-confidence way to reproduce the issue?

Not applicable as a feature PR. Source and the supplied diff do establish the compatibility concern: the existing canonical handler is replaced with a DSSE-only handler that can return 503 before serving the stored feed.

Is this the best way to solve the issue?

No. Signing the stored payload is a sound implementation direction, but an unconditional replacement of the existing public representation is not the narrowest safe rollout while the corresponding OpenClaw consumer and trust-profile work remain open.

Full review comments:

  • [P1] Preserve the existing feed during the signed rollout — convex/http.ts:168
    The handler replacement changes every existing ApiRoutes.catalogFeed response from the established stored JSON representation to DSSE and makes it fail with 503 until the new secret is provisioned. Preserve the old representation or add an explicit negotiated/versioned DSSE path until the OpenClaw consumer and trust-profile rollout is actually available.
    Confidence: 0.92

Overall correctness: patch is incorrect
Overall confidence: 0.9

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against a9775fc39b10.

Label changes

Label justifications:

  • P2: This is a bounded public API and trust-rollout feature with meaningful compatibility and operational impact, not an active user-facing outage.
  • merge-risk: 🚨 compatibility: The patch replaces an existing public feed response at the same route and media type boundary rather than preserving an upgrade path.
  • merge-risk: 🚨 security-boundary: DSSE signing establishes what OpenClaw clients trust and depends on coordinated key-id, public-key, and rotation behavior.
  • merge-risk: 🚨 availability: Invalid or absent signing configuration makes the canonical feed route return 503 no-store before reading the stored publication.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR describes generated-key unit/source-harness verification, but it explicitly leaves production secret provisioning and public endpoint behavior unproven; add redacted live endpoint output showing a verified DSSE response and missing-config behavior. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

Security concerns:

  • [medium] Coordinate the public trust-root rollout — convex/http.ts:168
    A DSSE-only response at the existing catalog URL requires the matching OpenClaw public key, key id, parser, rotation behavior, and recovery procedure to be deployed coherently; otherwise clients either cannot validate the feed or lose service when the secret is absent.
    Confidence: 0.87

What I checked:

  • Current main does not contain this feature: The current-main HTTP router does not import or register signedCatalogFeedV1Http, so the proposed signed catalog-feed behavior is not already implemented. (convex/http.ts, a9775fc39b10)
  • The patch changes the canonical public route: The PR replaces the existing catalog-feed handler at ApiRoutes.catalogFeed with the DSSE-only signing handler rather than adding a negotiated or versioned representation. (convex/http.ts:168, b20bda13bba4)
  • The new handler is deliberately unavailable without deployment configuration: The PR body and signing handler design require one atomic CLAWHUB_FEED_SIGNING_CONFIG; absent or invalid configuration returns 503 no-store before querying publications. (convex/httpApiV1/catalogFeedSigning.ts:40, b20bda13bba4)
  • Prior reviewer fixes were addressed, but they were not product approval: Patrick-Erichsen's review requested atomic key-pair activation and safe validator handling; the current branch implements the atomic config and omits Last-Modified for the signed representation, but no maintainer decision in the supplied discussion approves replacing the established public response contract. (specs/hosted-catalog-feed.md:121, b20bda13bba4)
  • Existing hosted-feed contract provenance: Merged hosted-feed work introduced the stored immutable publication, integrity metadata, and public route as an unsigned feed, explicitly leaving signing and trust-root deployment as a separate decision. (convex/httpApiV1/catalogFeedV1.ts, 72c5cdd86491)
  • Related consumer is not a landed dependency: The PR identifies OpenClaw standard-envelope consumption as tracked separately; the supplied related-item context still shows the dependent work as open, so compatibility cannot be assumed from this producer-only branch. (b20bda13bba4)

Likely related people:

  • vincentkoc: Authored and merged the hosted catalog-feed producer that established immutable stored publications, artifact integrity, and the initial unsigned public endpoint. (role: hosted-feed contract feature owner; confidence: high; commits: 422c287, d0c4a58, d566ee6; files: convex/catalogFeed.ts, convex/httpApiV1/catalogFeedV1.ts, packages/schema/src/catalogFeed.ts)
  • Patrick-Erichsen: Provided the two concrete review requirements on this PR's signing rotation and conditional-response behavior and has recent history around the public proxy and preview route setup. (role: recent public-route reviewer and contributor; confidence: high; commits: dfca6f5d9d1c; files: convex/http.ts, server/convexProxy.ts, specs/hosted-catalog-feed.md)
  • jesse-merhi: Prior feature-history review traced the stored-publication implementation and hosted-feed specification text to this contributor's current-main commit. (role: current implementation provenance contributor; confidence: medium; commits: 3ce0ce4ad6b5; files: convex/catalogFeed.ts, convex/httpApiV1/catalogFeedV1.ts, specs/hosted-catalog-feed.md)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (4 earlier review cycles)
  • reviewed 2026-07-08T03:50:05.888Z sha 685c963c9c9a6a9d8145139f14ef9b5e94e531a7 :: needs real behavior proof before merge. :: [P1] Register the signer in a Node-runtime action | [P1] Sign stored feed bytes instead of live digest rows | [P1] Do not sign mutable plugin install coordinates
  • reviewed 2026-07-08T16:12:08.769Z sha 5bc6456e032793d5ddd4817924a024f386925fdf :: needs real behavior proof before merge. :: [P1] Sign the stored feed publication bytes | [P1] Bind signed entries to exact artifacts
  • reviewed 2026-07-08T19:02:32.005Z sha fd1d3732ac99799e78ae1aef3d87a10160c25763 :: needs real behavior proof before merge. :: [P1] Sign the stored feed publication bytes | [P1] Include artifact integrity in signed entries | [P1] Serve the signer from the public feed route
  • reviewed 2026-07-09T20:25:39.239Z sha fd1d3732ac99799e78ae1aef3d87a10160c25763 :: needs real behavior proof before merge. :: [P1] Sign the stored feed publication bytes | [P1] Include artifact integrity in signed entries | [P1] Serve the signer from the public feed route

@giodl73-repo
giodl73-repo force-pushed the user/giodl/clawhub-signed-openclaw-feed branch 3 times, most recently from fd1d373 to ba9c4c8 Compare July 15, 2026 14:44
@giodl73-repo giodl73-repo changed the title feat: sign OpenClaw plugin feed feat: sign stored OpenClaw catalog publications Jul 15, 2026
@giodl73-repo
giodl73-repo force-pushed the user/giodl/clawhub-signed-openclaw-feed branch from ba9c4c8 to e566e3e Compare July 15, 2026 15:07

@Patrick-Erichsen Patrick-Erichsen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This revision now signs the canonical stored clawhub-official publication bytes, preserves the payload digest/sequence/expiry fields, and matches the merged OpenClaw-specific DSSE/Ed25519 envelope contract. That is the right behavior and trust boundary.

LOC: +462/-33 (5 files)

Two rotation/cache findings remain below.

Best-fix verdict: acceptable architecture, but not merge-ready until signer transitions cannot publish a mixed key pair and all validators describe the selected signed representation.

Alternatives considered: storing the signed envelope alongside each publication would make representation revisions naturally immutable, but it couples publication to signing-secret availability and expands the storage contract. The narrower fix is an atomic signer configuration/activation revision plus rotation-aware validators.

Code/contracts read: ClawHub publication/store/HTTP/proxy paths and tests; current OpenClaw envelope verifier, loader, snapshot rollback path, and 1 MiB response bound; Convex's upstream Ed25519 WebCrypto implementation; DSSE protocol/envelope docs; RFC 0009 corrected trust/feed drafts.

CI: exact-head pr-gates, static, unit, types-build, packages, and e2e-http are green. The only failing status is external Vercel team authorization.

Expected deployment blockers, separate from these findings: the production key and live endpoint proof do not exist yet; OpenClaw's default ClawHub trust/feed-id PR and rotation follow-up remain open; the corrected RFC contract is also still open. Current OpenClaw main also does not yet enforce the signed payload's expiresAt, so end-to-end production trust is not complete even after this producer lands.

Comment thread specs/hosted-catalog-feed.md Outdated
Comment thread convex/httpApiV1/catalogFeedSigning.ts Outdated
@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@Patrick-Erichsen Re-review when convenient: your two requested producer fixes are both present at exact head c62a506. Signer id/key activation is atomic, and Last-Modified now varies with the selected signed representation. The substantive static/unit/types/packages/e2e checks are green; the remaining failures are the unrelated moderation-star Playwright lane and Vercel authorization.

@clawsweeper

clawsweeper Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: feat: sign stored OpenClaw catalog publications This is item 1/1 in the current shard. Shard 19/22.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@giodl73-repo giodl73-repo self-assigned this Jul 24, 2026
@giodl73-repo
giodl73-repo force-pushed the user/giodl/clawhub-signed-openclaw-feed branch from 8469465 to 1527bb4 Compare July 24, 2026 02:03
@giodl73-repo giodl73-repo changed the title feat: sign stored OpenClaw catalog publications feat(feeds): add dormant catalog signing foundation Jul 24, 2026
@giodl73-repo
giodl73-repo force-pushed the user/giodl/clawhub-signed-openclaw-feed branch from 1527bb4 to 15b8dfb Compare July 26, 2026 04:01
@giodl73-repo

Copy link
Copy Markdown
Contributor Author

@Patrick-Erichsen The current restacked head \15b8dfba\ addresses both requested changes: signer key/id activation is atomic, and signed representation validators no longer reuse a stale Last-Modified value. It also keeps signing dormant behind explicit activation, preserving the unsigned canonical response until rollout. Substantive CI is green; only the external Vercel authorization status remains. Re-review when convenient.\n\n@clawsweeper re-review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants