@melra/policy-core 0.3.0-alpha.11 → 0.3.0-alpha.13
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 +6 -3
- package/dist/index.d.ts +11 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +236 -62
- package/dist/index.js.map +1 -1
- package/dist/network-policy.d.ts +13 -3
- package/dist/network-policy.d.ts.map +1 -1
- package/dist/network-policy.js +67 -6
- package/dist/network-policy.js.map +1 -1
- package/package.json +3 -3
- package/dist/credentials.test.d.ts +0 -2
- package/dist/credentials.test.d.ts.map +0 -1
- package/dist/credentials.test.js +0 -103
- package/dist/credentials.test.js.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -655
- package/dist/index.test.js.map +0 -1
- package/dist/network-policy.test.d.ts +0 -2
- package/dist/network-policy.test.d.ts.map +0 -1
- package/dist/network-policy.test.js +0 -39
- package/dist/network-policy.test.js.map +0 -1
package/dist/network-policy.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type LookupFunction } from "node:net";
|
|
1
2
|
export declare function isPrivateAddress(address: string): boolean;
|
|
2
3
|
export interface NetworkPolicy {
|
|
3
4
|
allowedDomains: string[];
|
|
@@ -19,10 +20,19 @@ export interface NetworkPolicy {
|
|
|
19
20
|
*/
|
|
20
21
|
export interface SafeDestination {
|
|
21
22
|
url: URL;
|
|
22
|
-
/** The
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
/** The host to connect to: the name, or an IP literal without brackets. */
|
|
24
|
+
host: string;
|
|
25
|
+
/**
|
|
26
|
+
* A `lookup` for `net`/`http`/`https` that answers only with the addresses
|
|
27
|
+
* this check accepted, so the socket never resolves the name again. Every
|
|
28
|
+
* answer is offered, not just the first, so Node can fall back between them:
|
|
29
|
+
* `localhost` answering `::1` first must still reach a server that listens
|
|
30
|
+
* only on 127.0.0.1.
|
|
31
|
+
*/
|
|
32
|
+
lookup: LookupFunction;
|
|
25
33
|
}
|
|
34
|
+
/** The URL's host, lowercased, with an IPv6 literal's brackets removed. */
|
|
35
|
+
export declare function hostOf(url: URL): string;
|
|
26
36
|
export declare function assertSafeDestination(rawUrl: string, policy: NetworkPolicy): Promise<SafeDestination>;
|
|
27
37
|
export declare function assertSafeUrl(rawUrl: string, policy: NetworkPolicy): Promise<URL>;
|
|
28
38
|
//# sourceMappingURL=network-policy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-policy.d.ts","sourceRoot":"","sources":["../src/network-policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"network-policy.d.ts","sourceRoot":"","sources":["../src/network-policy.ts"],"names":[],"mappings":"AAGA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAmErD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsCzD;AASD,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAWD;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,GAAG,CAAC;IACT,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,MAAM,EAAE,cAAc,CAAC;CACxB;AAcD,2EAA2E;AAC3E,wBAAgB,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAEvC;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,eAAe,CAAC,CA8C1B;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,GAAG,CAAC,CAEd"}
|
package/dist/network-policy.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright 2026 XAGI Labs Private Limited
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import { isIP } from "node:net";
|
|
4
|
+
import { lookup as dnsLookup } from "node:dns";
|
|
4
5
|
import { lookup } from "node:dns/promises";
|
|
5
6
|
function ipv4Number(address) {
|
|
6
7
|
return address
|
|
@@ -32,6 +33,40 @@ function mappedIpv4Address(address) {
|
|
|
32
33
|
low & 0xff,
|
|
33
34
|
].join(".");
|
|
34
35
|
}
|
|
36
|
+
/** The eight 16-bit groups of an IPv6 address, an embedded IPv4 tail included. */
|
|
37
|
+
function ipv6Groups(address) {
|
|
38
|
+
let text = address.toLowerCase();
|
|
39
|
+
// The dotted tail, if any, found without a regular expression: one that
|
|
40
|
+
// backtracks on long digit runs is a way to stall the destination check.
|
|
41
|
+
const tail = text.slice(text.lastIndexOf(":") + 1);
|
|
42
|
+
if (isIP(tail) === 4) {
|
|
43
|
+
const [a, b, c, d] = tail.split(".").map(Number);
|
|
44
|
+
text = `${text.slice(0, -tail.length)}${((a << 8) | b).toString(16)}:${((c << 8) | d).toString(16)}`;
|
|
45
|
+
}
|
|
46
|
+
const [head = "", rest] = text.split("::");
|
|
47
|
+
const left = head === "" ? [] : head.split(":");
|
|
48
|
+
const right = rest === undefined || rest === "" ? [] : rest.split(":");
|
|
49
|
+
const missing = 8 - left.length - right.length;
|
|
50
|
+
if (missing < 0 || (rest === undefined && missing !== 0))
|
|
51
|
+
return undefined;
|
|
52
|
+
return [...left, ...Array(missing).fill("0"), ...right].map((group) => Number.parseInt(group, 16));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The IPv4 address a NAT64 address stands for, or whether it is a local-use
|
|
56
|
+
* translation (RFC 8215 `64:ff9b:1::/48`), which only ever reaches a private
|
|
57
|
+
* network. `64:ff9b::a00:5` is 10.0.0.5 on a host behind NAT64.
|
|
58
|
+
*/
|
|
59
|
+
function nat64(address) {
|
|
60
|
+
const groups = ipv6Groups(address);
|
|
61
|
+
if (groups === undefined || groups[0] !== 0x64 || groups[1] !== 0xff9b)
|
|
62
|
+
return undefined;
|
|
63
|
+
if (groups[2] === 1)
|
|
64
|
+
return { localUse: true };
|
|
65
|
+
if (groups.slice(2, 6).some((group) => group !== 0))
|
|
66
|
+
return undefined;
|
|
67
|
+
const [high, low] = [groups[6], groups[7]];
|
|
68
|
+
return { ipv4: [high >>> 8, high & 0xff, low >>> 8, low & 0xff].join("."), localUse: false };
|
|
69
|
+
}
|
|
35
70
|
export function isPrivateAddress(address) {
|
|
36
71
|
const version = isIP(address);
|
|
37
72
|
if (version === 4) {
|
|
@@ -54,6 +89,10 @@ export function isPrivateAddress(address) {
|
|
|
54
89
|
const mapped = mappedIpv4Address(normalized);
|
|
55
90
|
if (mapped !== undefined)
|
|
56
91
|
return isPrivateAddress(mapped);
|
|
92
|
+
const translated = nat64(normalized);
|
|
93
|
+
if (translated !== undefined) {
|
|
94
|
+
return translated.localUse || isPrivateAddress(translated.ipv4);
|
|
95
|
+
}
|
|
57
96
|
return (normalized === "::" ||
|
|
58
97
|
normalized === "::1" ||
|
|
59
98
|
normalized.startsWith("fc") ||
|
|
@@ -78,19 +117,42 @@ function domainAllowed(host, allowed) {
|
|
|
78
117
|
host === entry.toLowerCase() ||
|
|
79
118
|
host.endsWith(`.${entry.toLowerCase()}`));
|
|
80
119
|
}
|
|
120
|
+
function pinnedLookup(addresses) {
|
|
121
|
+
const answers = addresses.map((address) => ({ address, family: isIP(address) }));
|
|
122
|
+
return (_hostname, options, callback) => {
|
|
123
|
+
const family = { IPv4: 4, IPv6: 6 }[String(options.family)] ?? options.family;
|
|
124
|
+
const wanted = answers.filter((answer) => !family || answer.family === family);
|
|
125
|
+
if (wanted.length === 0) {
|
|
126
|
+
callback(Object.assign(new Error("destination_no_address"), { code: "ENOTFOUND" }), "", 0);
|
|
127
|
+
}
|
|
128
|
+
else if (options.all)
|
|
129
|
+
callback(null, wanted);
|
|
130
|
+
else
|
|
131
|
+
callback(null, wanted[0].address, wanted[0].family);
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/** The URL's host, lowercased, with an IPv6 literal's brackets removed. */
|
|
135
|
+
export function hostOf(url) {
|
|
136
|
+
return url.hostname.toLowerCase().replace(/^\[(.*)\]$/, "$1");
|
|
137
|
+
}
|
|
81
138
|
export async function assertSafeDestination(rawUrl, policy) {
|
|
82
139
|
const url = new URL(rawUrl);
|
|
83
140
|
// Unhinged mode still parses the URL — a value the browser cannot navigate to
|
|
84
141
|
// is a bug either way — but asserts nothing about where it points.
|
|
85
142
|
if (policy.unhinged)
|
|
86
|
-
return { url,
|
|
143
|
+
return { url, host: hostOf(url), lookup: dnsLookup };
|
|
87
144
|
if (!["http:", "https:"].includes(url.protocol)) {
|
|
88
145
|
throw new Error("destination_protocol_not_allowed");
|
|
89
146
|
}
|
|
90
147
|
if (url.username !== "" || url.password !== "") {
|
|
91
148
|
throw new Error("destination_credentials_not_allowed");
|
|
92
149
|
}
|
|
93
|
-
|
|
150
|
+
// WHATWG URL keeps an IPv6 literal's brackets in `hostname` ("[::1]"), and
|
|
151
|
+
// `isIP("[::1]")` is 0, so without this an IPv6 address was treated as a name:
|
|
152
|
+
// the private-range check below never ran, and the request only failed because
|
|
153
|
+
// DNS cannot resolve a bracketed string. Strip them so it is checked as the
|
|
154
|
+
// address it is.
|
|
155
|
+
const host = hostOf(url);
|
|
94
156
|
const localName = host === "localhost" || host.endsWith(".localhost");
|
|
95
157
|
if (localName && !policy.allowLocalhost) {
|
|
96
158
|
throw new Error("destination_private_blocked");
|
|
@@ -103,7 +165,7 @@ export async function assertSafeDestination(rawUrl, policy) {
|
|
|
103
165
|
!(policy.allowLocalhost && isLoopbackAddress(host))) {
|
|
104
166
|
throw new Error("destination_private_blocked");
|
|
105
167
|
}
|
|
106
|
-
return { url,
|
|
168
|
+
return { url, host, lookup: pinnedLookup([host]) };
|
|
107
169
|
}
|
|
108
170
|
const addresses = await lookup(host, { all: true, verbatim: true });
|
|
109
171
|
if (addresses.length === 0 ||
|
|
@@ -111,9 +173,8 @@ export async function assertSafeDestination(rawUrl, policy) {
|
|
|
111
173
|
!(policy.allowLocalhost && isLoopbackAddress(item.address)))) {
|
|
112
174
|
throw new Error("destination_private_blocked");
|
|
113
175
|
}
|
|
114
|
-
// Every answer passed, so
|
|
115
|
-
|
|
116
|
-
return { url, address: addresses[0].address };
|
|
176
|
+
// Every answer passed, so all of them are safe to pin, in the resolver's order.
|
|
177
|
+
return { url, host, lookup: pinnedLookup(addresses.map((item) => item.address)) };
|
|
117
178
|
}
|
|
118
179
|
export async function assertSafeUrl(rawUrl, policy) {
|
|
119
180
|
return (await assertSafeDestination(rawUrl, policy)).url;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-policy.js","sourceRoot":"","sources":["../src/network-policy.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,sCAAsC;AAEtC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"network-policy.js","sourceRoot":"","sources":["../src/network-policy.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@melra/policy-core",
|
|
3
|
-
"version": "0.3.0-alpha.
|
|
3
|
+
"version": "0.3.0-alpha.13",
|
|
4
4
|
"description": "Policy evaluation and scoped approval primitives for MELRA.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
"dist"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@melra/protocol": "0.3.0-alpha.
|
|
24
|
+
"@melra/protocol": "0.3.0-alpha.13"
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build": "tsc -p tsconfig.json",
|
|
28
28
|
"clean": "rm -rf dist",
|
|
29
29
|
"test": "vitest run",
|
|
30
|
-
"typecheck": "tsc -p tsconfig.json
|
|
30
|
+
"typecheck": "tsc -p tsconfig.test.json"
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.test.d.ts","sourceRoot":"","sources":["../src/credentials.test.ts"],"names":[],"mappings":""}
|
package/dist/credentials.test.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 XAGI Labs Private Limited
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { chmod, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
4
|
-
import { tmpdir } from "node:os";
|
|
5
|
-
import { join } from "node:path";
|
|
6
|
-
import { afterAll, describe, expect, it } from "vitest";
|
|
7
|
-
import { CredentialsSchema } from "@melra/protocol";
|
|
8
|
-
import { CredentialBroker } from "./credentials.js";
|
|
9
|
-
const roots = [];
|
|
10
|
-
afterAll(async () => {
|
|
11
|
-
for (const root of roots)
|
|
12
|
-
await rm(root, { recursive: true, force: true });
|
|
13
|
-
});
|
|
14
|
-
async function secretFile(mode) {
|
|
15
|
-
const root = await mkdtemp(join(tmpdir(), "melra-credentials-"));
|
|
16
|
-
roots.push(root);
|
|
17
|
-
const path = join(root, "stripe.key");
|
|
18
|
-
await writeFile(path, "sk_live_from_a_file\n");
|
|
19
|
-
await chmod(path, mode);
|
|
20
|
-
return path;
|
|
21
|
-
}
|
|
22
|
-
const stripe = {
|
|
23
|
-
stripe: {
|
|
24
|
-
source: { env: "MELRA_TEST_STRIPE_KEY" },
|
|
25
|
-
inject: { header: "Authorization", scheme: "Bearer" },
|
|
26
|
-
hosts: ["api.stripe.com"],
|
|
27
|
-
capability: "http.post:https://api.stripe.com/v1/refunds*",
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
const broker = (definitions = stripe, environment = { MELRA_TEST_STRIPE_KEY: "sk_live_secret" }) => new CredentialBroker(CredentialsSchema.parse(definitions), environment);
|
|
31
|
-
describe("credential broker", () => {
|
|
32
|
-
it("injects the secret for an operation the delegation covers", async () => {
|
|
33
|
-
const { headers, used } = await broker().headersFor({
|
|
34
|
-
host: "api.stripe.com",
|
|
35
|
-
capability: "http.post",
|
|
36
|
-
target: "https://api.stripe.com/v1/refunds",
|
|
37
|
-
});
|
|
38
|
-
expect(headers.authorization).toBe("Bearer sk_live_secret");
|
|
39
|
-
// The names are what a caller may see. The values are what it may not.
|
|
40
|
-
expect(used).toEqual(["stripe"]);
|
|
41
|
-
});
|
|
42
|
-
it("sends a request to another host unauthenticated rather than refusing it", async () => {
|
|
43
|
-
const { headers, used } = await broker().headersFor({
|
|
44
|
-
host: "api.example.com",
|
|
45
|
-
capability: "http.post",
|
|
46
|
-
target: "https://api.example.com/v1/refunds",
|
|
47
|
-
});
|
|
48
|
-
expect(headers).toEqual({});
|
|
49
|
-
expect(used).toEqual([]);
|
|
50
|
-
});
|
|
51
|
-
it("refuses an operation outside the delegation without reading the secret", async () => {
|
|
52
|
-
// The source points at a file that does not exist. A `credential_source_*`
|
|
53
|
-
// or `ENOENT` here would mean the broker read first and checked second —
|
|
54
|
-
// the refusal has to land before the plaintext is anywhere near the process.
|
|
55
|
-
const refusing = broker({
|
|
56
|
-
stripe: {
|
|
57
|
-
...stripe.stripe,
|
|
58
|
-
source: { file: join(tmpdir(), "melra-nonexistent-credential") },
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
await expect(refusing.headersFor({
|
|
62
|
-
host: "api.stripe.com",
|
|
63
|
-
capability: "http.delete",
|
|
64
|
-
target: "https://api.stripe.com/v1/customers/cus_1",
|
|
65
|
-
})).rejects.toThrow("credential_capability_not_covered:stripe");
|
|
66
|
-
});
|
|
67
|
-
it("reads a mode-0600 file and refuses a permissive one", async () => {
|
|
68
|
-
const path = await secretFile(0o600);
|
|
69
|
-
const request = {
|
|
70
|
-
host: "api.stripe.com",
|
|
71
|
-
capability: "http.post",
|
|
72
|
-
target: "https://api.stripe.com/v1/refunds",
|
|
73
|
-
};
|
|
74
|
-
const definitions = {
|
|
75
|
-
stripe: { ...stripe.stripe, source: { file: path } },
|
|
76
|
-
};
|
|
77
|
-
const { headers } = await broker(definitions).headersFor(request);
|
|
78
|
-
expect(headers.authorization).toBe("Bearer sk_live_from_a_file");
|
|
79
|
-
await chmod(path, 0o644);
|
|
80
|
-
const permissive = broker(definitions).headersFor(request);
|
|
81
|
-
if (process.platform === "win32") {
|
|
82
|
-
// Windows does not carry the mode bits this checks, so the guard cannot
|
|
83
|
-
// fire there. Asserting it would only test the platform.
|
|
84
|
-
await expect(permissive).resolves.toBeDefined();
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
await expect(permissive).rejects.toThrow("credential_file_permissions_too_open");
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
it("fails loudly when the source names nothing", async () => {
|
|
91
|
-
await expect(broker(stripe, {}).headersFor({
|
|
92
|
-
host: "api.stripe.com",
|
|
93
|
-
capability: "http.post",
|
|
94
|
-
target: "https://api.stripe.com/v1/refunds",
|
|
95
|
-
})).rejects.toThrow("credential_source_missing:stripe");
|
|
96
|
-
});
|
|
97
|
-
it("rejects an unknown field in a definition", () => {
|
|
98
|
-
expect(() => CredentialsSchema.parse({
|
|
99
|
-
stripe: { ...stripe.stripe, allowRedirects: true },
|
|
100
|
-
})).toThrow();
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
//# sourceMappingURL=credentials.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.test.js","sourceRoot":"","sources":["../src/credentials.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.test.d.ts
DELETED
package/dist/index.test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
|