@solongate/proxy 0.83.39 → 0.83.41

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.
@@ -8337,9 +8337,9 @@ async function getOpaWasmBytes(policy) {
8337
8337
  try {
8338
8338
  if (existsSync(cacheFile)) {
8339
8339
  const c = JSON.parse(readFileSync(cacheFile, "utf-8"));
8340
- if (c && c.wasm) {
8340
+ if (c && c.wasm && c.fp === fp) {
8341
8341
  stale = new Uint8Array(Buffer.from(c.wasm, "base64"));
8342
- if (c.fp === fp && c._ts && Date.now() - c._ts < OPA_WASM_TTL_MS) {
8342
+ if (c._ts && Date.now() - c._ts < OPA_WASM_TTL_MS) {
8343
8343
  return stale;
8344
8344
  }
8345
8345
  }
package/hooks/guard.mjs CHANGED
@@ -2312,13 +2312,25 @@ async function getOpaWasmBytes(policy) {
2312
2312
  // Read any cached bundle. A "fresh" hit (same policy fingerprint, within TTL)
2313
2313
  // is returned immediately; otherwise we keep it as `stale` to fall back on if
2314
2314
  // the API is momentarily unreachable — so transient downtime never drops OPA.
2315
+ //
2316
+ // ONLY when the fingerprint still matches. A bundle compiled from a DIFFERENT
2317
+ // policy is not "last known good", it is the wrong policy: it enforces rules
2318
+ // the user has deleted and misses the ones they just wrote. That is what a
2319
+ // stale hit did until now, and it is invisible from the outside — the denial
2320
+ // cites a rule id that is no longer in `policy active`, and the user's only
2321
+ // clue is that their own policy does not contain the rule that just fired.
2322
+ //
2323
+ // Dropping it here does not disarm anything. With no bundle the guard falls
2324
+ // through to its deterministic evaluator, which reads the policy it actually
2325
+ // has, so a fingerprint mismatch costs the OPA-only behaviours and keeps the
2326
+ // rules correct. Enforcing a deleted rule is the worse of the two.
2315
2327
  let stale = null;
2316
2328
  try {
2317
2329
  if (existsSync(cacheFile)) {
2318
2330
  const c = JSON.parse(readFileSync(cacheFile, 'utf-8'));
2319
- if (c && c.wasm) {
2331
+ if (c && c.wasm && c.fp === fp) {
2320
2332
  stale = new Uint8Array(Buffer.from(c.wasm, 'base64'));
2321
- if (c.fp === fp && c._ts && Date.now() - c._ts < OPA_WASM_TTL_MS) {
2333
+ if (c._ts && Date.now() - c._ts < OPA_WASM_TTL_MS) {
2322
2334
  return stale;
2323
2335
  }
2324
2336
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.83.39",
3
+ "version": "0.83.41",
4
4
  "description": "AI tool security proxy: protect any AI tool server with customizable policies, path/command constraints, rate limiting, and audit logging. No code changes required.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -61,12 +61,12 @@
61
61
  "node": ">=20.0.0"
62
62
  },
63
63
  "optionalDependencies": {
64
- "@solongate/guard-linux-x64": "0.83.39",
65
- "@solongate/guard-linux-arm64": "0.83.39",
66
- "@solongate/guard-darwin-x64": "0.83.39",
67
- "@solongate/guard-darwin-arm64": "0.83.39",
68
- "@solongate/guard-win32-x64": "0.83.39",
69
- "@solongate/guard-win32-arm64": "0.83.39"
64
+ "@solongate/guard-linux-x64": "0.83.41",
65
+ "@solongate/guard-linux-arm64": "0.83.41",
66
+ "@solongate/guard-darwin-x64": "0.83.41",
67
+ "@solongate/guard-darwin-arm64": "0.83.41",
68
+ "@solongate/guard-win32-x64": "0.83.41",
69
+ "@solongate/guard-win32-arm64": "0.83.41"
70
70
  },
71
71
  "dependencies": {
72
72
  "@modelcontextprotocol/sdk": "^1.26.0",