@amalgm/core 0.4.3 → 0.4.4
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/PURPOSE.md +2 -0
- package/dist/identity/authorization/dpop.d.ts +6 -0
- package/dist/identity/authorization/dpop.d.ts.map +1 -1
- package/dist/identity/authorization/dpop.js +20 -0
- package/dist/identity/authorization/dpop.js.map +1 -1
- package/docs/authorization.md +6 -4
- package/package.json +1 -1
package/PURPOSE.md
CHANGED
|
@@ -127,6 +127,8 @@ that composes an exact Core release with the other product releases.
|
|
|
127
127
|
credential may mint an audience- and scope-exact access token, but every
|
|
128
128
|
resource request also proves possession of that machine's key; Core owns
|
|
129
129
|
the claims and renewal law while hosts own keys, storage, signing, and HTTP.
|
|
130
|
+
Behind a proxy, the configured public origin is authority for the DPoP URL;
|
|
131
|
+
caller-controlled forwarding headers are not.
|
|
130
132
|
23. **Machine key replacement is an explicit recovery, never startup repair.**
|
|
131
133
|
Ordinary registration may pin an absent key or reuse the same key; replacing
|
|
132
134
|
it requires fresh user approval, proof of the candidate private key, and a
|
|
@@ -17,4 +17,10 @@ export interface DpopSignerPort {
|
|
|
17
17
|
/** RFC 9449 htu excludes query and fragment and uses an absolute URI. */
|
|
18
18
|
export declare function normalizeDpopHtu(value: string): string;
|
|
19
19
|
export declare function normalizeDpopMethod(value: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Reconstruct the public resource URL behind a reverse proxy without trusting
|
|
22
|
+
* caller-controlled forwarding headers. Deployment config owns the origin;
|
|
23
|
+
* the HTTP request contributes only its origin-form path and query.
|
|
24
|
+
*/
|
|
25
|
+
export declare function publicResourceRequestUrl(publicOrigin: string, requestTarget: string): string;
|
|
20
26
|
//# sourceMappingURL=dpop.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dpop.d.ts","sourceRoot":"","sources":["../../../src/identity/authorization/dpop.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACnD;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUtD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzD"}
|
|
1
|
+
{"version":3,"file":"dpop.d.ts","sourceRoot":"","sources":["../../../src/identity/authorization/dpop.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACnD;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUtD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAe5F"}
|
|
@@ -16,4 +16,24 @@ export function normalizeDpopMethod(value) {
|
|
|
16
16
|
throw new TypeError('DPoP method is invalid');
|
|
17
17
|
return method;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Reconstruct the public resource URL behind a reverse proxy without trusting
|
|
21
|
+
* caller-controlled forwarding headers. Deployment config owns the origin;
|
|
22
|
+
* the HTTP request contributes only its origin-form path and query.
|
|
23
|
+
*/
|
|
24
|
+
export function publicResourceRequestUrl(publicOrigin, requestTarget) {
|
|
25
|
+
const origin = new URL(publicOrigin);
|
|
26
|
+
const loopback = origin.hostname === 'localhost' || origin.hostname === '127.0.0.1';
|
|
27
|
+
if ((origin.protocol !== 'https:' && !(loopback && origin.protocol === 'http:'))
|
|
28
|
+
|| origin.username
|
|
29
|
+
|| origin.password
|
|
30
|
+
|| origin.pathname !== '/'
|
|
31
|
+
|| origin.search
|
|
32
|
+
|| origin.hash)
|
|
33
|
+
throw new TypeError('Public resource origin must be an HTTPS origin');
|
|
34
|
+
if (!requestTarget.startsWith('/') || requestTarget.startsWith('//')) {
|
|
35
|
+
throw new TypeError('Resource request target must use origin form');
|
|
36
|
+
}
|
|
37
|
+
return new URL(requestTarget, origin).toString();
|
|
38
|
+
}
|
|
19
39
|
//# sourceMappingURL=dpop.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dpop.js","sourceRoot":"","sources":["../../../src/identity/authorization/dpop.ts"],"names":[],"mappings":"AAmBA,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,SAAS,CAAC,iCAAiC,CAAC,CAAC;IACzD,CAAC;IACD,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;IAClB,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;IAClB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;IAChB,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;IACd,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,wBAAwB,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"dpop.js","sourceRoot":"","sources":["../../../src/identity/authorization/dpop.ts"],"names":[],"mappings":"AAmBA,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,SAAS,CAAC,iCAAiC,CAAC,CAAC;IACzD,CAAC;IACD,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;IAClB,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC;IAClB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;IAChB,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;IACd,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,wBAAwB,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,YAAoB,EAAE,aAAqB;IAClF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,KAAK,WAAW,IAAI,MAAM,CAAC,QAAQ,KAAK,WAAW,CAAC;IACpF,IACE,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;WACzE,MAAM,CAAC,QAAQ;WACf,MAAM,CAAC,QAAQ;WACf,MAAM,CAAC,QAAQ,KAAK,GAAG;WACvB,MAAM,CAAC,MAAM;WACb,MAAM,CAAC,IAAI;QACd,MAAM,IAAI,SAAS,CAAC,gDAAgD,CAAC,CAAC;IACxE,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;AACnD,CAAC"}
|
package/docs/authorization.md
CHANGED
|
@@ -16,14 +16,16 @@ needs.
|
|
|
16
16
|
set, expiry, token id, signing key, and device-key thumbprint.
|
|
17
17
|
3. Every resource request has a fresh DPoP proof bound to its method, URL,
|
|
18
18
|
access token, and machine key.
|
|
19
|
-
4.
|
|
19
|
+
4. A proxied resource reconstructs that URL from its configured public origin
|
|
20
|
+
and the origin-form request target; forwarding headers are not authority.
|
|
21
|
+
5. The broker caches an exact grant, refreshes before expiry with jitter,
|
|
20
22
|
single-flights concurrent renewal, and performs no silent auth fallback.
|
|
21
|
-
|
|
23
|
+
6. Audiences and scopes are closed sets. Adding a consumer changes this module
|
|
22
24
|
and its tests before any issuer or verifier accepts it.
|
|
23
|
-
|
|
25
|
+
7. A machine key is pinned once. Replacement requires an explicit, browser-
|
|
24
26
|
approved recovery bound to the expected old thumbprint and a different
|
|
25
27
|
candidate key; retrying an already completed replacement is idempotent.
|
|
26
|
-
|
|
28
|
+
8. Provider access is memory-only. Registration and machine resume never
|
|
27
29
|
persist an access token, DPoP proof, or provider proxy credential; resume
|
|
28
30
|
removes retired proxy and HMAC fields left by older installations.
|
|
29
31
|
|
package/package.json
CHANGED