@astrale-os/sdk 0.5.0-beta.85 → 0.5.0-beta.87
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/CHANGELOG.md +14 -0
- package/dist/execution/identity/exchange.d.ts +10 -1
- package/dist/execution/identity/exchange.js +33 -6
- package/dist/execution/identity/identity.js +5 -2
- package/dist/execution/identity/index.d.ts +1 -1
- package/dist/execution/identity/index.js +1 -1
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.0-beta.87](https://github.com/astrale-os/sdk/compare/sdk-v0.5.0-beta.86...sdk-v0.5.0-beta.87) (2026-08-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* expose managed Domain token exchange ([#354](https://github.com/astrale-os/sdk/issues/354)) ([f7d97bc](https://github.com/astrale-os/sdk/commit/f7d97bc4016d263ccb7f966509775c26368a350f))
|
|
9
|
+
|
|
10
|
+
## [0.5.0-beta.86](https://github.com/astrale-os/sdk/compare/sdk-v0.5.0-beta.85...sdk-v0.5.0-beta.86) (2026-08-30)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* support trusted Domain token-exchange authority ([#352](https://github.com/astrale-os/sdk/issues/352)) ([8bec391](https://github.com/astrale-os/sdk/commit/8bec3915afad8aef6fab66d6e8906ea89ca8ad39))
|
|
16
|
+
|
|
3
17
|
## [0.5.0-beta.85](https://github.com/astrale-os/sdk/compare/sdk-v0.5.0-beta.84...sdk-v0.5.0-beta.85) (2026-08-30)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -4,6 +4,15 @@ import type { IdentityNetworkPolicy, VerificationBasisResolver } from './jwks.js
|
|
|
4
4
|
import type { SigningMaterial } from './signing.js';
|
|
5
5
|
export interface ExchangeOptions {
|
|
6
6
|
readonly maximumTtlSeconds?: number;
|
|
7
|
+
/** Authority carried by the exchanged Domain credential. Defaults to the authenticated caller. */
|
|
8
|
+
readonly grantMode?: ExchangeGrantMode;
|
|
9
|
+
}
|
|
10
|
+
export type ExchangeGrantMode = 'caller' | 'union';
|
|
11
|
+
interface AcceptedExchangeOptions {
|
|
12
|
+
readonly maximumTtlSeconds: number;
|
|
13
|
+
readonly grantMode: ExchangeGrantMode;
|
|
7
14
|
}
|
|
8
15
|
export declare function maximumExchangeTtl(input: ExchangeOptions | undefined): number;
|
|
9
|
-
export declare function tokenExchange(issuer: IssuerId, subject: string, signing: SigningMaterial, policy: IdentityNetworkPolicy, verification: VerificationBasisResolver, maximumTtlSeconds: number): exchange.Provider;
|
|
16
|
+
export declare function tokenExchange(issuer: IssuerId, subject: string, signing: SigningMaterial, policy: IdentityNetworkPolicy, verification: VerificationBasisResolver, maximumTtlSeconds: number, grantMode?: ExchangeGrantMode): exchange.Provider;
|
|
17
|
+
export declare function exchangeOptions(input: ExchangeOptions | undefined): AcceptedExchangeOptions;
|
|
18
|
+
export {};
|
|
@@ -8,21 +8,27 @@ import { CredentialRejected, IssuerUnavailable } from './errors.js';
|
|
|
8
8
|
import { verifyCredential, verifyCredentialAgainst } from './jwks.js';
|
|
9
9
|
const DEFAULT_MAXIMUM_TTL_SECONDS = 300;
|
|
10
10
|
export function maximumExchangeTtl(input) {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
return acceptExchangeOptions(input).maximumTtlSeconds;
|
|
12
|
+
}
|
|
13
|
+
function acceptExchangeOptions(input) {
|
|
14
|
+
if (input === undefined) {
|
|
15
|
+
return Object.freeze({ maximumTtlSeconds: DEFAULT_MAXIMUM_TTL_SECONDS, grantMode: 'caller' });
|
|
16
|
+
}
|
|
13
17
|
if (input === null ||
|
|
14
18
|
typeof input !== 'object' ||
|
|
15
19
|
Array.isArray(input) ||
|
|
16
|
-
Reflect.ownKeys(input).some((key) => key !== 'maximumTtlSeconds')) {
|
|
20
|
+
Reflect.ownKeys(input).some((key) => key !== 'maximumTtlSeconds' && key !== 'grantMode')) {
|
|
17
21
|
throw new TypeError('Execution identity tokenExchange options are invalid.');
|
|
18
22
|
}
|
|
19
23
|
const value = input.maximumTtlSeconds ?? DEFAULT_MAXIMUM_TTL_SECONDS;
|
|
20
24
|
if (!Number.isSafeInteger(value) || value < 1) {
|
|
21
25
|
throw new TypeError('tokenExchange.maximumTtlSeconds must be a positive safe integer.');
|
|
22
26
|
}
|
|
23
|
-
|
|
27
|
+
const grantMode = input.grantMode ?? 'caller';
|
|
28
|
+
return Object.freeze({ maximumTtlSeconds: value, grantMode: acceptExchangeGrantMode(grantMode) });
|
|
24
29
|
}
|
|
25
|
-
export function tokenExchange(issuer, subject, signing, policy, verification, maximumTtlSeconds) {
|
|
30
|
+
export function tokenExchange(issuer, subject, signing, policy, verification, maximumTtlSeconds, grantMode = 'caller') {
|
|
31
|
+
const acceptedGrantMode = acceptExchangeGrantMode(grantMode);
|
|
26
32
|
return Object.freeze({
|
|
27
33
|
async exchange(request, context) {
|
|
28
34
|
try {
|
|
@@ -45,7 +51,7 @@ export function tokenExchange(issuer, subject, signing, policy, verification, ma
|
|
|
45
51
|
const token = await new SignJWT({
|
|
46
52
|
grant: {
|
|
47
53
|
v: 1,
|
|
48
|
-
expr:
|
|
54
|
+
expr: exchangeGrant(acceptedGrantMode, carried.credential),
|
|
49
55
|
},
|
|
50
56
|
})
|
|
51
57
|
.setProtectedHeader({
|
|
@@ -81,6 +87,27 @@ export function tokenExchange(issuer, subject, signing, policy, verification, ma
|
|
|
81
87
|
},
|
|
82
88
|
});
|
|
83
89
|
}
|
|
90
|
+
export function exchangeOptions(input) {
|
|
91
|
+
return acceptExchangeOptions(input);
|
|
92
|
+
}
|
|
93
|
+
function exchangeGrant(mode, credential) {
|
|
94
|
+
const caller = Object.freeze({ kind: 'identity', credential });
|
|
95
|
+
if (mode === 'caller')
|
|
96
|
+
return caller;
|
|
97
|
+
return Object.freeze({
|
|
98
|
+
kind: 'union',
|
|
99
|
+
operands: Object.freeze([
|
|
100
|
+
Object.freeze({ kind: 'identity', self: true }),
|
|
101
|
+
caller,
|
|
102
|
+
]),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function acceptExchangeGrantMode(input) {
|
|
106
|
+
if (input !== 'caller' && input !== 'union') {
|
|
107
|
+
throw new TypeError('tokenExchange.grantMode must be caller or union.');
|
|
108
|
+
}
|
|
109
|
+
return input;
|
|
110
|
+
}
|
|
84
111
|
function requireProfile(input, profile) {
|
|
85
112
|
const expected = ['aud', 'delegation', 'exp', 'iat', 'iss', 'sub'];
|
|
86
113
|
const actual = Object.keys(input.claims).sort();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { admit, authenticate } from './authentication.js';
|
|
2
2
|
import { publicationDelivery } from './delivery.js';
|
|
3
3
|
import { httpIssuer } from './errors.js';
|
|
4
|
-
import {
|
|
4
|
+
import { exchangeOptions, tokenExchange } from './exchange.js';
|
|
5
5
|
import { createVerificationBasisResolver } from './jwks.js';
|
|
6
6
|
import { signing } from './signing.js';
|
|
7
7
|
/** Create one stateless execution identity backed by an asymmetric private JWK. */
|
|
@@ -37,7 +37,10 @@ export function createIdentity(input) {
|
|
|
37
37
|
});
|
|
38
38
|
const exchangeProvider = input.tokenExchange === false
|
|
39
39
|
? undefined
|
|
40
|
-
:
|
|
40
|
+
: (() => {
|
|
41
|
+
const options = exchangeOptions(input.tokenExchange);
|
|
42
|
+
return tokenExchange(issuer, input.subject, material, policy, verification, options.maximumTtlSeconds, options.grantMode);
|
|
43
|
+
})();
|
|
41
44
|
return identity({
|
|
42
45
|
issuer,
|
|
43
46
|
subject: input.subject,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { createIdentity, identity, type Identity, type IdentityInput } from './identity.js';
|
|
2
|
-
export { maximumExchangeTtl, tokenExchange, type ExchangeOptions } from './exchange.js';
|
|
2
|
+
export { maximumExchangeTtl, tokenExchange, type ExchangeGrantMode, type ExchangeOptions, } from './exchange.js';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { createIdentity, identity } from './identity.js';
|
|
2
|
-
export { maximumExchangeTtl, tokenExchange } from './exchange.js';
|
|
2
|
+
export { maximumExchangeTtl, tokenExchange, } from './exchange.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { serve } from './serve.js';
|
|
2
2
|
export type { ExecutionContext, ServedApplication, ServeInput } from './serve.js';
|
|
3
|
-
export { createIdentity, type Identity, type IdentityInput } from './identity/index.js';
|
|
3
|
+
export { createIdentity, type ExchangeGrantMode, type ExchangeOptions, type Identity, type IdentityInput, } from './identity/index.js';
|
|
4
4
|
export { InvocationError } from './invocation/index.js';
|
|
5
5
|
export type { InvocationErrorCode } from './invocation/index.js';
|
package/dist/execution/index.js
CHANGED