shieldcortex 4.35.0 → 4.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
- package/dist/api/routes/memories.js +14 -1
- package/dist/cloud/cli.js +26 -1
- package/dist/defence/firewall/markdown-image-detector.d.ts +15 -0
- package/dist/defence/firewall/markdown-image-detector.js +30 -0
- package/dist/defence/quarantine/review.js +29 -7
- package/dist/defence/tool-response-enforce.d.ts +57 -0
- package/dist/defence/tool-response-enforce.js +107 -0
- package/dist/defence/tool-response-scanner.d.ts +6 -3
- package/dist/defence/tool-response-scanner.js +56 -6
- package/dist/defence/trust/recall-filter.js +6 -2
- package/dist/defence/trust/source-scorer.js +5 -0
- package/dist/defence/types.d.ts +9 -0
- package/dist/memory/consolidate.js +50 -18
- package/dist/memory/lifecycle.js +13 -0
- package/dist/memory/store.d.ts +1 -0
- package/dist/memory/store.js +73 -54
- package/dist/server.d.ts +6 -0
- package/dist/server.js +52 -2
- package/package.json +1 -1
- package/scripts/lib/recall-defence.mjs +254 -0
- package/scripts/lib/save-memory.mjs +12 -3
- package/scripts/prompt-recall-hook.mjs +33 -0
- package/scripts/session-start-hook.mjs +36 -4
- /package/dashboard/.next/standalone/dashboard/.next/static/{h2qG7AvaXDfMKQrI-bK4V → Xdk3QuQEKommHIbMSem56}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{h2qG7AvaXDfMKQrI-bK4V → Xdk3QuQEKommHIbMSem56}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{h2qG7AvaXDfMKQrI-bK4V → Xdk3QuQEKommHIbMSem56}/_ssgManifest.js +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<!DOCTYPE html><!--
|
|
2
|
-
@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/d878b929b21636c4.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57043,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n3:I[27657,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n4:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"ViewportBoundary\"]\n9:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"MetadataBoundary\"]\nb:I[30687,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"
|
|
1
|
+
<!DOCTYPE html><!--Xdk3QuQEKommHIbMSem56--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/d878b929b21636c4.js"/><script src="/_next/static/chunks/f70f563804550a9c.js" async=""></script><script src="/_next/static/chunks/43d761df92da7cb6.js" async=""></script><script src="/_next/static/chunks/e281719dbabcca1d.js" async=""></script><script src="/_next/static/chunks/9e56d1f8f4d7adcb.js" async=""></script><script src="/_next/static/chunks/turbopack-768a6a8b9db952e0.js" async=""></script><script src="/_next/static/chunks/102f894cc892994d.js" async=""></script><script src="/_next/static/chunks/417032eeb2cd875f.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
|
|
2
|
+
@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/d878b929b21636c4.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57043,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n3:I[27657,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n4:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"ViewportBoundary\"]\n9:I[56978,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"MetadataBoundary\"]\nb:I[30687,[\"/_next/static/chunks/102f894cc892994d.js\",\"/_next/static/chunks/417032eeb2cd875f.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"Xdk3QuQEKommHIbMSem56\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/102f894cc892994d.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/417032eeb2cd875f.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\na:[]\n"])</script></body></html>
|
|
@@ -553,7 +553,11 @@ export function registerMemoryRoutes(app, deps) {
|
|
|
553
553
|
salience,
|
|
554
554
|
memoryPurpose: memoryPurpose || undefined,
|
|
555
555
|
memoryScope: memoryScope || undefined,
|
|
556
|
-
}
|
|
556
|
+
}, undefined,
|
|
557
|
+
// Operator-attributable dashboard write → api:dashboard (trust 0.7):
|
|
558
|
+
// scanned like every write, but stays broadly recallable (above the
|
|
559
|
+
// sub-agent band) rather than the generic unattributed 0.3.
|
|
560
|
+
{ type: 'api', identifier: 'dashboard' });
|
|
557
561
|
res.status(201).json(memory);
|
|
558
562
|
}
|
|
559
563
|
catch (error) {
|
|
@@ -564,6 +568,15 @@ export function registerMemoryRoutes(app, deps) {
|
|
|
564
568
|
message: 'Use the dashboard control panel to resume memory creation.',
|
|
565
569
|
});
|
|
566
570
|
}
|
|
571
|
+
// The dashboard write is now scanned — surface a defence block as a 422,
|
|
572
|
+
// not a generic 500.
|
|
573
|
+
if (error.name === 'MemoryBlockedError') {
|
|
574
|
+
return res.status(422).json({
|
|
575
|
+
error: 'Blocked by the defence pipeline',
|
|
576
|
+
blocked: true,
|
|
577
|
+
message: error.message,
|
|
578
|
+
});
|
|
579
|
+
}
|
|
567
580
|
res.status(500).json({ error: error.message });
|
|
568
581
|
}
|
|
569
582
|
});
|
package/dist/cloud/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getCloudConfig, setCloudConfig, getCloudSyncControls, setCloudSyncControls, getDefenceMode, setDefenceMode, getVerifyConfig, setVerifyConfig, getReviewCopilotConfig, getOpenClawAutoMemory, setOpenClawAutoMemory, isProactiveRecallEnabled, setProactiveRecall, restore410Defaults, getRankerConfig, setRankerConfig, } from './config.js';
|
|
1
|
+
import { getCloudConfig, setCloudConfig, getCloudSyncControls, setCloudSyncControls, getDefenceMode, setDefenceMode, getVerifyConfig, setVerifyConfig, getReviewCopilotConfig, getOpenClawAutoMemory, setOpenClawAutoMemory, isProactiveRecallEnabled, setProactiveRecall, restore410Defaults, getRankerConfig, setRankerConfig, getToolResponseScanConfig, setToolResponseScanConfig, } from './config.js';
|
|
2
2
|
const VALID_RANKER_ENGINES = ['rrf', 'legacy'];
|
|
3
3
|
import { syncAllGraphToCloud } from './graph-sync.js';
|
|
4
4
|
import { syncAllMemoriesToCloud } from './memory-sync.js';
|
|
@@ -17,9 +17,11 @@ export function handleCloudConfig(args) {
|
|
|
17
17
|
const openclawAutoMemory = getOpenClawAutoMemory();
|
|
18
18
|
const ranker = getRankerConfig();
|
|
19
19
|
const syncControls = getCloudSyncControls();
|
|
20
|
+
const toolFirewall = getToolResponseScanConfig();
|
|
20
21
|
const rankerOverridden = !!process.env.SHIELDCORTEX_RANKER;
|
|
21
22
|
console.log('\nShieldCortex Configuration:');
|
|
22
23
|
console.log(` Defence Mode: ${mode}`);
|
|
24
|
+
console.log(` Tool-Output Firewall: ${toolFirewall.scanToolResponses ? toolFirewall.toolResponseMode : 'Off'}`);
|
|
23
25
|
console.log(` Cloud Enabled: ${config.cloudEnabled ? 'Yes' : 'No'}`);
|
|
24
26
|
console.log(` API Key: ${config.cloudApiKey ? config.cloudApiKey.substring(0, 12) + '...' : 'Not set'}`);
|
|
25
27
|
console.log(` Base URL: ${config.cloudBaseUrl}`);
|
|
@@ -188,6 +190,26 @@ export function handleCloudConfig(args) {
|
|
|
188
190
|
console.log(`Proactive recall ${enabled ? 'enabled' : 'disabled'}.`);
|
|
189
191
|
changed = true;
|
|
190
192
|
}
|
|
193
|
+
if (args.includes('--tool-firewall-enforce')) {
|
|
194
|
+
setToolResponseScanConfig({ scanToolResponses: true, toolResponseMode: 'enforce' });
|
|
195
|
+
console.log('Tool-output firewall set to ENFORCE — threatening tool output will be redacted/withheld before the agent sees it.');
|
|
196
|
+
changed = true;
|
|
197
|
+
}
|
|
198
|
+
if (args.includes('--tool-firewall-advisory')) {
|
|
199
|
+
setToolResponseScanConfig({ scanToolResponses: true, toolResponseMode: 'advisory' });
|
|
200
|
+
console.log('Tool-output firewall set to ADVISORY — threats are logged but tool output is delivered intact (default).');
|
|
201
|
+
changed = true;
|
|
202
|
+
}
|
|
203
|
+
if (args.includes('--tool-firewall-off')) {
|
|
204
|
+
setToolResponseScanConfig({ scanToolResponses: false });
|
|
205
|
+
console.log('Tool-output firewall disabled — tool responses are no longer scanned.');
|
|
206
|
+
changed = true;
|
|
207
|
+
}
|
|
208
|
+
if (args.includes('--tool-firewall-on')) {
|
|
209
|
+
setToolResponseScanConfig({ scanToolResponses: true });
|
|
210
|
+
console.log('Tool-output firewall enabled (scanning on).');
|
|
211
|
+
changed = true;
|
|
212
|
+
}
|
|
191
213
|
if (args.includes('--upsell-mute')) {
|
|
192
214
|
setUpsellState({ proMuted: true });
|
|
193
215
|
console.log('Pro upsell muted. Re-enable with --upsell-unmute.');
|
|
@@ -213,6 +235,9 @@ export function handleCloudConfig(args) {
|
|
|
213
235
|
console.log(' --openclaw-auto-memory <true|false> Extract memories from OpenClaw LLM output (default: off)');
|
|
214
236
|
console.log(' --proactive-recall <true|false> Inject SC memory into prompts (default: off — adds latency)');
|
|
215
237
|
console.log(' --ranker <rrf|legacy> Hybrid retrieval engine (default: rrf; SHIELDCORTEX_RANKER env overrides)');
|
|
238
|
+
console.log(' --tool-firewall-enforce Redact/withhold threatening tool output before the agent sees it');
|
|
239
|
+
console.log(' --tool-firewall-advisory Log tool-output threats but deliver intact (default)');
|
|
240
|
+
console.log(' --tool-firewall-off / --tool-firewall-on Disable / enable tool-output scanning');
|
|
216
241
|
console.log(' --restore-4.10-defaults Restore pre-v4.11.0 defaults (recall on, strict interceptor, minimal preamble)');
|
|
217
242
|
console.log(' --upsell-mute Suppress the Pro upsell footer in doctor');
|
|
218
243
|
console.log(' --upsell-unmute Allow the Pro upsell footer to surface again');
|
|
@@ -32,3 +32,18 @@ export interface MarkdownImageExfilResult {
|
|
|
32
32
|
* Scan content for markdown-image exfiltration links.
|
|
33
33
|
*/
|
|
34
34
|
export declare function detectMarkdownImageExfil(content: string): MarkdownImageExfilResult;
|
|
35
|
+
/** Replacement for a neutralised exfil image: a dead host carrying no data. */
|
|
36
|
+
export declare const NEUTRALISED_IMAGE = "";
|
|
37
|
+
/**
|
|
38
|
+
* Strip markdown-image exfiltration links from content for enforce mode.
|
|
39
|
+
*
|
|
40
|
+
* Re-runs the SAME regex + urlLooksLikeExfil predicate as detection and replaces
|
|
41
|
+
* each offending `` match WHOLE (alt dropped too — it can itself carry
|
|
42
|
+
* data). Splices by match offset, so it does not depend on substring equality
|
|
43
|
+
* with a previously-captured (truncated) URL and is unaffected by any other
|
|
44
|
+
* mutation applied to the content first. Benign images are left untouched.
|
|
45
|
+
*/
|
|
46
|
+
export declare function neutraliseMarkdownImageExfil(content: string): {
|
|
47
|
+
content: string;
|
|
48
|
+
stripped: number;
|
|
49
|
+
};
|
|
@@ -81,3 +81,33 @@ export function detectMarkdownImageExfil(content) {
|
|
|
81
81
|
urls,
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
+
/** Replacement for a neutralised exfil image: a dead host carrying no data. */
|
|
85
|
+
export const NEUTRALISED_IMAGE = '';
|
|
86
|
+
/**
|
|
87
|
+
* Strip markdown-image exfiltration links from content for enforce mode.
|
|
88
|
+
*
|
|
89
|
+
* Re-runs the SAME regex + urlLooksLikeExfil predicate as detection and replaces
|
|
90
|
+
* each offending `` match WHOLE (alt dropped too — it can itself carry
|
|
91
|
+
* data). Splices by match offset, so it does not depend on substring equality
|
|
92
|
+
* with a previously-captured (truncated) URL and is unaffected by any other
|
|
93
|
+
* mutation applied to the content first. Benign images are left untouched.
|
|
94
|
+
*/
|
|
95
|
+
export function neutraliseMarkdownImageExfil(content) {
|
|
96
|
+
const spans = [];
|
|
97
|
+
MARKDOWN_IMAGE_PATTERN.lastIndex = 0;
|
|
98
|
+
let match;
|
|
99
|
+
while ((match = MARKDOWN_IMAGE_PATTERN.exec(content)) !== null) {
|
|
100
|
+
if (urlLooksLikeExfil(match[1])) {
|
|
101
|
+
spans.push({ start: match.index, end: match.index + match[0].length });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (spans.length === 0)
|
|
105
|
+
return { content, stripped: 0 };
|
|
106
|
+
// Splice from the end so earlier offsets stay valid.
|
|
107
|
+
let result = content;
|
|
108
|
+
for (let i = spans.length - 1; i >= 0; i--) {
|
|
109
|
+
const { start, end } = spans[i];
|
|
110
|
+
result = result.slice(0, start) + NEUTRALISED_IMAGE + result.slice(end);
|
|
111
|
+
}
|
|
112
|
+
return { content: result, stripped: spans.length };
|
|
113
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { getDatabase, withTransaction } from '../../database/init.js';
|
|
2
|
-
import { addMemory } from '../../memory/store.js';
|
|
2
|
+
import { addMemory, MemoryBlockedError } from '../../memory/store.js';
|
|
3
3
|
function getPendingQuarantineRow(id) {
|
|
4
4
|
const db = getDatabase();
|
|
5
|
-
const row = db.prepare(`SELECT id, original_title, original_content, project, source_type, source_identifier, reason
|
|
5
|
+
const row = db.prepare(`SELECT id, original_title, original_content, project, source_type, source_identifier, reason, firewall_result
|
|
6
6
|
FROM quarantine
|
|
7
7
|
WHERE id = ? AND status = 'pending'`).get(id);
|
|
8
8
|
return row ?? null;
|
|
@@ -31,16 +31,20 @@ function promoteApprovedQuarantineRow(row, reviewedBy) {
|
|
|
31
31
|
approvedFromQuarantine: true,
|
|
32
32
|
quarantineId: row.id,
|
|
33
33
|
quarantineReason: row.reason ?? null,
|
|
34
|
+
// Original provenance is preserved here (the trust now reflects the
|
|
35
|
+
// human approval, not the original source).
|
|
34
36
|
originalSourceType: row.source_type ?? null,
|
|
35
37
|
originalSourceIdentifier: row.source_identifier ?? null,
|
|
36
38
|
},
|
|
37
39
|
captureMethod: 'review',
|
|
38
40
|
reviewedBy,
|
|
39
41
|
sourceKind: normalizeSourceKind(row.source_type),
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
}, undefined,
|
|
43
|
+
// A human approving the item IS the parent-approval the quarantine was
|
|
44
|
+
// waiting for, so admit at user:approved (0.9 — out of the 0.5–0.7 auto-
|
|
45
|
+
// quarantine band, so it isn't re-quarantined in a loop). The pipeline still
|
|
46
|
+
// RE-SCANS, so genuinely-malicious content fails closed (caller catches it).
|
|
47
|
+
{ type: 'user', identifier: 'approved' });
|
|
44
48
|
}
|
|
45
49
|
function markPendingRowReviewed(id, status, reviewedBy) {
|
|
46
50
|
const db = getDatabase();
|
|
@@ -58,7 +62,25 @@ function approveExistingPendingRow(row, reviewedBy) {
|
|
|
58
62
|
status: 'approved',
|
|
59
63
|
};
|
|
60
64
|
}
|
|
61
|
-
|
|
65
|
+
// Never re-admit content the pipeline HARD-BLOCKED. Approving a BLOCK item
|
|
66
|
+
// rejects it instead of laundering hard-rejected poison back into memory.
|
|
67
|
+
if (row.firewall_result === 'BLOCK') {
|
|
68
|
+
markPendingRowReviewed(row.id, 'rejected', reviewedBy);
|
|
69
|
+
return { id: row.id, status: 'rejected' };
|
|
70
|
+
}
|
|
71
|
+
// QUARANTINE (soft hold): re-admit through the pipeline at operator-approved
|
|
72
|
+
// trust. If the content now hard-blocks, fail closed — reject, don't admit.
|
|
73
|
+
let memory;
|
|
74
|
+
try {
|
|
75
|
+
memory = promoteApprovedQuarantineRow(row, reviewedBy);
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
if (e instanceof MemoryBlockedError) {
|
|
79
|
+
markPendingRowReviewed(row.id, 'rejected', reviewedBy);
|
|
80
|
+
return { id: row.id, status: 'rejected' };
|
|
81
|
+
}
|
|
82
|
+
throw e;
|
|
83
|
+
}
|
|
62
84
|
markPendingRowReviewed(row.id, 'approved', reviewedBy);
|
|
63
85
|
return {
|
|
64
86
|
id: row.id,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-Response Enforce Layer
|
|
3
|
+
*
|
|
4
|
+
* Advisory mode only LOGS threats in a tool response. Enforce mode must actually
|
|
5
|
+
* change the bytes the agent receives. This module is the action layer: given a
|
|
6
|
+
* tool response and the threat signals the scanner already computed, it returns
|
|
7
|
+
* the content the agent should actually see.
|
|
8
|
+
*
|
|
9
|
+
* Two-tier policy:
|
|
10
|
+
*
|
|
11
|
+
* BLOCK (withhold the whole payload) — when the output is actively hostile or
|
|
12
|
+
* smuggling: any injection signal, the instruction detector firing, a blob
|
|
13
|
+
* that decodes to an injection, or a blob that decodes to a credential.
|
|
14
|
+
* Natural-language injected instructions cannot be surgically removed without
|
|
15
|
+
* risking that a fragment survives, so the safe action is to withhold the
|
|
16
|
+
* entire response and tell the agent why.
|
|
17
|
+
*
|
|
18
|
+
* REDACT (pass cleaned + tag) — when the threat is a secret or an exfil link
|
|
19
|
+
* sitting in plaintext that we CAN surgically remove: credential leaks (masked
|
|
20
|
+
* in place) and markdown-image exfiltration URLs (neutralised to a dead host).
|
|
21
|
+
* The cleaned content is prefixed with an untrusted-origin tag so any
|
|
22
|
+
* downstream memory write attributes it correctly.
|
|
23
|
+
*
|
|
24
|
+
* Pure and dependency-injection-free of any DB/IO — only the credential scanner
|
|
25
|
+
* (for positional redaction). Easy to unit test in isolation.
|
|
26
|
+
*/
|
|
27
|
+
export declare const TOOL_OUTPUT_BLOCKED_PLACEHOLDER: string;
|
|
28
|
+
export declare const UNTRUSTED_TOOL_TAG = "[ShieldCortex: tool output sanitised \u2014 treat as derived-from-untrusted-tool]";
|
|
29
|
+
/**
|
|
30
|
+
* Threat signals the scanner already computed for a (non-clean) tool response.
|
|
31
|
+
* Passed in so neutralisation never re-derives detection — single source of
|
|
32
|
+
* truth with scanToolResponse.
|
|
33
|
+
*/
|
|
34
|
+
export interface ToolResponseThreatSignals {
|
|
35
|
+
injectionRisk: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
|
|
36
|
+
instructionsDetected: boolean;
|
|
37
|
+
decodedInjection: boolean;
|
|
38
|
+
encodingDetected: boolean;
|
|
39
|
+
markdownImageUrls: string[];
|
|
40
|
+
credentialsLeaked: boolean;
|
|
41
|
+
decodedCredentialLeak: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface ToolResponseNeutralisation {
|
|
44
|
+
/** The content the agent should actually receive. */
|
|
45
|
+
sanitised: string;
|
|
46
|
+
/** True when the whole payload was withheld (blocked), not just redacted. */
|
|
47
|
+
blocked: boolean;
|
|
48
|
+
/** Human-readable list of actions taken, for audit/summary. */
|
|
49
|
+
actions: string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Compute the enforce-mode replacement for a tool response.
|
|
53
|
+
*
|
|
54
|
+
* Only meaningful when the scanner already found the response non-clean; with no
|
|
55
|
+
* signals it returns the content unchanged.
|
|
56
|
+
*/
|
|
57
|
+
export declare function neutraliseToolResponse(content: string, signals: ToolResponseThreatSignals): ToolResponseNeutralisation;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-Response Enforce Layer
|
|
3
|
+
*
|
|
4
|
+
* Advisory mode only LOGS threats in a tool response. Enforce mode must actually
|
|
5
|
+
* change the bytes the agent receives. This module is the action layer: given a
|
|
6
|
+
* tool response and the threat signals the scanner already computed, it returns
|
|
7
|
+
* the content the agent should actually see.
|
|
8
|
+
*
|
|
9
|
+
* Two-tier policy:
|
|
10
|
+
*
|
|
11
|
+
* BLOCK (withhold the whole payload) — when the output is actively hostile or
|
|
12
|
+
* smuggling: any injection signal, the instruction detector firing, a blob
|
|
13
|
+
* that decodes to an injection, or a blob that decodes to a credential.
|
|
14
|
+
* Natural-language injected instructions cannot be surgically removed without
|
|
15
|
+
* risking that a fragment survives, so the safe action is to withhold the
|
|
16
|
+
* entire response and tell the agent why.
|
|
17
|
+
*
|
|
18
|
+
* REDACT (pass cleaned + tag) — when the threat is a secret or an exfil link
|
|
19
|
+
* sitting in plaintext that we CAN surgically remove: credential leaks (masked
|
|
20
|
+
* in place) and markdown-image exfiltration URLs (neutralised to a dead host).
|
|
21
|
+
* The cleaned content is prefixed with an untrusted-origin tag so any
|
|
22
|
+
* downstream memory write attributes it correctly.
|
|
23
|
+
*
|
|
24
|
+
* Pure and dependency-injection-free of any DB/IO — only the credential scanner
|
|
25
|
+
* (for positional redaction). Easy to unit test in isolation.
|
|
26
|
+
*/
|
|
27
|
+
import { scanForCredentials } from './credential-leak/index.js';
|
|
28
|
+
import { neutraliseMarkdownImageExfil } from './firewall/markdown-image-detector.js';
|
|
29
|
+
export const TOOL_OUTPUT_BLOCKED_PLACEHOLDER = '[ShieldCortex] Tool output withheld in enforce mode — prompt-injection / data-smuggling detected. ' +
|
|
30
|
+
'The original response was blocked to protect the agent. Review the ShieldCortex audit log for details.';
|
|
31
|
+
export const UNTRUSTED_TOOL_TAG = '[ShieldCortex: tool output sanitised — treat as derived-from-untrusted-tool]';
|
|
32
|
+
function hasAnySignal(s) {
|
|
33
|
+
return (s.injectionRisk !== 'NONE' ||
|
|
34
|
+
s.instructionsDetected ||
|
|
35
|
+
s.decodedInjection ||
|
|
36
|
+
s.encodingDetected ||
|
|
37
|
+
s.markdownImageUrls.length > 0 ||
|
|
38
|
+
s.credentialsLeaked ||
|
|
39
|
+
s.decodedCredentialLeak);
|
|
40
|
+
}
|
|
41
|
+
/** Output is actively hostile / smuggling — withhold the whole payload. */
|
|
42
|
+
function shouldBlock(s) {
|
|
43
|
+
return (s.injectionRisk !== 'NONE' ||
|
|
44
|
+
s.instructionsDetected ||
|
|
45
|
+
s.decodedInjection ||
|
|
46
|
+
s.decodedCredentialLeak);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Compute the enforce-mode replacement for a tool response.
|
|
50
|
+
*
|
|
51
|
+
* Only meaningful when the scanner already found the response non-clean; with no
|
|
52
|
+
* signals it returns the content unchanged.
|
|
53
|
+
*/
|
|
54
|
+
export function neutraliseToolResponse(content, signals) {
|
|
55
|
+
if (!hasAnySignal(signals)) {
|
|
56
|
+
return { sanitised: content, blocked: false, actions: [] };
|
|
57
|
+
}
|
|
58
|
+
if (shouldBlock(signals)) {
|
|
59
|
+
const actions = [];
|
|
60
|
+
if (signals.injectionRisk !== 'NONE') {
|
|
61
|
+
actions.push(`blocked: prompt-injection (${signals.injectionRisk.toLowerCase()})`);
|
|
62
|
+
}
|
|
63
|
+
else if (signals.instructionsDetected) {
|
|
64
|
+
// No high-confidence Iron Dome hit — be honest that this is the heuristic
|
|
65
|
+
// instruction detector, not a graded injection (don't say "injection (none)").
|
|
66
|
+
actions.push('blocked: suspicious-instruction pattern (heuristic)');
|
|
67
|
+
}
|
|
68
|
+
if (signals.decodedInjection)
|
|
69
|
+
actions.push('blocked: encoded payload decoded to injection');
|
|
70
|
+
if (signals.decodedCredentialLeak)
|
|
71
|
+
actions.push('blocked: encoded payload decoded to credential');
|
|
72
|
+
return { sanitised: TOOL_OUTPUT_BLOCKED_PLACEHOLDER, blocked: true, actions };
|
|
73
|
+
}
|
|
74
|
+
// Redact path: surgically clean a payload that merely contains secrets / exfil
|
|
75
|
+
// links in plaintext. The untrusted-origin tag is NOT embedded here — callers
|
|
76
|
+
// convey it out-of-band so redacted structured output (JSON/CSV) stays parseable.
|
|
77
|
+
const actions = [];
|
|
78
|
+
let working = content;
|
|
79
|
+
// Markdown-image exfil FIRST, before any other mutation. Uses a full-match
|
|
80
|
+
// regex over the content (not substring equality with a pre-captured, possibly
|
|
81
|
+
// truncated URL), so credential redaction reordering and >200-char URLs can't
|
|
82
|
+
// defeat it. If the scanner flagged exfil images but none could be located
|
|
83
|
+
// here, fail SAFE: withhold the whole payload rather than deliver it.
|
|
84
|
+
if (signals.markdownImageUrls.length > 0) {
|
|
85
|
+
const { content: stripped, stripped: count } = neutraliseMarkdownImageExfil(working);
|
|
86
|
+
if (count === 0) {
|
|
87
|
+
return {
|
|
88
|
+
sanitised: TOOL_OUTPUT_BLOCKED_PLACEHOLDER,
|
|
89
|
+
blocked: true,
|
|
90
|
+
actions: ['blocked: flagged markdown-image exfil could not be neutralised (fail-safe)'],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
working = stripped;
|
|
94
|
+
actions.push(`stripped ${count} markdown-image exfil URL(s)`);
|
|
95
|
+
}
|
|
96
|
+
if (signals.credentialsLeaked) {
|
|
97
|
+
const cred = scanForCredentials(working);
|
|
98
|
+
if (cred.leaked && cred.redactedContent) {
|
|
99
|
+
working = cred.redactedContent;
|
|
100
|
+
actions.push(`redacted ${cred.findings.length} credential(s)`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (signals.encodingDetected) {
|
|
104
|
+
actions.push('flagged obfuscated/encoded content (passed through)');
|
|
105
|
+
}
|
|
106
|
+
return { sanitised: working, blocked: false, actions };
|
|
107
|
+
}
|
|
@@ -17,9 +17,12 @@
|
|
|
17
17
|
* It deliberately does NOT pull in the write-path's trust scoring, anomaly,
|
|
18
18
|
* privilege, fragmentation or sensitivity layers — those are write concerns.
|
|
19
19
|
*
|
|
20
|
-
* Advisory by default: logs threats but
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* Advisory by default: logs threats but leaves the response untouched. In
|
|
21
|
+
* enforce mode the scanner additionally computes `sanitisedContent` — the bytes
|
|
22
|
+
* the agent should actually receive (injection withheld, secrets redacted, exfil
|
|
23
|
+
* links stripped) — via the neutraliseToolResponse action layer. Callers
|
|
24
|
+
* (withResponseScan, the scan_tool_response tool) swap in sanitisedContent when
|
|
25
|
+
* present; the scanner never blocks tool EXECUTION, only the threatening output.
|
|
23
26
|
*/
|
|
24
27
|
import type { ToolResponseScanResult } from './types.js';
|
|
25
28
|
/**
|
|
@@ -17,15 +17,19 @@
|
|
|
17
17
|
* It deliberately does NOT pull in the write-path's trust scoring, anomaly,
|
|
18
18
|
* privilege, fragmentation or sensitivity layers — those are write concerns.
|
|
19
19
|
*
|
|
20
|
-
* Advisory by default: logs threats but
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* Advisory by default: logs threats but leaves the response untouched. In
|
|
21
|
+
* enforce mode the scanner additionally computes `sanitisedContent` — the bytes
|
|
22
|
+
* the agent should actually receive (injection withheld, secrets redacted, exfil
|
|
23
|
+
* links stripped) — via the neutraliseToolResponse action layer. Callers
|
|
24
|
+
* (withResponseScan, the scan_tool_response tool) swap in sanitisedContent when
|
|
25
|
+
* present; the scanner never blocks tool EXECUTION, only the threatening output.
|
|
23
26
|
*/
|
|
24
27
|
import { scanForInjection } from './iron-dome/injection-scanner.js';
|
|
25
28
|
import { scanForCredentials } from './credential-leak/index.js';
|
|
26
29
|
import { detectInstructions } from './firewall/instruction-detector.js';
|
|
27
30
|
import { detectEncoding } from './firewall/encoding-detector.js';
|
|
28
31
|
import { detectMarkdownImageExfil } from './firewall/markdown-image-detector.js';
|
|
32
|
+
import { neutraliseToolResponse } from './tool-response-enforce.js';
|
|
29
33
|
import { logAudit } from './audit/logger.js';
|
|
30
34
|
import { isDatabaseInitialized } from '../database/init.js';
|
|
31
35
|
import { getToolResponseScanConfig } from '../cloud/config.js';
|
|
@@ -48,6 +52,11 @@ const HIGH_RISK_TOOLS = new Set([
|
|
|
48
52
|
'export_memories',
|
|
49
53
|
'detect_contradictions',
|
|
50
54
|
]);
|
|
55
|
+
// Instruction-detector pattern groups that are WRITE-path concerns and over-fire
|
|
56
|
+
// on legitimate tool OUTPUT (instructional docs telling the agent which tool to
|
|
57
|
+
// call). Excluded from the read-path instruction signal; real injection groups
|
|
58
|
+
// (system_prompt_marker, hidden_instruction, prompt_extraction, …) still apply.
|
|
59
|
+
const READ_PATH_EXCLUDED_INSTRUCTION_PATTERNS = new Set(['imperative_tool_call']);
|
|
51
60
|
// Tools that only return metadata/stats (not worth scanning)
|
|
52
61
|
const METADATA_ONLY_TOOLS = new Set([
|
|
53
62
|
'memory_stats',
|
|
@@ -90,6 +99,9 @@ export function scanToolResponse(toolName, content, mode) {
|
|
|
90
99
|
summary: `Tool response from "${toolName}" skipped (too short)`,
|
|
91
100
|
durationMs: Math.round(performance.now() - startTime),
|
|
92
101
|
auditId: -1,
|
|
102
|
+
sanitisedContent: null,
|
|
103
|
+
blocked: false,
|
|
104
|
+
enforceActions: [],
|
|
93
105
|
};
|
|
94
106
|
}
|
|
95
107
|
// 1. Injection scan (Iron Dome named patterns — drives the `injection` field
|
|
@@ -97,7 +109,17 @@ export function scanToolResponse(toolName, content, mode) {
|
|
|
97
109
|
const injection = scanForInjection(content);
|
|
98
110
|
// 2. Write-path detectors (parity). detectInstructions folds homoglyphs and
|
|
99
111
|
// scans in windows; detectEncoding decodes base64/hex/url blobs.
|
|
100
|
-
|
|
112
|
+
//
|
|
113
|
+
// FP reduction on the READ path: `imperative_tool_call` ("call the X tool")
|
|
114
|
+
// exists to catch injected directives at WRITE time. On tool OUTPUT it is
|
|
115
|
+
// legitimate instructional content (docs telling the agent which tool to
|
|
116
|
+
// use), so we exclude it here. Real injection phrasing ("ignore previous
|
|
117
|
+
// instructions", "you are now…") lives in the other groups + Iron Dome and
|
|
118
|
+
// is unaffected. Decoded snippets (below) keep full detection — an encoded
|
|
119
|
+
// imperative is inherently suspicious.
|
|
120
|
+
const instructionsRaw = detectInstructions(content);
|
|
121
|
+
const instructionPatterns = instructionsRaw.patterns.filter((p) => !READ_PATH_EXCLUDED_INSTRUCTION_PATTERNS.has(p));
|
|
122
|
+
const instructions = { detected: instructionPatterns.length > 0, patterns: instructionPatterns };
|
|
101
123
|
const encoding = detectEncoding(content);
|
|
102
124
|
// 2b. Decode-and-rescan: re-run instruction + credential detection on each
|
|
103
125
|
// decoded snippet so a BARE base64/hex blob that decodes to an injection
|
|
@@ -155,6 +177,31 @@ export function scanToolResponse(toolName, content, mode) {
|
|
|
155
177
|
!markdownImage.detected &&
|
|
156
178
|
!credentials.leaked;
|
|
157
179
|
const durationMs = Math.round(performance.now() - startTime);
|
|
180
|
+
// 5b. Enforce action layer. Advisory mode only logs; enforce mode computes the
|
|
181
|
+
// content the agent should ACTUALLY receive (block injection, redact
|
|
182
|
+
// secrets, strip exfil links). Single source of truth in
|
|
183
|
+
// neutraliseToolResponse — the scanner just feeds it the signals it found.
|
|
184
|
+
let sanitisedContent = null;
|
|
185
|
+
let blocked = false;
|
|
186
|
+
let enforceActions = [];
|
|
187
|
+
if (!clean && resolvedMode === 'enforce') {
|
|
188
|
+
const neutralisation = neutraliseToolResponse(content, {
|
|
189
|
+
injectionRisk: injection.riskLevel,
|
|
190
|
+
instructionsDetected: instructions.detected,
|
|
191
|
+
decodedInjection,
|
|
192
|
+
encodingDetected: encoding.detected,
|
|
193
|
+
markdownImageUrls: markdownImage.urls,
|
|
194
|
+
credentialsLeaked: credentials.leaked,
|
|
195
|
+
decodedCredentialLeak,
|
|
196
|
+
});
|
|
197
|
+
sanitisedContent = neutralisation.sanitised;
|
|
198
|
+
blocked = neutralisation.blocked;
|
|
199
|
+
enforceActions = neutralisation.actions;
|
|
200
|
+
}
|
|
201
|
+
// Truthful firewall_result: advisory only observes (ALLOW); enforce that
|
|
202
|
+
// withholds the whole payload is a BLOCK; enforce that surgically redacts but
|
|
203
|
+
// still delivers is a QUARANTINE.
|
|
204
|
+
const firewallResult = resolvedMode !== 'enforce' ? 'ALLOW' : blocked ? 'BLOCK' : 'QUARANTINE';
|
|
158
205
|
// 6. Build summary
|
|
159
206
|
let summary;
|
|
160
207
|
if (clean) {
|
|
@@ -202,7 +249,7 @@ export function scanToolResponse(toolName, content, mode) {
|
|
|
202
249
|
source_identifier: toolName,
|
|
203
250
|
trust_score: 0.5,
|
|
204
251
|
sensitivity_level: (credentials.leaked || decodedCredentialLeak) ? 'CONFIDENTIAL' : 'PUBLIC',
|
|
205
|
-
firewall_result:
|
|
252
|
+
firewall_result: firewallResult,
|
|
206
253
|
anomaly_score: anomalyScore,
|
|
207
254
|
threat_indicators: JSON.stringify(threatIndicators),
|
|
208
255
|
blocked_patterns: JSON.stringify(blockedPatterns),
|
|
@@ -219,7 +266,7 @@ export function scanToolResponse(toolName, content, mode) {
|
|
|
219
266
|
persistEvent('defence_event', {
|
|
220
267
|
source_type: 'tool_response',
|
|
221
268
|
source_identifier: toolName,
|
|
222
|
-
firewall_result:
|
|
269
|
+
firewall_result: firewallResult,
|
|
223
270
|
trust_score: 0.5,
|
|
224
271
|
anomaly_score: anomalyScore,
|
|
225
272
|
reason: summary,
|
|
@@ -241,5 +288,8 @@ export function scanToolResponse(toolName, content, mode) {
|
|
|
241
288
|
summary,
|
|
242
289
|
durationMs,
|
|
243
290
|
auditId,
|
|
291
|
+
sanitisedContent,
|
|
292
|
+
blocked,
|
|
293
|
+
enforceActions,
|
|
244
294
|
};
|
|
245
295
|
}
|
|
@@ -11,9 +11,13 @@ export function filterByTrust(results, minTrust, context) {
|
|
|
11
11
|
// Filter below minimum trust
|
|
12
12
|
if (score < minTrust)
|
|
13
13
|
return false;
|
|
14
|
-
// CONFIDENTIAL: only
|
|
14
|
+
// CONFIDENTIAL: context-scope only when the row actually DECLARES a
|
|
15
|
+
// context. metadata.context is not written on store today, so requiring
|
|
16
|
+
// equality dropped every CONFIDENTIAL (any email/phone-bearing) row from
|
|
17
|
+
// recall — silent amnesia. Drop only a declared-but-mismatched context.
|
|
15
18
|
if (item.sensitivity_level === 'CONFIDENTIAL') {
|
|
16
|
-
|
|
19
|
+
const rowContext = item.metadata?.context;
|
|
20
|
+
if (rowContext != null && context != null && rowContext !== context)
|
|
17
21
|
return false;
|
|
18
22
|
}
|
|
19
23
|
return true;
|
|
@@ -5,6 +5,11 @@ import { scoreAgent, buildAgentHierarchy } from './agent-scorer.js';
|
|
|
5
5
|
const BASE_SCORES = {
|
|
6
6
|
'user:direct': 1.0,
|
|
7
7
|
'user:approved': 0.9,
|
|
8
|
+
// Bulk import (restore from a backup/JSON). The generic `file` type is 0.6,
|
|
9
|
+
// which sits inside the 0.5–0.7 auto-quarantine band and would quarantine
|
|
10
|
+
// every imported row. Pin below the band so a benign restore succeeds while
|
|
11
|
+
// imported file data stays scanned + low-trust until reviewed.
|
|
12
|
+
'file:import': 0.4,
|
|
8
13
|
};
|
|
9
14
|
const TYPE_SCORES = {
|
|
10
15
|
user: 1.0,
|
package/dist/defence/types.d.ts
CHANGED
|
@@ -21,6 +21,15 @@ export interface ToolResponseScanResult {
|
|
|
21
21
|
summary: string;
|
|
22
22
|
durationMs: number;
|
|
23
23
|
auditId: number;
|
|
24
|
+
/**
|
|
25
|
+
* Enforce-mode replacement content the agent should actually receive.
|
|
26
|
+
* `null` in advisory mode and whenever the response is clean (nothing to do).
|
|
27
|
+
*/
|
|
28
|
+
sanitisedContent: string | null;
|
|
29
|
+
/** True when enforce mode withheld the whole payload (vs. surgically redacting). */
|
|
30
|
+
blocked: boolean;
|
|
31
|
+
/** Human-readable actions taken in enforce mode (empty otherwise). */
|
|
32
|
+
enforceActions: string[];
|
|
24
33
|
}
|
|
25
34
|
export interface FirewallAnalysis {
|
|
26
35
|
result: FirewallResult;
|