@mudraid/sidecar 1.1.1 → 1.1.2
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/README.md +12 -0
- package/dist/build-inputs.json +4 -4
- package/dist/{chunk-XEUNXTTV.js → chunk-5SXBQNJF.js} +15 -2
- package/dist/index.js +1 -1
- package/dist/server.js +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -55,3 +55,15 @@ The image uses a build stage and runs compiled code as the unprivileged Node use
|
|
|
55
55
|
## Qualification still pending
|
|
56
56
|
|
|
57
57
|
Exact body bytes, caller, HTTP target and action/configuration are now bound to the signed decision, and the sidecar forwards its owned authorized snapshot. Trusted business-fact profiles and policy projection remain unimplemented; the runtime must not be represented as proving independent business-state truth or a committed operation. Standalone installed-package checks also do not establish network bypass resistance, containment-channel convergence, graceful drain, chaos/soak behavior or multi-architecture publication. These require their respective runtime evidence before broader support claims.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
### Authorization expires before forwarding
|
|
61
|
+
|
|
62
|
+
A verified decision that arrives after its deadline is refused with HTTP 503,
|
|
63
|
+
`ENFORCE_DECIDE_UNAVAILABLE`, and reason `deadline_exceeded`. The message explains
|
|
64
|
+
that authorization expired and this attempt was not forwarded. This differs
|
|
65
|
+
from an unreachable authority; it does not mean that permission was denied.
|
|
66
|
+
The adapter does not automatically retry. A deliberate retry must obtain a fresh
|
|
67
|
+
decision. Use application-level idempotency for operations that could already
|
|
68
|
+
have executed in an earlier attempt; this error makes no claim about those
|
|
69
|
+
other attempts. Never reuse an expired decision or disable expiry validation.
|
package/dist/build-inputs.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schema": "mudraid.sidecar.build-inputs/1",
|
|
3
3
|
"bundledCore": {
|
|
4
4
|
"name": "@mudraid/adapter-node",
|
|
5
|
-
"version": "1.1.
|
|
5
|
+
"version": "1.1.2",
|
|
6
6
|
"license": "Apache-2.0"
|
|
7
7
|
},
|
|
8
8
|
"inputs": [
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
"path": "adapter-node/src/controlLoop.ts",
|
|
39
|
-
"sha256": "
|
|
39
|
+
"sha256": "e51bdeccd9369006f30a5df6fda3d31aa88d718728143bf4b0d1087ef446040a"
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
"path": "adapter-node/src/decideClient.ts",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
"path": "adapter-node/src/httpAuthority.ts",
|
|
51
|
-
"sha256": "
|
|
51
|
+
"sha256": "cdf8f7e18ef8d71d90a88b5dd9cab455b70a6193ded98be84392eca8aa468acb"
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
"path": "adapter-node/src/index.ts",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"path": "adapter-node/src/types.ts",
|
|
63
|
-
"sha256": "
|
|
63
|
+
"sha256": "f2e4f0a1441bb96122c418c0559a6015eb8234a7fb03014027680eacb722fb55"
|
|
64
64
|
}
|
|
65
65
|
]
|
|
66
66
|
}
|
|
@@ -350,7 +350,7 @@ var HttpAuthority = class {
|
|
|
350
350
|
const response = await this.request("decide", "POST", {
|
|
351
351
|
schema_version: "mudraid.enforce.decide-request/1",
|
|
352
352
|
decision_id: decisionId,
|
|
353
|
-
adapter: { type: this.adapterType, version: "1.1.
|
|
353
|
+
adapter: { type: this.adapterType, version: "1.1.2" },
|
|
354
354
|
bundle: { version: snapshot.version, payload_digest: snapshot.digest },
|
|
355
355
|
// Bundle display metadata is not part of the strict decision contract.
|
|
356
356
|
surface: {
|
|
@@ -367,7 +367,7 @@ var HttpAuthority = class {
|
|
|
367
367
|
const now = Date.now();
|
|
368
368
|
const decidedAt = instant(response["decided_at"]);
|
|
369
369
|
if (decidedAt > now + 3e4 || now - decidedAt > 6e4) throw new Error("Stale decision");
|
|
370
|
-
|
|
370
|
+
const deadline = instant(response["deadline_at"]);
|
|
371
371
|
const signature = object(response["signature"]);
|
|
372
372
|
const claims = object(signature["claims"]);
|
|
373
373
|
const keyId = signature["key_id"];
|
|
@@ -386,6 +386,7 @@ var HttpAuthority = class {
|
|
|
386
386
|
if (instant(claims["not_before"]) > now + 3e4 || instant(claims["expires_at"]) <= now) throw new Error("Invalid decision window");
|
|
387
387
|
if (snapshot !== this.bundle) throw new Error("Bundle changed during decision");
|
|
388
388
|
if (response["decision"] !== "allow" && response["decision"] !== "deny") throw new Error("Invalid decision outcome");
|
|
389
|
+
if (deadline <= Date.now()) return { status: "expired" };
|
|
389
390
|
if (this.observed?.version !== snapshot.version || this.observed.digest !== snapshot.digest) {
|
|
390
391
|
this.observed = { version: snapshot.version, digest: snapshot.digest, at: new Date(now).toISOString() };
|
|
391
392
|
}
|
|
@@ -409,6 +410,7 @@ var DEFAULT_PUBLIC_METHODS = /* @__PURE__ */ new Set([
|
|
|
409
410
|
"tools/list"
|
|
410
411
|
]);
|
|
411
412
|
var DECIDE_UNAVAILABLE_REASONS = {
|
|
413
|
+
expired: "deadline_exceeded",
|
|
412
414
|
timeout: "deadline_exceeded",
|
|
413
415
|
error: "authority_source_unavailable",
|
|
414
416
|
unreachable: "authority_source_unavailable",
|
|
@@ -637,6 +639,17 @@ async function evaluateV2(facts, decide) {
|
|
|
637
639
|
stripped
|
|
638
640
|
);
|
|
639
641
|
}
|
|
642
|
+
if (result.status === "expired") {
|
|
643
|
+
return deny(
|
|
644
|
+
"deadline_exceeded",
|
|
645
|
+
"authorization",
|
|
646
|
+
503,
|
|
647
|
+
"ENFORCE_DECIDE_UNAVAILABLE",
|
|
648
|
+
"Authorization expired before this request could be forwarded. This attempt was not forwarded. Obtain fresh authorization before retrying; do not automatically retry operations that may already have executed in another attempt.",
|
|
649
|
+
stripped,
|
|
650
|
+
"not_safely_decided"
|
|
651
|
+
);
|
|
652
|
+
}
|
|
640
653
|
const reason = DECIDE_UNAVAILABLE_REASONS[result.status] ?? "authority_source_unavailable";
|
|
641
654
|
return deny(
|
|
642
655
|
reason,
|
package/dist/index.js
CHANGED
package/dist/server.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mudraid/sidecar",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Customer-hosted MudraID enforcement proxy with authenticated configuration and signed decisions.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
"node": ">=20"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@types/node": "20.
|
|
25
|
-
"
|
|
24
|
+
"@types/node": "20.19.43",
|
|
25
|
+
"esbuild": "0.28.2",
|
|
26
|
+
"tsx": "4.23.15",
|
|
26
27
|
"typescript": "5.6.3",
|
|
27
|
-
"vitest": "
|
|
28
|
-
"esbuild": "0.23.1"
|
|
28
|
+
"vitest": "4.1.11"
|
|
29
29
|
},
|
|
30
30
|
"exports": {
|
|
31
31
|
".": "./dist/index.js"
|