feat(protect): per-site Pulse rules client (fetch rules by site UUID)#62
Merged
Conversation
Adds PulseRuleClient (GET <base>/rules/<uuid>, fail-open + last-known-good cache) as a third rule source in createProtection; precedence siteUuid -> token -> bundled. The protect installer bakes the site UUID from .patchstackrc.json into the scaffolded guard so the runtime fetches per-site rules with no user config. Bundled rules.json stays as the offline fallback.
|
Well-structured per-site rules client with comprehensive test coverage. 🎯 Quality: 100% Elite · 📦 Size: Large — consider splitting if possible 📈 This month: Your 59th PR — above team average · Averaging Excellent |
patchstackdave
requested changes
Jul 14, 2026
patchstackdave
left a comment
Contributor
There was a problem hiding this comment.
This might need changes per my PR comment in saas?
… expiry; guard bakeSiteUuid on UUID format - bakeSiteUuid now validates UUID format before baking, falling through to the inert placeholder for missing/malformed values (avoids junk in the TS literal) - runtime-pulse: last-known-good disk cache, siteUuid>token precedence, whitelist suppression over the Pulse path - pulse-client: cache expiry past TTL + clearCache() refetch - protect-install: realistic UUID fixture + malformed-value inert case
…connect # Conflicts: # src/protect/install.ts # src/protect/templates/guard.ts
Contributor
Author
|
/review |
mariojgt
approved these changes
Jul 14, 2026
patchstackdave
approved these changes
Jul 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a per-site rules source to the runtime guard so a Pulse app fetches the exact WAF rules for its vulnerable npm packages using only its site UUID — no WAF token, no user config.
Changes
PulseRuleClient(src/protect/engine/pulse-client.js) —GET <base>/rules/<uuid>, fail-open, last-known-good disk cache. Sibling ofPatchstackRuleClient.createProtection— newsiteUuidrule source inresolveRules; precedence siteUuid → token → bundledrules. Cached + fail-open like the token path.protectinstaller — bakes the site UUID from.patchstackrc.jsoninto the scaffolded guard (replaces a sentinel) so the runtime callspulse/rules/{uuid}with zero user config; falls back toPATCHSTACK_SITE_UUIDenv or the bundled rule.siteUuid?+pulseRulesUrl?onCreateProtectionOptions.Tests
Rebased onto
main(post #57 Tier-3 + #58tests/protect/restructure). New tests undertests/protect/:pulse-client.test.ts— fetch / parse / cache / fail-openruntime-pulse.test.ts—createProtectionfetches by UUID + falls back to bundled on fetch failuredave-example-rule.test.ts— engine enforces a real hub-format rule (isset/contains) inline + via the fetch-by-UUID pathprotect-install.test.ts— installer bakes the UUIDFull suite green: 386 tests, 26 files.
Related
GET /monitor/pulse/rules/{uuid}ships in patchstack/saas#999.@latestfetches per-site rules by UUID; bundledrules.jsonstays the offline fallback.