@agenticprimitives/agent-profile 1.0.0-alpha.45 → 1.0.0-alpha.47
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 +23 -0
- package/dist/a2a/binding.d.ts +5 -0
- package/dist/a2a/binding.d.ts.map +1 -1
- package/dist/a2a/binding.js +5 -0
- package/dist/a2a/binding.js.map +1 -1
- package/dist/a2a/index.d.ts +1 -0
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +2 -0
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/jws.d.ts.map +1 -1
- package/dist/a2a/jws.js +6 -1
- package/dist/a2a/jws.js.map +1 -1
- package/dist/a2a/onchain-verifier.d.ts +71 -0
- package/dist/a2a/onchain-verifier.d.ts.map +1 -0
- package/dist/a2a/onchain-verifier.js +159 -0
- package/dist/a2a/onchain-verifier.js.map +1 -0
- package/dist/a2a/validation.d.ts +6 -0
- package/dist/a2a/validation.d.ts.map +1 -1
- package/dist/a2a/validation.js +54 -40
- package/dist/a2a/validation.js.map +1 -1
- package/dist/card.d.ts +7 -0
- package/dist/card.d.ts.map +1 -1
- package/dist/card.js +9 -1
- package/dist/card.js.map +1 -1
- package/dist/client.d.ts +13 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +33 -50
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/safe-fetch.d.ts +26 -0
- package/dist/safe-fetch.d.ts.map +1 -0
- package/dist/safe-fetch.js +130 -0
- package/dist/safe-fetch.js.map +1 -0
- package/dist/url-policy.d.ts +34 -0
- package/dist/url-policy.d.ts.map +1 -0
- package/dist/url-policy.js +226 -0
- package/dist/url-policy.js.map +1 -0
- package/package.json +5 -4
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// ONE GUARDED GET FOR A URL THIS PACKAGE DID NOT CHOOSE — spec 445 (audit NAME-7; completes NEW-AP-2).
|
|
2
|
+
//
|
|
3
|
+
// The property, over the whole request: a URL taken from a record, a card or a caller is fetched only if it is
|
|
4
|
+
// public (url-policy.ts), the request cannot be handed on (no redirect is followed), it cannot run long (one
|
|
5
|
+
// deadline over connect + headers + body), it cannot be large (the cap is enforced WHILE reading, and a declared
|
|
6
|
+
// content-length over the cap is refused before a byte is read), the answer says it is JSON, and nothing ambient
|
|
7
|
+
// (cookie, Authorization) rides along. Every refusal is a `ProfileFetchError` with a stable `code`.
|
|
8
|
+
//
|
|
9
|
+
// NOT CLOSED HERE: DNS rebinding between the check and the connection. `fetch` takes a URL, not an address, so
|
|
10
|
+
// the address that was checked cannot be pinned. A deployment with reach to internal services closes that at the
|
|
11
|
+
// transport (an egress proxy / resolver that refuses private answers), not in this file.
|
|
12
|
+
import { checkPublicUrl } from './url-policy.js';
|
|
13
|
+
export class ProfileFetchError extends Error {
|
|
14
|
+
code;
|
|
15
|
+
constructor(code, detail) {
|
|
16
|
+
// "SSRF guard" is kept in the URL refusal: callers and tests match on it since NEW-AP-2.
|
|
17
|
+
super(`[agent-profile] fetch refused (${code}${code === 'url_refused' ? ' — SSRF guard' : ''}): ${detail}`);
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.name = 'ProfileFetchError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export const DEFAULT_FETCH_TIMEOUT_MS = 5_000;
|
|
23
|
+
export const DEFAULT_FETCH_MAX_BYTES = 256 * 1024;
|
|
24
|
+
const JSON_TYPE = /^application\/(?:[a-z0-9.!#$&^_-]+\+)?json$/i;
|
|
25
|
+
function positive(n, fallback, what) {
|
|
26
|
+
if (n === undefined)
|
|
27
|
+
return fallback;
|
|
28
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
29
|
+
throw new RangeError(`[agent-profile] ${what} must be a positive number`);
|
|
30
|
+
return n;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* GET `url` and return its body as text, under the property stated at the top of this file. Throws
|
|
34
|
+
* `ProfileFetchError`; never returns a partial body.
|
|
35
|
+
*/
|
|
36
|
+
export async function fetchPublicJsonText(url, opts = {}) {
|
|
37
|
+
const timeoutMs = positive(opts.timeoutMs, DEFAULT_FETCH_TIMEOUT_MS, 'timeoutMs');
|
|
38
|
+
const maxBytes = positive(opts.maxBytes, DEFAULT_FETCH_MAX_BYTES, 'maxBytes');
|
|
39
|
+
const fetcher = opts.fetch ?? globalThis.fetch.bind(globalThis);
|
|
40
|
+
// 1. The URL, before anything touches the network.
|
|
41
|
+
const decision = await checkPublicUrl(url, { policy: opts.policy, resolveHost: opts.resolveHost });
|
|
42
|
+
if (!decision.allow)
|
|
43
|
+
throw new ProfileFetchError('url_refused', decision.reason);
|
|
44
|
+
// 2. One deadline. The signal asks the transport to stop; the race makes the deadline hold even over a
|
|
45
|
+
// fetch (or a body) that ignores the signal.
|
|
46
|
+
const controller = new AbortController();
|
|
47
|
+
let timer;
|
|
48
|
+
const deadline = new Promise((_, reject) => {
|
|
49
|
+
timer = setTimeout(() => {
|
|
50
|
+
controller.abort();
|
|
51
|
+
reject(new ProfileFetchError('timeout', `no complete response within ${timeoutMs} ms`));
|
|
52
|
+
}, timeoutMs);
|
|
53
|
+
});
|
|
54
|
+
const within = (p) => Promise.race([p, deadline]);
|
|
55
|
+
let reader;
|
|
56
|
+
try {
|
|
57
|
+
const init = {
|
|
58
|
+
method: 'GET',
|
|
59
|
+
// A public host may not hand the request on to a private one. `manual`, not `error`: workerd rejects
|
|
60
|
+
// `redirect: 'error'` with a TypeError, which would fail every fetch on Workers (COR-5). The check below
|
|
61
|
+
// refuses any 3xx, a followed redirect and an opaque redirect, so nothing is ever followed.
|
|
62
|
+
redirect: 'manual',
|
|
63
|
+
signal: controller.signal,
|
|
64
|
+
headers: { accept: 'application/json' }, // the ONLY header: no Authorization, no cookie
|
|
65
|
+
};
|
|
66
|
+
// Only a browser has an ambient cookie jar; say `omit` there. (Server runtimes send none, and some refuse
|
|
67
|
+
// the field outright.)
|
|
68
|
+
if (typeof document !== 'undefined')
|
|
69
|
+
init.credentials = 'omit';
|
|
70
|
+
let response;
|
|
71
|
+
try {
|
|
72
|
+
response = await within(fetcher(url, init));
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
if (e instanceof ProfileFetchError)
|
|
76
|
+
throw e;
|
|
77
|
+
// A network failure. No detail from the far side.
|
|
78
|
+
throw new ProfileFetchError('network_error', 'the request failed');
|
|
79
|
+
}
|
|
80
|
+
// 3. Under `manual` a redirect arrives as a 3xx (server runtimes) or an opaque redirect (browsers); a fetch that
|
|
81
|
+
// followed one anyway reports `redirected`. Each is refused; nothing is ever followed.
|
|
82
|
+
if (response.redirected || (response.status >= 300 && response.status < 400) || response.type === 'opaqueredirect') {
|
|
83
|
+
throw new ProfileFetchError('redirect_refused', `the server redirected (HTTP ${response.status}); redirects are not followed`);
|
|
84
|
+
}
|
|
85
|
+
if (!response.ok)
|
|
86
|
+
throw new ProfileFetchError('http_error', `HTTP ${response.status}`);
|
|
87
|
+
const type = (response.headers.get('content-type') ?? '').split(';')[0].trim();
|
|
88
|
+
if (!JSON_TYPE.test(type))
|
|
89
|
+
throw new ProfileFetchError('not_json', `content-type "${type || '(none)'}" is not JSON`);
|
|
90
|
+
// 4. Size: the declared length first (refuse before reading), then the bytes as they arrive.
|
|
91
|
+
const declared = response.headers.get('content-length');
|
|
92
|
+
if (declared !== null && /^\d+$/.test(declared.trim()) && Number(declared) > maxBytes) {
|
|
93
|
+
throw new ProfileFetchError('too_large', `content-length ${declared.trim()} exceeds the ${maxBytes}-byte cap`);
|
|
94
|
+
}
|
|
95
|
+
if (!response.body)
|
|
96
|
+
throw new ProfileFetchError('no_body', 'the response has no readable body');
|
|
97
|
+
reader = response.body.getReader();
|
|
98
|
+
const chunks = [];
|
|
99
|
+
let total = 0;
|
|
100
|
+
for (;;) {
|
|
101
|
+
const { done, value } = await within(reader.read());
|
|
102
|
+
if (done)
|
|
103
|
+
break;
|
|
104
|
+
total += value.byteLength;
|
|
105
|
+
if (total > maxBytes)
|
|
106
|
+
throw new ProfileFetchError('too_large', `the body exceeds the ${maxBytes}-byte cap`);
|
|
107
|
+
chunks.push(value);
|
|
108
|
+
}
|
|
109
|
+
const all = new Uint8Array(total);
|
|
110
|
+
let at = 0;
|
|
111
|
+
for (const c of chunks) {
|
|
112
|
+
all.set(c, at);
|
|
113
|
+
at += c.byteLength;
|
|
114
|
+
}
|
|
115
|
+
return new TextDecoder('utf-8', { fatal: false }).decode(all);
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
// Stop the transfer on ANY refusal — the cap and the deadline abort, they do not merely stop listening.
|
|
119
|
+
controller.abort();
|
|
120
|
+
if (reader)
|
|
121
|
+
void reader.cancel().catch(() => undefined);
|
|
122
|
+
throw e;
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
if (timer !== undefined)
|
|
126
|
+
clearTimeout(timer);
|
|
127
|
+
deadline.catch(() => undefined);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=safe-fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-fetch.js","sourceRoot":"","sources":["../src/safe-fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** The policy's answer. A refusal says why, in words fit for an error message. */
|
|
2
|
+
export type PublicUrlDecision = {
|
|
3
|
+
allow: true;
|
|
4
|
+
} | {
|
|
5
|
+
allow: false;
|
|
6
|
+
reason: string;
|
|
7
|
+
};
|
|
8
|
+
/** The port: a synchronous judgement of one URL. `defaultPublicUrlPolicy` is the shipped one. */
|
|
9
|
+
export type PublicUrlPolicy = (url: string) => PublicUrlDecision;
|
|
10
|
+
/** Optional port: the addresses a host name resolves to (A and AAAA), as IP literals. */
|
|
11
|
+
export type PublicHostResolver = (host: string) => Promise<string[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Why an IP literal is not a public destination — `null` when it is public, a reason when it is refused, and
|
|
14
|
+
* a reason too when the string is not an IP literal at all (a resolver that answers with something else has
|
|
15
|
+
* not answered). Brackets around an IPv6 literal are accepted.
|
|
16
|
+
*/
|
|
17
|
+
export declare function publicAddressRefusal(address: string): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* THE SHIPPED POLICY (spec 445; the same rule as a2a's push policy, spec 445 §3.5). Pure and synchronous: it judges the URL as written.
|
|
20
|
+
* Allows only an `https:` URL with no credentials whose host is a public IP literal or a name that is not
|
|
21
|
+
* local by construction.
|
|
22
|
+
*/
|
|
23
|
+
export declare function defaultPublicUrlPolicy(url: string): PublicUrlDecision;
|
|
24
|
+
/**
|
|
25
|
+
* The whole check, run before every outbound request to a URL this package did not choose: the policy
|
|
26
|
+
* first; then, when the deployment can resolve names, EVERY address the host resolves to must be public. A
|
|
27
|
+
* host that resolves to nothing, or a resolver that fails, is a refusal — never "unknown, so allowed".
|
|
28
|
+
* An IP-literal host is already judged by the policy and is not resolved.
|
|
29
|
+
*/
|
|
30
|
+
export declare function checkPublicUrl(url: string, ports?: {
|
|
31
|
+
policy?: PublicUrlPolicy;
|
|
32
|
+
resolveHost?: PublicHostResolver;
|
|
33
|
+
}): Promise<PublicUrlDecision>;
|
|
34
|
+
//# sourceMappingURL=url-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-policy.d.ts","sourceRoot":"","sources":["../src/url-policy.ts"],"names":[],"mappings":"AAyBA,kFAAkF;AAClF,MAAM,MAAM,iBAAiB,GAAG;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,iGAAiG;AACjG,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,iBAAiB,CAAC;AAEjE,yFAAyF;AACzF,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAiFrE;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOnE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CA0BrE;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE;IAAE,MAAM,CAAC,EAAE,eAAe,CAAC;IAAC,WAAW,CAAC,EAAE,kBAAkB,CAAA;CAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAcxJ"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// WHERE THIS PACKAGE MAY SEND A REQUEST — spec 445 (audit NAME-7; completes ledger NEW-AP-2).
|
|
2
|
+
//
|
|
3
|
+
// A profile's metadata URI is ON-CHAIN STATE THE AGENT WROTE ABOUT ITSELF. Whoever fetches it (an indexer, a
|
|
4
|
+
// Worker) lends the agent its network position: cloud metadata at 169.254.169.254, a loopback admin port, a
|
|
5
|
+
// private service. So a URL that came from a record, a card or a caller is fetched only when it is PUBLIC.
|
|
6
|
+
//
|
|
7
|
+
// THE RULE: `https:` only; no credentials in the URL; no IP literal in a loopback, link-local, private, CGNAT,
|
|
8
|
+
// unspecified, multicast or reserved range — in any spelling, including an IPv4 address carried inside an IPv6
|
|
9
|
+
// one (mapped, compatible, NAT64, 6to4) and a numeric host the URL parser did not canonicalize; no name that is
|
|
10
|
+
// local by construction (`localhost`, `*.localhost`, `*.local`, `*.internal`).
|
|
11
|
+
//
|
|
12
|
+
// PURE: no I/O, no DNS. A name that RESOLVES to a refused range is a second question, answered by
|
|
13
|
+
// `checkPublicUrl` when a deployment supplies a resolver (every address must pass; none, or a failed lookup, is
|
|
14
|
+
// a refusal). What neither closes: a name re-resolved to a different address between this check and the
|
|
15
|
+
// connection (DNS rebinding) — that needs the transport to pin the checked address, which a fetch-shaped port
|
|
16
|
+
// cannot say. Redirects are refused at the request (`redirect: 'manual'` plus a refusal of any 3xx, see safe-fetch.ts), so a public address
|
|
17
|
+
// cannot hand the request on to a private one.
|
|
18
|
+
//
|
|
19
|
+
// DUPLICATE — UNIFY IN A FOLLOW-UP. This is the same policy as `packages/a2a/src/standard/push-url-policy.ts`
|
|
20
|
+
// (written the same day, 2026-11-10), copied because `agent-profile` must not depend on `a2a` and the a2a file
|
|
21
|
+
// was not ours to move. Two copies of a security table drift. The policy is pure, dependency-free and names no
|
|
22
|
+
// transport, so under the repo's boundary rules it can live in `@agenticprimitives/types` (the transport-agnostic
|
|
23
|
+
// base both packages already depend on) — as its own module/subpath there — and both copies become re-exports.
|
|
24
|
+
// Until then: a change to one table is a change to both, and both test tables.
|
|
25
|
+
const refuse = (reason) => ({ allow: false, reason });
|
|
26
|
+
const ALLOW = { allow: true };
|
|
27
|
+
/** Four octets from a strict dotted quad, else null. The URL parser has already normalized the odd
|
|
28
|
+
* spellings (`0x7f.1`, `2130706433`, `017700000001`) to this form for an https URL. */
|
|
29
|
+
function parseIpv4(s) {
|
|
30
|
+
const m = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(s);
|
|
31
|
+
if (!m)
|
|
32
|
+
return null;
|
|
33
|
+
const o = [Number(m[1]), Number(m[2]), Number(m[3]), Number(m[4])];
|
|
34
|
+
return o.every((n) => n <= 255) ? o : null;
|
|
35
|
+
}
|
|
36
|
+
/** Eight 16-bit groups from an IPv6 literal (no brackets, zone id dropped), else null. Handles `::` and a
|
|
37
|
+
* dotted IPv4 tail. */
|
|
38
|
+
function parseIpv6(input) {
|
|
39
|
+
let s = input;
|
|
40
|
+
const zone = s.indexOf('%');
|
|
41
|
+
if (zone >= 0)
|
|
42
|
+
s = s.slice(0, zone);
|
|
43
|
+
if (!s.includes(':') || !/^[0-9a-f:.]+$/i.test(s))
|
|
44
|
+
return null;
|
|
45
|
+
const tail = /(^|:)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/.exec(s);
|
|
46
|
+
if (tail) {
|
|
47
|
+
const v4 = parseIpv4(tail[2]);
|
|
48
|
+
if (!v4)
|
|
49
|
+
return null;
|
|
50
|
+
s = `${s.slice(0, s.length - tail[2].length)}${((v4[0] << 8) | v4[1]).toString(16)}:${((v4[2] << 8) | v4[3]).toString(16)}`;
|
|
51
|
+
}
|
|
52
|
+
if (s.includes('.'))
|
|
53
|
+
return null;
|
|
54
|
+
const halves = s.split('::');
|
|
55
|
+
if (halves.length > 2)
|
|
56
|
+
return null;
|
|
57
|
+
const groups = (part) => {
|
|
58
|
+
if (part === '')
|
|
59
|
+
return [];
|
|
60
|
+
const out = [];
|
|
61
|
+
for (const g of part.split(':')) {
|
|
62
|
+
if (!/^[0-9a-f]{1,4}$/i.test(g))
|
|
63
|
+
return null;
|
|
64
|
+
out.push(parseInt(g, 16));
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
};
|
|
68
|
+
const head = groups(halves[0]);
|
|
69
|
+
const rest = halves.length === 2 ? groups(halves[1]) : [];
|
|
70
|
+
if (!head || !rest)
|
|
71
|
+
return null;
|
|
72
|
+
if (halves.length === 1)
|
|
73
|
+
return head.length === 8 ? head : null;
|
|
74
|
+
const fill = 8 - head.length - rest.length;
|
|
75
|
+
if (fill < 1)
|
|
76
|
+
return null;
|
|
77
|
+
return [...head, ...new Array(fill).fill(0), ...rest];
|
|
78
|
+
}
|
|
79
|
+
/** Why an IPv4 address is not a public destination, or null when it is. */
|
|
80
|
+
function ipv4Refusal(o) {
|
|
81
|
+
const [a, b] = o;
|
|
82
|
+
if (a === 0)
|
|
83
|
+
return 'an unspecified ("this network") address';
|
|
84
|
+
if (a === 127)
|
|
85
|
+
return 'a loopback address';
|
|
86
|
+
if (a === 10)
|
|
87
|
+
return 'a private address (10.0.0.0/8)';
|
|
88
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
89
|
+
return 'a private address (172.16.0.0/12)';
|
|
90
|
+
if (a === 192 && b === 168)
|
|
91
|
+
return 'a private address (192.168.0.0/16)';
|
|
92
|
+
if (a === 169 && b === 254)
|
|
93
|
+
return 'a link-local address (169.254.0.0/16)';
|
|
94
|
+
if (a === 100 && b >= 64 && b <= 127)
|
|
95
|
+
return 'a carrier-grade NAT address (100.64.0.0/10)';
|
|
96
|
+
if (a >= 224)
|
|
97
|
+
return 'a multicast or reserved address';
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
/** Why an IPv6 address is not a public destination, or null when it is. An address that CARRIES an IPv4
|
|
101
|
+
* one (mapped `::ffff:a.b.c.d`, the deprecated compatible `::a.b.c.d`, NAT64 `64:ff9b::/96`, 6to4
|
|
102
|
+
* `2002::/16`) is judged by the IPv4 address it reaches. */
|
|
103
|
+
function ipv6Refusal(g) {
|
|
104
|
+
const zeros = (n) => g.slice(0, n).every((x) => x === 0);
|
|
105
|
+
const embedded = (hi, lo, what) => {
|
|
106
|
+
const r = ipv4Refusal([hi >> 8, hi & 0xff, lo >> 8, lo & 0xff]);
|
|
107
|
+
return r ? `${what} for ${r}` : null;
|
|
108
|
+
};
|
|
109
|
+
if (zeros(8))
|
|
110
|
+
return 'the unspecified address (::)';
|
|
111
|
+
if (zeros(7) && g[7] === 1)
|
|
112
|
+
return 'a loopback address (::1)';
|
|
113
|
+
if (zeros(5) && g[5] === 0xffff)
|
|
114
|
+
return embedded(g[6], g[7], 'an IPv4-mapped IPv6 form');
|
|
115
|
+
if (zeros(6))
|
|
116
|
+
return embedded(g[6], g[7], 'an IPv4-compatible IPv6 form') ?? 'an IPv4-compatible IPv6 address';
|
|
117
|
+
if (g[0] === 0x64 && g[1] === 0xff9b && g.slice(2, 6).every((x) => x === 0))
|
|
118
|
+
return embedded(g[6], g[7], 'a NAT64 form');
|
|
119
|
+
if (g[0] === 0x2002)
|
|
120
|
+
return embedded(g[1], g[2], 'a 6to4 form');
|
|
121
|
+
if ((g[0] & 0xffc0) === 0xfe80)
|
|
122
|
+
return 'a link-local address (fe80::/10)';
|
|
123
|
+
if ((g[0] & 0xffc0) === 0xfec0)
|
|
124
|
+
return 'a site-local address (fec0::/10)';
|
|
125
|
+
if ((g[0] & 0xfe00) === 0xfc00)
|
|
126
|
+
return 'a private address (fc00::/7)';
|
|
127
|
+
if ((g[0] & 0xff00) === 0xff00)
|
|
128
|
+
return 'a multicast address (ff00::/8)';
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Why an IP literal is not a public destination — `null` when it is public, a reason when it is refused, and
|
|
133
|
+
* a reason too when the string is not an IP literal at all (a resolver that answers with something else has
|
|
134
|
+
* not answered). Brackets around an IPv6 literal are accepted.
|
|
135
|
+
*/
|
|
136
|
+
export function publicAddressRefusal(address) {
|
|
137
|
+
const s = address.trim().toLowerCase().replace(/^\[(.*)\]$/, '$1');
|
|
138
|
+
const v4 = parseIpv4(s);
|
|
139
|
+
if (v4)
|
|
140
|
+
return ipv4Refusal(v4);
|
|
141
|
+
const v6 = parseIpv6(s);
|
|
142
|
+
if (v6)
|
|
143
|
+
return ipv6Refusal(v6);
|
|
144
|
+
return 'not an IP address';
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* THE SHIPPED POLICY (spec 445; the same rule as a2a's push policy, spec 445 §3.5). Pure and synchronous: it judges the URL as written.
|
|
148
|
+
* Allows only an `https:` URL with no credentials whose host is a public IP literal or a name that is not
|
|
149
|
+
* local by construction.
|
|
150
|
+
*/
|
|
151
|
+
export function defaultPublicUrlPolicy(url) {
|
|
152
|
+
let u;
|
|
153
|
+
try {
|
|
154
|
+
u = new URL(url);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return refuse('the URL is not a valid absolute URL');
|
|
158
|
+
}
|
|
159
|
+
if (u.protocol !== 'https:')
|
|
160
|
+
return refuse(`the URL must be https: (got ${u.protocol})`);
|
|
161
|
+
if (u.username || u.password)
|
|
162
|
+
return refuse('the URL must not carry credentials (user:password@)');
|
|
163
|
+
const host = u.hostname.toLowerCase().replace(/\.$/, '');
|
|
164
|
+
if (!host)
|
|
165
|
+
return refuse('the URL names no host');
|
|
166
|
+
if (host.startsWith('[') || host.includes(':')) {
|
|
167
|
+
const g = parseIpv6(host.replace(/^\[(.*)\]$/, '$1'));
|
|
168
|
+
if (!g)
|
|
169
|
+
return refuse('the URL host is not a valid IPv6 address');
|
|
170
|
+
const why = ipv6Refusal(g);
|
|
171
|
+
return why ? refuse(`the URL host is ${why}`) : ALLOW;
|
|
172
|
+
}
|
|
173
|
+
const v4 = parseIpv4(host);
|
|
174
|
+
if (v4) {
|
|
175
|
+
const why = ipv4Refusal(v4);
|
|
176
|
+
return why ? refuse(`the URL host is ${why}`) : ALLOW;
|
|
177
|
+
}
|
|
178
|
+
// A host whose last label is a number is an IPv4 address in some spelling (WHATWG "ends in a number").
|
|
179
|
+
// A parser that normalized it was handled above; one that did not must not let it through as a name.
|
|
180
|
+
const last = host.slice(host.lastIndexOf('.') + 1);
|
|
181
|
+
if (/^(\d+|0x[0-9a-f]*)$/.test(last))
|
|
182
|
+
return refuse('the URL host is a numeric address in a non-canonical form');
|
|
183
|
+
if (host === 'localhost' || host.endsWith('.localhost'))
|
|
184
|
+
return refuse('the URL host is localhost');
|
|
185
|
+
if (host.endsWith('.local') || host === 'local')
|
|
186
|
+
return refuse('the URL host is a local (.local) name');
|
|
187
|
+
if (host.endsWith('.internal') || host === 'internal')
|
|
188
|
+
return refuse('the URL host is an internal (.internal) name');
|
|
189
|
+
return ALLOW;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* The whole check, run before every outbound request to a URL this package did not choose: the policy
|
|
193
|
+
* first; then, when the deployment can resolve names, EVERY address the host resolves to must be public. A
|
|
194
|
+
* host that resolves to nothing, or a resolver that fails, is a refusal — never "unknown, so allowed".
|
|
195
|
+
* An IP-literal host is already judged by the policy and is not resolved.
|
|
196
|
+
*/
|
|
197
|
+
export async function checkPublicUrl(url, ports = {}) {
|
|
198
|
+
const decision = (ports.policy ?? defaultPublicUrlPolicy)(url);
|
|
199
|
+
if (!decision.allow || !ports.resolveHost)
|
|
200
|
+
return decision;
|
|
201
|
+
let host;
|
|
202
|
+
try {
|
|
203
|
+
host = new URL(url).hostname.toLowerCase().replace(/\.$/, '');
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return refuse('the URL is not a valid absolute URL');
|
|
207
|
+
}
|
|
208
|
+
if (host.startsWith('[') || parseIpv4(host))
|
|
209
|
+
return decision;
|
|
210
|
+
let addresses;
|
|
211
|
+
try {
|
|
212
|
+
addresses = await ports.resolveHost(host);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return refuse(`the URL host ${host} could not be resolved`);
|
|
216
|
+
}
|
|
217
|
+
if (!Array.isArray(addresses) || addresses.length === 0)
|
|
218
|
+
return refuse(`the URL host ${host} resolves to no address`);
|
|
219
|
+
for (const a of addresses) {
|
|
220
|
+
const why = publicAddressRefusal(String(a));
|
|
221
|
+
if (why)
|
|
222
|
+
return refuse(`the URL host ${host} resolves to ${why}`);
|
|
223
|
+
}
|
|
224
|
+
return decision;
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=url-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-policy.js","sourceRoot":"","sources":["../src/url-policy.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agenticprimitives/agent-profile",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.47",
|
|
4
4
|
"description": "Agent identity SDK: AP-native Canonical Agent Profile (CanonicalAgentProfileV1) + signed profile bundle, CAIP-10 nativeId helpers, endpoint verification methods, and the A2A 1.0 Agent Card model (./a2a: JCS canonical bytes, ES256 JWS, EIP-712 Smart Agent binding, field provenance, pure validation, import, release lifecycle). External registry projections stay outside Ring 0.",
|
|
5
5
|
"homepage": "https://agenticprimitives.dev",
|
|
6
6
|
"bugs": {
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"viem": "^2.52.2",
|
|
55
|
-
"@agenticprimitives/agent-account": "^1.0.0-alpha.
|
|
56
|
-
"@agenticprimitives/connect-auth": "^1.0.0-alpha.
|
|
57
|
-
"@agenticprimitives/types": "^1.0.0-alpha.
|
|
55
|
+
"@agenticprimitives/agent-account": "^1.0.0-alpha.47",
|
|
56
|
+
"@agenticprimitives/connect-auth": "^1.0.0-alpha.47",
|
|
57
|
+
"@agenticprimitives/types": "^1.0.0-alpha.47"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/node": "^22.7.0",
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
"build": "tsc -p tsconfig.build.json",
|
|
82
82
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
83
83
|
"test": "vitest run",
|
|
84
|
+
"test:unit": "vitest run",
|
|
84
85
|
"test:watch": "vitest",
|
|
85
86
|
"clean": "rm -rf dist"
|
|
86
87
|
}
|