@astrale-os/sdk 0.1.1 → 0.1.3
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/dist/auth/authenticate.d.ts +24 -0
- package/dist/auth/authenticate.d.ts.map +1 -0
- package/dist/auth/authenticate.js +29 -0
- package/dist/auth/authenticate.js.map +1 -0
- package/dist/auth/check.d.ts +39 -0
- package/dist/auth/check.d.ts.map +1 -0
- package/dist/auth/check.js +54 -0
- package/dist/auth/check.js.map +1 -0
- package/dist/auth/compose.d.ts +41 -0
- package/dist/auth/compose.d.ts.map +1 -0
- package/dist/auth/compose.js +45 -0
- package/dist/auth/compose.js.map +1 -0
- package/dist/auth/errors.d.ts +16 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/errors.js +26 -0
- package/dist/auth/errors.js.map +1 -0
- package/dist/auth/identity.d.ts +16 -0
- package/dist/auth/identity.d.ts.map +1 -0
- package/dist/auth/identity.js +2 -0
- package/dist/auth/identity.js.map +1 -0
- package/dist/auth/index.d.ts +12 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +9 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/kernel-client.d.ts +43 -0
- package/dist/auth/kernel-client.d.ts.map +1 -0
- package/dist/auth/kernel-client.js +146 -0
- package/dist/auth/kernel-client.js.map +1 -0
- package/dist/auth/resolve.d.ts +19 -0
- package/dist/auth/resolve.d.ts.map +1 -0
- package/dist/auth/resolve.js +43 -0
- package/dist/auth/resolve.js.map +1 -0
- package/dist/auth/sign.d.ts +15 -0
- package/dist/auth/sign.d.ts.map +1 -0
- package/dist/auth/sign.js +24 -0
- package/dist/auth/sign.js.map +1 -0
- package/dist/auth/verify.d.ts +26 -0
- package/dist/auth/verify.d.ts.map +1 -0
- package/dist/auth/verify.js +96 -0
- package/dist/auth/verify.js.map +1 -0
- package/dist/define/index.d.ts +5 -0
- package/dist/define/index.d.ts.map +1 -0
- package/dist/define/index.js +3 -0
- package/dist/define/index.js.map +1 -0
- package/dist/define/remote-function.d.ts +96 -0
- package/dist/define/remote-function.d.ts.map +1 -0
- package/dist/define/remote-function.js +25 -0
- package/dist/define/remote-function.js.map +1 -0
- package/dist/define/view.d.ts +86 -0
- package/dist/define/view.d.ts.map +1 -0
- package/dist/define/view.js +28 -0
- package/dist/define/view.js.map +1 -0
- package/dist/deploy/check.d.ts +30 -0
- package/dist/deploy/check.d.ts.map +1 -0
- package/dist/deploy/check.js +82 -0
- package/dist/deploy/check.js.map +1 -0
- package/dist/deploy/hash-spec.d.ts +9 -0
- package/dist/deploy/hash-spec.d.ts.map +1 -0
- package/dist/deploy/hash-spec.js +29 -0
- package/dist/deploy/hash-spec.js.map +1 -0
- package/dist/deploy/index.d.ts +4 -0
- package/dist/deploy/index.d.ts.map +1 -0
- package/dist/deploy/index.js +4 -0
- package/dist/deploy/index.js.map +1 -0
- package/dist/deploy/meta.d.ts +18 -0
- package/dist/deploy/meta.d.ts.map +1 -0
- package/dist/deploy/meta.js +22 -0
- package/dist/deploy/meta.js.map +1 -0
- package/dist/dispatch/authorize.d.ts +14 -0
- package/dist/dispatch/authorize.d.ts.map +1 -0
- package/dist/dispatch/authorize.js +24 -0
- package/dist/dispatch/authorize.js.map +1 -0
- package/dist/dispatch/call-remote.d.ts +35 -0
- package/dist/dispatch/call-remote.d.ts.map +1 -0
- package/dist/dispatch/call-remote.js +37 -0
- package/dist/dispatch/call-remote.js.map +1 -0
- package/dist/dispatch/dispatcher.d.ts +60 -0
- package/dist/dispatch/dispatcher.d.ts.map +1 -0
- package/dist/dispatch/dispatcher.js +177 -0
- package/dist/dispatch/dispatcher.js.map +1 -0
- package/dist/dispatch/errors.d.ts +47 -0
- package/dist/dispatch/errors.d.ts.map +1 -0
- package/dist/dispatch/errors.js +76 -0
- package/dist/dispatch/errors.js.map +1 -0
- package/dist/dispatch/execute.d.ts +33 -0
- package/dist/dispatch/execute.d.ts.map +1 -0
- package/dist/dispatch/execute.js +24 -0
- package/dist/dispatch/execute.js.map +1 -0
- package/dist/dispatch/identity.d.ts +73 -0
- package/dist/dispatch/identity.d.ts.map +1 -0
- package/dist/dispatch/identity.js +106 -0
- package/dist/dispatch/identity.js.map +1 -0
- package/dist/dispatch/index.d.ts +8 -0
- package/dist/dispatch/index.d.ts.map +1 -0
- package/dist/dispatch/index.js +8 -0
- package/dist/dispatch/index.js.map +1 -0
- package/dist/dispatch/resolve.d.ts +27 -0
- package/dist/dispatch/resolve.d.ts.map +1 -0
- package/dist/dispatch/resolve.js +65 -0
- package/dist/dispatch/resolve.js.map +1 -0
- package/dist/dispatch/self.d.ts +27 -0
- package/dist/dispatch/self.d.ts.map +1 -0
- package/dist/dispatch/self.js +25 -0
- package/dist/dispatch/self.js.map +1 -0
- package/dist/dispatch/validate.d.ts +35 -0
- package/dist/dispatch/validate.d.ts.map +1 -0
- package/dist/dispatch/validate.js +27 -0
- package/dist/dispatch/validate.js.map +1 -0
- package/dist/domain/build-spec.d.ts +37 -0
- package/dist/domain/build-spec.d.ts.map +1 -0
- package/dist/domain/build-spec.js +95 -0
- package/dist/domain/build-spec.js.map +1 -0
- package/dist/domain/contract.d.ts +17 -0
- package/dist/domain/contract.d.ts.map +1 -0
- package/dist/domain/contract.js +26 -0
- package/dist/domain/contract.js.map +1 -0
- package/dist/domain/define.d.ts +82 -0
- package/dist/domain/define.d.ts.map +1 -0
- package/dist/domain/define.js +99 -0
- package/dist/domain/define.js.map +1 -0
- package/dist/domain/extend-core.d.ts +49 -0
- package/dist/domain/extend-core.d.ts.map +1 -0
- package/dist/domain/extend-core.js +182 -0
- package/dist/domain/extend-core.js.map +1 -0
- package/dist/domain/index.d.ts +5 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +4 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/method/class.d.ts +70 -0
- package/dist/method/class.d.ts.map +1 -0
- package/dist/method/class.js +26 -0
- package/dist/method/class.js.map +1 -0
- package/dist/method/context.d.ts +43 -0
- package/dist/method/context.d.ts.map +1 -0
- package/dist/method/context.js +10 -0
- package/dist/method/context.js.map +1 -0
- package/dist/method/index.d.ts +6 -0
- package/dist/method/index.d.ts.map +1 -0
- package/dist/method/index.js +3 -0
- package/dist/method/index.js.map +1 -0
- package/dist/method/single.d.ts +88 -0
- package/dist/method/single.d.ts.map +1 -0
- package/dist/method/single.js +18 -0
- package/dist/method/single.js.map +1 -0
- package/dist/server/auxiliary-routes.d.ts +44 -0
- package/dist/server/auxiliary-routes.d.ts.map +1 -0
- package/dist/server/auxiliary-routes.js +239 -0
- package/dist/server/auxiliary-routes.js.map +1 -0
- package/dist/server/config.d.ts +83 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +8 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/create.d.ts +21 -0
- package/dist/server/create.d.ts.map +1 -0
- package/dist/server/create.js +210 -0
- package/dist/server/create.js.map +1 -0
- package/dist/server/handle.d.ts +35 -0
- package/dist/server/handle.d.ts.map +1 -0
- package/dist/server/handle.js +9 -0
- package/dist/server/handle.js.map +1 -0
- package/dist/server/index.d.ts +11 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +8 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/jwks.d.ts +11 -0
- package/dist/server/jwks.d.ts.map +1 -0
- package/dist/server/jwks.js +15 -0
- package/dist/server/jwks.js.map +1 -0
- package/dist/server/require-env.d.ts +15 -0
- package/dist/server/require-env.d.ts.map +1 -0
- package/dist/server/require-env.js +21 -0
- package/dist/server/require-env.js.map +1 -0
- package/dist/server/serving-url.d.ts +14 -0
- package/dist/server/serving-url.d.ts.map +1 -0
- package/dist/server/serving-url.js +28 -0
- package/dist/server/serving-url.js.map +1 -0
- package/dist/server/start.d.ts +11 -0
- package/dist/server/start.d.ts.map +1 -0
- package/dist/server/start.js +34 -0
- package/dist/server/start.js.map +1 -0
- package/dist/server/worker-entry.d.ts +60 -0
- package/dist/server/worker-entry.d.ts.map +1 -0
- package/dist/server/worker-entry.js +79 -0
- package/dist/server/worker-entry.js.map +1 -0
- package/dist/server/worker-meta.d.ts +6 -0
- package/dist/server/worker-meta.d.ts.map +1 -0
- package/dist/server/worker-meta.js +10 -0
- package/dist/server/worker-meta.js.map +1 -0
- package/package.json +5 -5
- package/src/auth/compose.ts +27 -2
- package/src/auth/kernel-client.ts +103 -11
- package/src/define/remote-function.ts +10 -0
- package/src/server/auxiliary-routes.ts +3 -1
- package/src/server/start.ts +5 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Verifies an inbound credential, extracts the delegation it carries,
|
|
5
|
+
* and binds a `BoundClientSessionView` for outbound kernel calls. Delegates
|
|
6
|
+
* the real work to `verify`, `compose` + `sign` (inside `kernel-client`),
|
|
7
|
+
* and returns a generic `Authenticated` result plus the bound view.
|
|
8
|
+
*/
|
|
9
|
+
import type { FnMap } from '@astrale-os/kernel-client';
|
|
10
|
+
import type { BoundClientSessionView } from '@astrale-os/kernel-client/session';
|
|
11
|
+
import type { Authenticated, CredentialInput } from '@astrale-os/kernel-core';
|
|
12
|
+
import type { RemoteIdentityConfig } from './identity';
|
|
13
|
+
export type AuthenticateResult = {
|
|
14
|
+
authenticated: Authenticated;
|
|
15
|
+
kernel: BoundClientSessionView<FnMap> | null;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Verifies an inbound credential and binds a call-back kernel view. The `sub`
|
|
19
|
+
* claim on the outbound credential is the function's own identity, taken from
|
|
20
|
+
* `config.subject` (the function node's path), so the kernel matches an
|
|
21
|
+
* existing function identity instead of provisioning a generic one.
|
|
22
|
+
*/
|
|
23
|
+
export declare function authenticateRequest(credential: CredentialInput, config: RemoteIdentityConfig): Promise<AuthenticateResult>;
|
|
24
|
+
//# sourceMappingURL=authenticate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authenticate.d.ts","sourceRoot":"","sources":["../../src/auth/authenticate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAI7E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAKtD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,aAAa,EAAE,aAAa,CAAA;IAC5B,MAAM,EAAE,sBAAsB,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;CAC7C,CAAA;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAgB7B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Verifies an inbound credential, extracts the delegation it carries,
|
|
5
|
+
* and binds a `BoundClientSessionView` for outbound kernel calls. Delegates
|
|
6
|
+
* the real work to `verify`, `compose` + `sign` (inside `kernel-client`),
|
|
7
|
+
* and returns a generic `Authenticated` result plus the bound view.
|
|
8
|
+
*/
|
|
9
|
+
import { IdentityId, selfGrant } from '@astrale-os/kernel-core';
|
|
10
|
+
import { bindKernel } from './kernel-client';
|
|
11
|
+
import { verifyInboundCredential } from './verify';
|
|
12
|
+
/**
|
|
13
|
+
* Verifies an inbound credential and binds a call-back kernel view. The `sub`
|
|
14
|
+
* claim on the outbound credential is the function's own identity, taken from
|
|
15
|
+
* `config.subject` (the function node's path), so the kernel matches an
|
|
16
|
+
* existing function identity instead of provisioning a generic one.
|
|
17
|
+
*/
|
|
18
|
+
export async function authenticateRequest(credential, config) {
|
|
19
|
+
const { verified, issuer, attestation, delegation } = await verifyInboundCredential(credential, config);
|
|
20
|
+
const authenticated = {
|
|
21
|
+
credential: { raw: credential, verified },
|
|
22
|
+
grant: selfGrant(IdentityId(verified.sub)),
|
|
23
|
+
attestation,
|
|
24
|
+
delegation,
|
|
25
|
+
};
|
|
26
|
+
const kernel = await bindKernel(delegation, issuer, config);
|
|
27
|
+
return { authenticated, kernel };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=authenticate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../../src/auth/authenticate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAI/D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAA;AAOlD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAA2B,EAC3B,MAA4B;IAE5B,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,uBAAuB,CACjF,UAAU,EACV,MAAM,CACP,CAAA;IAED,MAAM,aAAa,GAAkB;QACnC,UAAU,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE;QACzC,KAAK,EAAE,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC1C,WAAW;QACX,UAAU;KACX,CAAA;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAE3D,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,CAAA;AAClC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission-check helpers for `RemoteHandler.authorize` hooks.
|
|
3
|
+
*
|
|
4
|
+
* The kernel already enforces `has_perm` independently — these helpers just
|
|
5
|
+
* give worker authors a one-line ergonomic way to fail-fast in `authorize`
|
|
6
|
+
* (so the dispatch never even calls `execute`) instead of letting the
|
|
7
|
+
* downstream `kernel.call` raise a less specific error mid-flight.
|
|
8
|
+
*
|
|
9
|
+
* Pattern:
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* remoteMethod(WorkerSchema, 'Project', 'addMember', {
|
|
13
|
+
* remoteUrl: BASE_URL,
|
|
14
|
+
* authorize: async ({ self, auth, kernel }) => {
|
|
15
|
+
* await assertPerm(kernel, self.path.raw, auth.principal, EDIT)
|
|
16
|
+
* },
|
|
17
|
+
* execute: async (ctx) => { ... },
|
|
18
|
+
* })
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Helpers throw `AuthorizationDeniedError` so the dispatch wrapper can
|
|
22
|
+
* surface them to the client as `PERMISSION_DENIED` cleanly.
|
|
23
|
+
*/
|
|
24
|
+
import type { FnMap } from '@astrale-os/kernel-client';
|
|
25
|
+
import type { BoundClientSessionView } from '@astrale-os/kernel-client/session';
|
|
26
|
+
import type { IdentityId } from '@astrale-os/kernel-core';
|
|
27
|
+
export { ALL, EDIT, READ, SHARE, USE } from '@astrale-os/kernel-core';
|
|
28
|
+
/**
|
|
29
|
+
* Throws `AuthorizationDeniedError` if `principal` lacks `requiredBits` on
|
|
30
|
+
* `target`. `requiredBits` is a bitmask — pass `READ | EDIT` to require both.
|
|
31
|
+
*
|
|
32
|
+
* Implementation: calls `@<principal>::checkPerm` on the kernel (the
|
|
33
|
+
* `checkPerm` syscall lives on the Identity, not the target). Cheap; adds
|
|
34
|
+
* one round-trip to the dispatch path.
|
|
35
|
+
*/
|
|
36
|
+
export declare function assertPerm(kernel: BoundClientSessionView<FnMap> | null, target: string, principal: IdentityId | null | undefined, requiredBits: number): Promise<void>;
|
|
37
|
+
/** Shortcut for "caller has SHARE bit on target" (the closest thing to "owns it"). */
|
|
38
|
+
export declare function requireOwnership(kernel: BoundClientSessionView<FnMap> | null, target: string, principal: IdentityId | null | undefined): Promise<void>;
|
|
39
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/auth/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAC/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAMzD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAA;AAErE;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,sBAAsB,CAAC,KAAK,CAAC,GAAG,IAAI,EAC5C,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EACxC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,sFAAsF;AACtF,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,sBAAsB,CAAC,KAAK,CAAC,GAAG,IAAI,EAC5C,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,GACvC,OAAO,CAAC,IAAI,CAAC,CAEf"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permission-check helpers for `RemoteHandler.authorize` hooks.
|
|
3
|
+
*
|
|
4
|
+
* The kernel already enforces `has_perm` independently — these helpers just
|
|
5
|
+
* give worker authors a one-line ergonomic way to fail-fast in `authorize`
|
|
6
|
+
* (so the dispatch never even calls `execute`) instead of letting the
|
|
7
|
+
* downstream `kernel.call` raise a less specific error mid-flight.
|
|
8
|
+
*
|
|
9
|
+
* Pattern:
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* remoteMethod(WorkerSchema, 'Project', 'addMember', {
|
|
13
|
+
* remoteUrl: BASE_URL,
|
|
14
|
+
* authorize: async ({ self, auth, kernel }) => {
|
|
15
|
+
* await assertPerm(kernel, self.path.raw, auth.principal, EDIT)
|
|
16
|
+
* },
|
|
17
|
+
* execute: async (ctx) => { ... },
|
|
18
|
+
* })
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Helpers throw `AuthorizationDeniedError` so the dispatch wrapper can
|
|
22
|
+
* surface them to the client as `PERMISSION_DENIED` cleanly.
|
|
23
|
+
*/
|
|
24
|
+
import { SHARE } from '@astrale-os/kernel-core';
|
|
25
|
+
import { AuthorizationDeniedError } from '../dispatch/errors';
|
|
26
|
+
export { ALL, EDIT, READ, SHARE, USE } from '@astrale-os/kernel-core';
|
|
27
|
+
/**
|
|
28
|
+
* Throws `AuthorizationDeniedError` if `principal` lacks `requiredBits` on
|
|
29
|
+
* `target`. `requiredBits` is a bitmask — pass `READ | EDIT` to require both.
|
|
30
|
+
*
|
|
31
|
+
* Implementation: calls `@<principal>::checkPerm` on the kernel (the
|
|
32
|
+
* `checkPerm` syscall lives on the Identity, not the target). Cheap; adds
|
|
33
|
+
* one round-trip to the dispatch path.
|
|
34
|
+
*/
|
|
35
|
+
export async function assertPerm(kernel, target, principal, requiredBits) {
|
|
36
|
+
if (!kernel) {
|
|
37
|
+
throw new AuthorizationDeniedError('No kernel client — cannot verify permissions');
|
|
38
|
+
}
|
|
39
|
+
if (!principal) {
|
|
40
|
+
throw new AuthorizationDeniedError('No authenticated principal');
|
|
41
|
+
}
|
|
42
|
+
const ok = (await kernel.call(`@${principal}::checkPerm`, {
|
|
43
|
+
node: target,
|
|
44
|
+
perms: requiredBits,
|
|
45
|
+
}));
|
|
46
|
+
if (!ok) {
|
|
47
|
+
throw new AuthorizationDeniedError(`Permission denied on "${target}" — required bits=${requiredBits} for principal "${principal}"`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Shortcut for "caller has SHARE bit on target" (the closest thing to "owns it"). */
|
|
51
|
+
export async function requireOwnership(kernel, target, principal) {
|
|
52
|
+
await assertPerm(kernel, target, principal, SHARE);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/auth/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAMH,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAE/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAE7D,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAA;AAErE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAA4C,EAC5C,MAAc,EACd,SAAwC,EACxC,YAAoB;IAEpB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,wBAAwB,CAAC,8CAA8C,CAAC,CAAA;IACpF,CAAC;IACD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,wBAAwB,CAAC,4BAA4B,CAAC,CAAA;IAClE,CAAC;IACD,MAAM,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,aAAa,EAAE;QACxD,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,YAAY;KACpB,CAAC,CAAY,CAAA;IACd,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,IAAI,wBAAwB,CAChC,yBAAyB,MAAM,qBAAqB,YAAY,mBAAmB,SAAS,GAAG,CAChG,CAAA;IACH,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAA4C,EAC5C,MAAc,EACd,SAAwC;IAExC,MAAM,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAA;AACpD,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Outbound grant expression building.
|
|
3
|
+
*
|
|
4
|
+
* Builds a composed grant expression for kernel calls:
|
|
5
|
+
* grant = union(credential(delegationJWT), self)
|
|
6
|
+
*
|
|
7
|
+
* The kernel resolves this by verifying the delegation JWT (kernel-signed)
|
|
8
|
+
* to get the caller's scoped identity, and resolving self to the function's
|
|
9
|
+
* identity. Union means either identity's permissions work.
|
|
10
|
+
*/
|
|
11
|
+
import type { Delegation } from '@astrale-os/kernel-core';
|
|
12
|
+
/**
|
|
13
|
+
* The composed identity expression: union of the caller's delegated access
|
|
14
|
+
* (a kernel-signed credential leaf) and the function's own identity (self).
|
|
15
|
+
*
|
|
16
|
+
* Used both as the grant on outbound kernel calls AND as the delegation
|
|
17
|
+
* expression when minting a NEXT-HOP credential — the next worker receives
|
|
18
|
+
* principal = this function, authority = union(caller's delegated, own).
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildComposedExpr(delegation: Delegation): import("@astrale-os/kernel-core").UnresolvedIdentityExpr;
|
|
21
|
+
/**
|
|
22
|
+
* Build the grant expression that unions the caller's delegated access
|
|
23
|
+
* with the function's own identity.
|
|
24
|
+
*
|
|
25
|
+
* @param delegation - Delegation extracted from the inbound credential
|
|
26
|
+
* @returns The unresolved grant object with version and expression
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildComposedGrant(delegation: Delegation): {
|
|
29
|
+
grant: import("@astrale-os/kernel-core").UnresolvedGrant;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* The SELF-ONLY expression: the function's own identity, nothing delegated.
|
|
33
|
+
* Used by `selfKernel` sessions (public/webhook handlers acting on their own
|
|
34
|
+
* authority) — both as the credential grant and as the next-hop delegation.
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildSelfExpr(): import("@astrale-os/kernel-core").UnresolvedIdentityExpr;
|
|
37
|
+
/** Self-only grant for `selfKernel` credentials. */
|
|
38
|
+
export declare function buildSelfGrant(): {
|
|
39
|
+
grant: import("@astrale-os/kernel-core").UnresolvedGrant;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=compose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/auth/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AASzD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,4DAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,UAAU;IAC9C,KAAK;EACf;AAED;;;;GAIG;AACH,wBAAgB,aAAa,6DAE5B;AAED,oDAAoD;AACpD,wBAAgB,cAAc;IACnB,KAAK;EACf"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Outbound grant expression building.
|
|
3
|
+
*
|
|
4
|
+
* Builds a composed grant expression for kernel calls:
|
|
5
|
+
* grant = union(credential(delegationJWT), self)
|
|
6
|
+
*
|
|
7
|
+
* The kernel resolves this by verifying the delegation JWT (kernel-signed)
|
|
8
|
+
* to get the caller's scoped identity, and resolving self to the function's
|
|
9
|
+
* identity. Union means either identity's permissions work.
|
|
10
|
+
*/
|
|
11
|
+
import { createUnresolvedGrant, unresolvedCredential, unresolvedSelf, unresolvedUnion, } from '@astrale-os/kernel-core';
|
|
12
|
+
/**
|
|
13
|
+
* The composed identity expression: union of the caller's delegated access
|
|
14
|
+
* (a kernel-signed credential leaf) and the function's own identity (self).
|
|
15
|
+
*
|
|
16
|
+
* Used both as the grant on outbound kernel calls AND as the delegation
|
|
17
|
+
* expression when minting a NEXT-HOP credential — the next worker receives
|
|
18
|
+
* principal = this function, authority = union(caller's delegated, own).
|
|
19
|
+
*/
|
|
20
|
+
export function buildComposedExpr(delegation) {
|
|
21
|
+
return unresolvedUnion(unresolvedCredential(delegation.credential), unresolvedSelf());
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build the grant expression that unions the caller's delegated access
|
|
25
|
+
* with the function's own identity.
|
|
26
|
+
*
|
|
27
|
+
* @param delegation - Delegation extracted from the inbound credential
|
|
28
|
+
* @returns The unresolved grant object with version and expression
|
|
29
|
+
*/
|
|
30
|
+
export function buildComposedGrant(delegation) {
|
|
31
|
+
return { grant: createUnresolvedGrant(buildComposedExpr(delegation)) };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The SELF-ONLY expression: the function's own identity, nothing delegated.
|
|
35
|
+
* Used by `selfKernel` sessions (public/webhook handlers acting on their own
|
|
36
|
+
* authority) — both as the credential grant and as the next-hop delegation.
|
|
37
|
+
*/
|
|
38
|
+
export function buildSelfExpr() {
|
|
39
|
+
return unresolvedSelf();
|
|
40
|
+
}
|
|
41
|
+
/** Self-only grant for `selfKernel` credentials. */
|
|
42
|
+
export function buildSelfGrant() {
|
|
43
|
+
return { grant: createUnresolvedGrant(buildSelfExpr()) };
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=compose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../../src/auth/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,eAAe,GAChB,MAAM,yBAAyB,CAAA;AAEhC;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAsB;IACtD,OAAO,eAAe,CAAC,oBAAoB,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC,CAAA;AACvF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAsB;IACvD,OAAO,EAAE,KAAK,EAAE,qBAAqB,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAA;AACxE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,cAAc,EAAE,CAAA;AACzB,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,cAAc;IAC5B,OAAO,EAAE,KAAK,EAAE,qBAAqB,CAAC,aAAa,EAAE,CAAC,EAAE,CAAA;AAC1D,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Errors thrown by the auth bridge.
|
|
3
|
+
*
|
|
4
|
+
* Each implements `KernelErrorClassifiable` so `kernel-api/dispatch` can
|
|
5
|
+
* convert them into typed `KernelErrorPayload` values automatically.
|
|
6
|
+
*/
|
|
7
|
+
import type { KernelErrorPayload, KernelErrorClassifiable } from '@astrale-os/kernel-api';
|
|
8
|
+
export declare class AuthMissingError extends Error implements KernelErrorClassifiable {
|
|
9
|
+
constructor();
|
|
10
|
+
toKernelErrorPayload(): KernelErrorPayload;
|
|
11
|
+
}
|
|
12
|
+
export declare class AuthInvalidError extends Error implements KernelErrorClassifiable {
|
|
13
|
+
constructor(message: string, cause?: unknown);
|
|
14
|
+
toKernelErrorPayload(): KernelErrorPayload;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAIzF,qBAAa,gBAAiB,SAAQ,KAAM,YAAW,uBAAuB;IAC5E,cAGC;IAED,oBAAoB,IAAI,kBAAkB,CAEzC;CACF;AAED,qBAAa,gBAAiB,SAAQ,KAAM,YAAW,uBAAuB;IAC5E,YAAY,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAG3C;IAED,oBAAoB,IAAI,kBAAkB,CAEzC;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Errors thrown by the auth bridge.
|
|
3
|
+
*
|
|
4
|
+
* Each implements `KernelErrorClassifiable` so `kernel-api/dispatch` can
|
|
5
|
+
* convert them into typed `KernelErrorPayload` values automatically.
|
|
6
|
+
*/
|
|
7
|
+
import { KERNEL_ERROR_CODES } from '@astrale-os/kernel-api';
|
|
8
|
+
export class AuthMissingError extends Error {
|
|
9
|
+
constructor() {
|
|
10
|
+
super('Missing credentials');
|
|
11
|
+
this.name = 'AuthMissingError';
|
|
12
|
+
}
|
|
13
|
+
toKernelErrorPayload() {
|
|
14
|
+
return { code: KERNEL_ERROR_CODES.AUTH_MISSING, message: this.message };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class AuthInvalidError extends Error {
|
|
18
|
+
constructor(message, cause) {
|
|
19
|
+
super(message, { cause });
|
|
20
|
+
this.name = 'AuthInvalidError';
|
|
21
|
+
}
|
|
22
|
+
toKernelErrorPayload() {
|
|
23
|
+
return { code: KERNEL_ERROR_CODES.AUTH_INVALID, message: this.message };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAE3D,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC;QACE,KAAK,CAAC,qBAAqB,CAAC,CAAA;QAC5B,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAA;IAChC,CAAC;IAED,oBAAoB;QAClB,OAAO,EAAE,IAAI,EAAE,kBAAkB,CAAC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;IACzE,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YAAY,OAAe,EAAE,KAAe;QAC1C,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QACzB,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAA;IAChC,CAAC;IAED,oBAAoB;QAClB,OAAO,EAAE,IAAI,EAAE,kBAAkB,CAAC,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;IACzE,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity configuration for a remote domain server.
|
|
3
|
+
*
|
|
4
|
+
* The issuer must be reachable via JWKS at `<issuer>/.well-known/jwks.json`
|
|
5
|
+
* (or registered in the kernel's trust store). The private key is used to
|
|
6
|
+
* sign outbound composed credentials.
|
|
7
|
+
*/
|
|
8
|
+
export type RemoteIdentityConfig = {
|
|
9
|
+
/** This service's issuer (URL where its JWKS is served, or a registered ID) */
|
|
10
|
+
issuer: string;
|
|
11
|
+
/** This service's subject identifier (e.g. "task-service") */
|
|
12
|
+
subject: string;
|
|
13
|
+
/** Private key for signing outbound credentials */
|
|
14
|
+
privateKey: JsonWebKey;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/auth/identity.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAA;IACf,mDAAmD;IACnD,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/auth/identity.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type { RemoteIdentityConfig } from './identity';
|
|
2
|
+
export type { VerifiedInbound } from './verify';
|
|
3
|
+
export type { AuthenticateResult } from './authenticate';
|
|
4
|
+
export { authenticateRequest } from './authenticate';
|
|
5
|
+
export { resolveInboundAuth, buildAuthContext, type ResolvedAuth } from './resolve';
|
|
6
|
+
export { verifyInboundCredential } from './verify';
|
|
7
|
+
export { buildComposedGrant } from './compose';
|
|
8
|
+
export { signCredential } from './sign';
|
|
9
|
+
export { bindKernel } from './kernel-client';
|
|
10
|
+
export { AuthMissingError, AuthInvalidError } from './errors';
|
|
11
|
+
export { assertPerm, requireOwnership, READ, EDIT, USE, SHARE, ALL } from './check';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAA;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { authenticateRequest } from './authenticate';
|
|
2
|
+
export { resolveInboundAuth, buildAuthContext } from './resolve';
|
|
3
|
+
export { verifyInboundCredential } from './verify';
|
|
4
|
+
export { buildComposedGrant } from './compose';
|
|
5
|
+
export { signCredential } from './sign';
|
|
6
|
+
export { bindKernel } from './kernel-client';
|
|
7
|
+
export { AuthMissingError, AuthInvalidError } from './errors';
|
|
8
|
+
export { assertPerm, requireOwnership, READ, EDIT, USE, SHARE, ALL } from './check';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAqB,MAAM,WAAW,CAAA;AACnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAA;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call-back kernel client.
|
|
3
|
+
*
|
|
4
|
+
* Every authenticated inbound request produces a `BoundClientSessionView` the
|
|
5
|
+
* handler uses to call back into the parent kernel. The view is bound to
|
|
6
|
+
* a composed credential (`union(delegation, self)`) so the kernel
|
|
7
|
+
* enforces both the caller's scoped identity and the function's own.
|
|
8
|
+
*
|
|
9
|
+
* The connection pool and schema registry are cached per kernel URL and reused
|
|
10
|
+
* across requests. The `ClientSession` itself is per-request: it carries a
|
|
11
|
+
* delegation mint bound to the calling function's own subject (`config.subject`)
|
|
12
|
+
* so a remote-bound call (one that redirects to another worker) mints a
|
|
13
|
+
* worker-scoped credential for the audience the kernel puts on the redirect
|
|
14
|
+
* (`CallRedirection.iss`) — the worker→worker dance, done reactively instead of
|
|
15
|
+
* the old proactive `lookupRemoteBinding` resolve-then-dial.
|
|
16
|
+
*/
|
|
17
|
+
import type { Delegation } from '@astrale-os/kernel-core';
|
|
18
|
+
import { type FnMap } from '@astrale-os/kernel-client';
|
|
19
|
+
import { type BoundClientSessionView } from '@astrale-os/kernel-client/session';
|
|
20
|
+
import type { RemoteIdentityConfig } from './identity';
|
|
21
|
+
/**
|
|
22
|
+
* Build a `BoundClientSessionView` that signs outbound calls as the composed
|
|
23
|
+
* identity (the caller's delegation unioned with this function's own
|
|
24
|
+
* identity). Remote-bound calls auto-follow the kernel's redirect and mint a
|
|
25
|
+
* worker-scoped delegation via `@<subject>::mintDelegationCredential`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function bindKernel(delegation: Delegation, kernelUrl: string, config: RemoteIdentityConfig): Promise<BoundClientSessionView<FnMap>>;
|
|
28
|
+
/**
|
|
29
|
+
* Build a `BoundClientSessionView` authenticated as the FUNCTION'S OWN
|
|
30
|
+
* identity — no inbound delegation, authority = the function's own grants
|
|
31
|
+
* only. The seam behind `selfKernel` for public/webhook handlers: an HMAC- or
|
|
32
|
+
* signature-verified webhook can act on the graph as itself after verifying
|
|
33
|
+
* the upstream. Next-hop mints delegate self only.
|
|
34
|
+
*/
|
|
35
|
+
export declare function bindSelfKernel(kernelUrl: string, config: RemoteIdentityConfig): Promise<BoundClientSessionView<FnMap>>;
|
|
36
|
+
/**
|
|
37
|
+
* Build the `selfKernel` accessor handed to remote-function handlers.
|
|
38
|
+
* Resolves the kernel URL from the explicit argument or `deps.KERNEL_URL`
|
|
39
|
+
* (a public request carries no credential, so the parent kernel cannot be
|
|
40
|
+
* inferred — it must be configured).
|
|
41
|
+
*/
|
|
42
|
+
export declare function makeSelfKernel(identity: RemoteIdentityConfig, deps: unknown): (kernelUrl?: string) => Promise<BoundClientSessionView<FnMap>>;
|
|
43
|
+
//# sourceMappingURL=kernel-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel-client.d.ts","sourceRoot":"","sources":["../../src/auth/kernel-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAGzD,OAAO,EAAgC,KAAK,KAAK,EAAE,MAAM,2BAA2B,CAAA;AAEpF,OAAO,EAAiB,KAAK,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAE9F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAsCtD;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAIxC;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAExC;AA0DD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,oBAAoB,EAC9B,IAAI,EAAE,OAAO,GACZ,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAWhE"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call-back kernel client.
|
|
3
|
+
*
|
|
4
|
+
* Every authenticated inbound request produces a `BoundClientSessionView` the
|
|
5
|
+
* handler uses to call back into the parent kernel. The view is bound to
|
|
6
|
+
* a composed credential (`union(delegation, self)`) so the kernel
|
|
7
|
+
* enforces both the caller's scoped identity and the function's own.
|
|
8
|
+
*
|
|
9
|
+
* The connection pool and schema registry are cached per kernel URL and reused
|
|
10
|
+
* across requests. The `ClientSession` itself is per-request: it carries a
|
|
11
|
+
* delegation mint bound to the calling function's own subject (`config.subject`)
|
|
12
|
+
* so a remote-bound call (one that redirects to another worker) mints a
|
|
13
|
+
* worker-scoped credential for the audience the kernel puts on the redirect
|
|
14
|
+
* (`CallRedirection.iss`) — the worker→worker dance, done reactively instead of
|
|
15
|
+
* the old proactive `lookupRemoteBinding` resolve-then-dial.
|
|
16
|
+
*/
|
|
17
|
+
import { KernelClient, SchemaRegistry } from '@astrale-os/kernel-client';
|
|
18
|
+
import { ClientPool } from '@astrale-os/kernel-client/pool';
|
|
19
|
+
import { ClientSession } from '@astrale-os/kernel-client/session';
|
|
20
|
+
import { buildComposedExpr, buildComposedGrant, buildSelfExpr, buildSelfGrant } from './compose';
|
|
21
|
+
import { signCredential } from './sign';
|
|
22
|
+
const DELEGATION_TTL_SECONDS = 3600;
|
|
23
|
+
// The kernel's whoami — returns the AUTHENTICATED principal's graph node, so
|
|
24
|
+
// the resolved id satisfies the mint syscall's `self.id === auth.principal`
|
|
25
|
+
// invariant by construction (same seam the shell uses to resolve self).
|
|
26
|
+
const WHOAMI_PATH = '/:kernel.astrale.ai:interface.Identity:whoami';
|
|
27
|
+
// Shared per kernel URL — the expensive, identity-agnostic state. Sessions are
|
|
28
|
+
// NOT shared (each binds a subject-specific delegation mint), but the pool
|
|
29
|
+
// (connections) and registry (learned schemas) are reused across them.
|
|
30
|
+
const pools = new Map();
|
|
31
|
+
const registries = new Map();
|
|
32
|
+
function getRegistry(url) {
|
|
33
|
+
let registry = registries.get(url);
|
|
34
|
+
if (!registry) {
|
|
35
|
+
registry = new SchemaRegistry();
|
|
36
|
+
registries.set(url, registry);
|
|
37
|
+
}
|
|
38
|
+
return registry;
|
|
39
|
+
}
|
|
40
|
+
function getPool(url) {
|
|
41
|
+
const cached = pools.get(url);
|
|
42
|
+
if (cached)
|
|
43
|
+
return cached;
|
|
44
|
+
const registry = getRegistry(url);
|
|
45
|
+
const pool = new ClientPool({
|
|
46
|
+
clientFactory: (u) => new KernelClient({ url: u, schema: registry }),
|
|
47
|
+
});
|
|
48
|
+
pools.set(url, pool);
|
|
49
|
+
return pool;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Build a `BoundClientSessionView` that signs outbound calls as the composed
|
|
53
|
+
* identity (the caller's delegation unioned with this function's own
|
|
54
|
+
* identity). Remote-bound calls auto-follow the kernel's redirect and mint a
|
|
55
|
+
* worker-scoped delegation via `@<subject>::mintDelegationCredential`.
|
|
56
|
+
*/
|
|
57
|
+
export async function bindKernel(delegation, kernelUrl, config) {
|
|
58
|
+
return bindSession(kernelUrl, config, buildComposedGrant(delegation).grant, () => buildComposedExpr(delegation));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Build a `BoundClientSessionView` authenticated as the FUNCTION'S OWN
|
|
62
|
+
* identity — no inbound delegation, authority = the function's own grants
|
|
63
|
+
* only. The seam behind `selfKernel` for public/webhook handlers: an HMAC- or
|
|
64
|
+
* signature-verified webhook can act on the graph as itself after verifying
|
|
65
|
+
* the upstream. Next-hop mints delegate self only.
|
|
66
|
+
*/
|
|
67
|
+
export async function bindSelfKernel(kernelUrl, config) {
|
|
68
|
+
return bindSession(kernelUrl, config, buildSelfGrant().grant, () => buildSelfExpr());
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Shared session construction: sign a credential as this function's identity
|
|
72
|
+
* carrying `grant`, bind the session to it, and wire the lazy NEXT-HOP mint.
|
|
73
|
+
*/
|
|
74
|
+
async function bindSession(kernelUrl, config, grant, nextHopDelegation) {
|
|
75
|
+
const credential = await signCredential({ grant }, {
|
|
76
|
+
issuer: config.issuer,
|
|
77
|
+
subject: config.subject,
|
|
78
|
+
audience: kernelUrl,
|
|
79
|
+
privateKey: config.privateKey,
|
|
80
|
+
});
|
|
81
|
+
// Self-reference in the mint closure is lazy — it only fires on a delegation
|
|
82
|
+
// cache miss while following a redirect, long after construction.
|
|
83
|
+
const session = new ClientSession({
|
|
84
|
+
default: kernelUrl,
|
|
85
|
+
schema: getRegistry(kernelUrl),
|
|
86
|
+
pool: getPool(kernelUrl),
|
|
87
|
+
delegation: {
|
|
88
|
+
// NEXT-HOP mint: each hop mints AS ITSELF. The anchor is this function's
|
|
89
|
+
// identity NODE id (resolved via whoami — `@` only accepts node ids, not
|
|
90
|
+
// paths), so `self.id === auth.principal` holds by construction. The
|
|
91
|
+
// minted delegation carries the session's authority expression (composed
|
|
92
|
+
// for delegated sessions, self-only for selfKernel): the next worker
|
|
93
|
+
// sees WHO called it while inheriting exactly that authority.
|
|
94
|
+
// `skipDelegation` keeps the whoami + mint from re-entering this
|
|
95
|
+
// closure — both target the kernel (same origin), so no delegation is
|
|
96
|
+
// needed.
|
|
97
|
+
mint: async (audience) => {
|
|
98
|
+
const selfId = await resolveSelfId(session, credential, kernelUrl, config);
|
|
99
|
+
const envelope = await session.call(`@${selfId}::mintDelegationCredential`, { audience, delegation: nextHopDelegation(), ttl: DELEGATION_TTL_SECONDS }, { credential, skipDelegation: true });
|
|
100
|
+
if (typeof envelope !== 'string') {
|
|
101
|
+
throw new Error(`mintDelegationCredential returned ${typeof envelope}, expected a credential string`);
|
|
102
|
+
}
|
|
103
|
+
return { credential: envelope, ttl: DELEGATION_TTL_SECONDS };
|
|
104
|
+
},
|
|
105
|
+
ttl: DELEGATION_TTL_SECONDS,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
return session.as(credential);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Build the `selfKernel` accessor handed to remote-function handlers.
|
|
112
|
+
* Resolves the kernel URL from the explicit argument or `deps.KERNEL_URL`
|
|
113
|
+
* (a public request carries no credential, so the parent kernel cannot be
|
|
114
|
+
* inferred — it must be configured).
|
|
115
|
+
*/
|
|
116
|
+
export function makeSelfKernel(identity, deps) {
|
|
117
|
+
return async (kernelUrl) => {
|
|
118
|
+
const url = kernelUrl ?? deps?.KERNEL_URL;
|
|
119
|
+
if (typeof url !== 'string' || url.length === 0) {
|
|
120
|
+
throw new Error('selfKernel: no kernel URL — pass one explicitly or set KERNEL_URL in the worker env ' +
|
|
121
|
+
'(managed deploys set it automatically).');
|
|
122
|
+
}
|
|
123
|
+
return bindSelfKernel(url, identity);
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
// Function-identity node ids, cached per (kernel, issuer, subject). Sessions
|
|
127
|
+
// are per-request, but a function's identity node is stable for the worker's
|
|
128
|
+
// lifetime — one whoami per function, not one per redirect.
|
|
129
|
+
const selfIds = new Map();
|
|
130
|
+
/**
|
|
131
|
+
* Resolve THIS function's identity node id on the parent kernel via whoami,
|
|
132
|
+
* authenticated with the composed credential (whose principal IS the function).
|
|
133
|
+
*/
|
|
134
|
+
async function resolveSelfId(session, credential, kernelUrl, config) {
|
|
135
|
+
const key = `${kernelUrl}|${config.issuer}|${config.subject}`;
|
|
136
|
+
const cached = selfIds.get(key);
|
|
137
|
+
if (cached)
|
|
138
|
+
return cached;
|
|
139
|
+
const me = (await session.call(WHOAMI_PATH, {}, { credential, skipDelegation: true }));
|
|
140
|
+
if (!me?.id) {
|
|
141
|
+
throw new Error(`whoami returned no identity node for ${config.subject} — cannot anchor the next-hop delegation mint`);
|
|
142
|
+
}
|
|
143
|
+
selfIds.set(key, me.id);
|
|
144
|
+
return me.id;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=kernel-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel-client.js","sourceRoot":"","sources":["../../src/auth/kernel-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared inbound-credential resolution.
|
|
3
|
+
*
|
|
4
|
+
* Consumed by both `SdkDispatcher` (kernel envelope) and `mountAuxiliaryRoutes`
|
|
5
|
+
* (View / RemoteFunction routes). Centralises the auth-policy three-way
|
|
6
|
+
* (`'required'` / `'optional'` / `'public'`) and the wrap of underlying
|
|
7
|
+
* verification errors into canonical `AuthMissingError` / `AuthInvalidError`.
|
|
8
|
+
*/
|
|
9
|
+
import type { AuthPolicy } from '@astrale-os/kernel-api/routed';
|
|
10
|
+
import type { AuthContext, Authenticated, CredentialInput } from '@astrale-os/kernel-core';
|
|
11
|
+
import type { AuthenticateResult } from './authenticate';
|
|
12
|
+
import type { RemoteIdentityConfig } from './identity';
|
|
13
|
+
export type ResolvedAuth = {
|
|
14
|
+
auth: AuthContext | null;
|
|
15
|
+
kernel: AuthenticateResult['kernel'];
|
|
16
|
+
};
|
|
17
|
+
export declare function resolveInboundAuth(credential: CredentialInput, policy: AuthPolicy | undefined, identity: RemoteIdentityConfig): Promise<ResolvedAuth>;
|
|
18
|
+
export declare function buildAuthContext(authenticated: Authenticated): AuthContext;
|
|
19
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/auth/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EACb,eAAe,EAEhB,MAAM,yBAAyB,CAAA;AAIhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAKtD,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IACxB,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAA;CACrC,CAAA;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,UAAU,GAAG,SAAS,EAC9B,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,YAAY,CAAC,CAkBvB;AAED,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,aAAa,GAAG,WAAW,CAQ1E"}
|