@xemahq/identity-client 0.9.7 → 0.10.0
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 +85 -1
- package/dist/client.d.ts +10 -1
- package/dist/client.js +13 -0
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/nestjs/identity-bootstrap.service.d.ts +12 -2
- package/dist/nestjs/identity-bootstrap.service.js +178 -79
- package/dist/nestjs/identity-bootstrap.service.js.map +1 -1
- package/dist/nestjs/index.d.ts +2 -1
- package/dist/nestjs/index.js +6 -1
- package/dist/nestjs/index.js.map +1 -1
- package/dist/nestjs/token-acquisition.d.ts +24 -0
- package/dist/nestjs/token-acquisition.js +96 -0
- package/dist/nestjs/token-acquisition.js.map +1 -0
- package/dist/types.d.ts +28 -0
- package/dist/types.js +6 -1
- package/dist/types.js.map +1 -1
- package/dist/workload-context.d.ts +27 -0
- package/dist/workload-context.js +122 -0
- package/dist/workload-context.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IdentityTokenRequestTimeoutError = exports.IdentityTokenWaitAbortedError = exports.IdentityTokenOperation = exports.DEFAULT_TOKEN_REQUEST_TIMEOUT_MS = void 0;
|
|
4
|
+
exports.resolveTokenRequestTimeoutMs = resolveTokenRequestTimeoutMs;
|
|
5
|
+
exports.withTokenRequestDeadline = withTokenRequestDeadline;
|
|
6
|
+
exports.awaitWithCallerSignal = awaitWithCallerSignal;
|
|
7
|
+
exports.DEFAULT_TOKEN_REQUEST_TIMEOUT_MS = 10_000;
|
|
8
|
+
var IdentityTokenOperation;
|
|
9
|
+
(function (IdentityTokenOperation) {
|
|
10
|
+
IdentityTokenOperation["ServiceTokenRefresh"] = "service-token-refresh";
|
|
11
|
+
IdentityTokenOperation["ScopedTokenMint"] = "scoped-token-mint";
|
|
12
|
+
IdentityTokenOperation["ExactAudienceTokenMint"] = "exact-audience-token-mint";
|
|
13
|
+
IdentityTokenOperation["CredentialRecoveryCoordination"] = "credential-recovery-coordination";
|
|
14
|
+
})(IdentityTokenOperation || (exports.IdentityTokenOperation = IdentityTokenOperation = {}));
|
|
15
|
+
class IdentityTokenWaitAbortedError extends Error {
|
|
16
|
+
operation;
|
|
17
|
+
reason;
|
|
18
|
+
name = 'IdentityTokenWaitAbortedError';
|
|
19
|
+
retryable = false;
|
|
20
|
+
constructor(operation, reason) {
|
|
21
|
+
super(`Wait for ${operation} token aborted by the caller's signal`);
|
|
22
|
+
this.operation = operation;
|
|
23
|
+
this.reason = reason;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.IdentityTokenWaitAbortedError = IdentityTokenWaitAbortedError;
|
|
27
|
+
class IdentityTokenRequestTimeoutError extends Error {
|
|
28
|
+
operation;
|
|
29
|
+
timeoutMs;
|
|
30
|
+
endpoint;
|
|
31
|
+
name = 'IdentityTokenRequestTimeoutError';
|
|
32
|
+
constructor(operation, timeoutMs, endpoint) {
|
|
33
|
+
super(`${operation} request to ${endpoint} did not complete within ${timeoutMs}ms`);
|
|
34
|
+
this.operation = operation;
|
|
35
|
+
this.timeoutMs = timeoutMs;
|
|
36
|
+
this.endpoint = endpoint;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.IdentityTokenRequestTimeoutError = IdentityTokenRequestTimeoutError;
|
|
40
|
+
function resolveTokenRequestTimeoutMs(configured) {
|
|
41
|
+
if (configured === undefined) {
|
|
42
|
+
return exports.DEFAULT_TOKEN_REQUEST_TIMEOUT_MS;
|
|
43
|
+
}
|
|
44
|
+
if (typeof configured !== 'number' ||
|
|
45
|
+
!Number.isInteger(configured) ||
|
|
46
|
+
configured <= 0) {
|
|
47
|
+
throw new Error(`[IdentityBootstrapService] Invalid IdentityBootstrapConfig: ` +
|
|
48
|
+
`'tokenRequestTimeoutMs' must be a positive integer number of ` +
|
|
49
|
+
`milliseconds, got ${JSON.stringify(configured)}.`);
|
|
50
|
+
}
|
|
51
|
+
return configured;
|
|
52
|
+
}
|
|
53
|
+
function describeEndpoint(url) {
|
|
54
|
+
try {
|
|
55
|
+
const parsed = new URL(url);
|
|
56
|
+
return `${parsed.origin}${parsed.pathname}`;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return '<unparseable endpoint>';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function withTokenRequestDeadline(operation, endpoint, timeoutMs, work) {
|
|
63
|
+
const deadline = AbortSignal.timeout(timeoutMs);
|
|
64
|
+
try {
|
|
65
|
+
return await work(deadline);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (deadline.aborted) {
|
|
69
|
+
throw new IdentityTokenRequestTimeoutError(operation, timeoutMs, describeEndpoint(endpoint));
|
|
70
|
+
}
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function awaitWithCallerSignal(shared, operation, signal) {
|
|
75
|
+
if (!signal) {
|
|
76
|
+
return shared;
|
|
77
|
+
}
|
|
78
|
+
if (signal.aborted) {
|
|
79
|
+
shared.catch(() => undefined);
|
|
80
|
+
return Promise.reject(new IdentityTokenWaitAbortedError(operation, signal.reason));
|
|
81
|
+
}
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
const onAbort = () => {
|
|
84
|
+
reject(new IdentityTokenWaitAbortedError(operation, signal.reason));
|
|
85
|
+
};
|
|
86
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
87
|
+
shared.then((value) => {
|
|
88
|
+
signal.removeEventListener('abort', onAbort);
|
|
89
|
+
resolve(value);
|
|
90
|
+
}, (error) => {
|
|
91
|
+
signal.removeEventListener('abort', onAbort);
|
|
92
|
+
reject(error);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=token-acquisition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-acquisition.js","sourceRoot":"","sources":["../../src/nestjs/token-acquisition.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -187,6 +187,34 @@ export interface ScopedClaimTokenResponse extends ScopedClaimTokenRequest {
|
|
|
187
187
|
expiresIn: number;
|
|
188
188
|
tokenType: 'Bearer';
|
|
189
189
|
}
|
|
190
|
+
export declare enum DelegationActorKind {
|
|
191
|
+
Agent = "agent",
|
|
192
|
+
Workload = "workload"
|
|
193
|
+
}
|
|
194
|
+
export interface CreateDelegationRequest {
|
|
195
|
+
subjectContext?: string;
|
|
196
|
+
parentId?: string;
|
|
197
|
+
actor: {
|
|
198
|
+
id: string;
|
|
199
|
+
kind: DelegationActorKind;
|
|
200
|
+
};
|
|
201
|
+
presenterPrincipalId: string;
|
|
202
|
+
organizationId?: string;
|
|
203
|
+
expiresAt: string;
|
|
204
|
+
realm?: string;
|
|
205
|
+
}
|
|
206
|
+
export interface DelegationRecordResponse {
|
|
207
|
+
id: string;
|
|
208
|
+
subjectPrincipalId: string;
|
|
209
|
+
organizationId: string | null;
|
|
210
|
+
expiresAt: string;
|
|
211
|
+
parentId: string | null;
|
|
212
|
+
}
|
|
213
|
+
export interface DelegatedContextResponse {
|
|
214
|
+
context: string;
|
|
215
|
+
expiresIn: number;
|
|
216
|
+
expiresAt: string;
|
|
217
|
+
}
|
|
190
218
|
export interface ApiEnvelope<T> {
|
|
191
219
|
data: T;
|
|
192
220
|
}
|
package/dist/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ORG_ADMIN_ROLES = exports.OrgRole = exports.SystemOrgEnsureOutcome = exports.InternalTokenScope = void 0;
|
|
3
|
+
exports.DelegationActorKind = exports.ORG_ADMIN_ROLES = exports.OrgRole = exports.SystemOrgEnsureOutcome = exports.InternalTokenScope = void 0;
|
|
4
4
|
var InternalTokenScope;
|
|
5
5
|
(function (InternalTokenScope) {
|
|
6
6
|
InternalTokenScope["SINGLE_REALM"] = "SINGLE_REALM";
|
|
@@ -23,4 +23,9 @@ exports.ORG_ADMIN_ROLES = new Set([
|
|
|
23
23
|
OrgRole.ORG_OWNER,
|
|
24
24
|
OrgRole.ORG_ADMIN,
|
|
25
25
|
]);
|
|
26
|
+
var DelegationActorKind;
|
|
27
|
+
(function (DelegationActorKind) {
|
|
28
|
+
DelegationActorKind["Agent"] = "agent";
|
|
29
|
+
DelegationActorKind["Workload"] = "workload";
|
|
30
|
+
})(DelegationActorKind || (exports.DelegationActorKind = DelegationActorKind = {}));
|
|
26
31
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAiBA,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,mDAA6B,CAAA;IAC7B,iDAA2B,CAAA;IAC3B,mEAA6C,CAAA;AAC/C,CAAC,EAJW,kBAAkB,kCAAlB,kBAAkB,QAI7B;AAqHD,IAAY,sBAOX;AAPD,WAAY,sBAAsB;IAEhC,6CAAmB,CAAA;IAEnB,4DAAkC,CAAA;IAElC,iDAAuB,CAAA;AACzB,CAAC,EAPW,sBAAsB,sCAAtB,sBAAsB,QAOjC;AA8HD,IAAY,OAIX;AAJD,WAAY,OAAO;IACjB,kCAAuB,CAAA;IACvB,kCAAuB,CAAA;IACvB,oCAAyB,CAAA;AAC3B,CAAC,EAJW,OAAO,uBAAP,OAAO,QAIlB;AAGY,QAAA,eAAe,GAAyB,IAAI,GAAG,CAAC;IAC3D,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;CAClB,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAiBA,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,mDAA6B,CAAA;IAC7B,iDAA2B,CAAA;IAC3B,mEAA6C,CAAA;AAC/C,CAAC,EAJW,kBAAkB,kCAAlB,kBAAkB,QAI7B;AAqHD,IAAY,sBAOX;AAPD,WAAY,sBAAsB;IAEhC,6CAAmB,CAAA;IAEnB,4DAAkC,CAAA;IAElC,iDAAuB,CAAA;AACzB,CAAC,EAPW,sBAAsB,sCAAtB,sBAAsB,QAOjC;AA8HD,IAAY,OAIX;AAJD,WAAY,OAAO;IACjB,kCAAuB,CAAA;IACvB,kCAAuB,CAAA;IACvB,oCAAyB,CAAA;AAC3B,CAAC,EAJW,OAAO,uBAAP,OAAO,QAIlB;AAGY,QAAA,eAAe,GAAyB,IAAI,GAAG,CAAC;IAC3D,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;CAClB,CAAC,CAAC;AA6KH,IAAY,mBAGX;AAHD,WAAY,mBAAmB;IAC7B,sCAAe,CAAA;IACf,4CAAqB,CAAA;AACvB,CAAC,EAHW,mBAAmB,mCAAnB,mBAAmB,QAG9B"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface WorkloadContextConfig {
|
|
2
|
+
readonly identityApiUrl: string;
|
|
3
|
+
readonly realm: string;
|
|
4
|
+
readonly audience: string;
|
|
5
|
+
readonly organizationId?: string;
|
|
6
|
+
readonly readCredential: () => Promise<string>;
|
|
7
|
+
readonly refreshBeforeExpirySeconds?: number;
|
|
8
|
+
readonly fetch?: typeof fetch;
|
|
9
|
+
readonly now?: () => number;
|
|
10
|
+
}
|
|
11
|
+
export declare class WorkloadContextError extends Error {
|
|
12
|
+
readonly code?: string | undefined;
|
|
13
|
+
readonly status?: number | undefined;
|
|
14
|
+
constructor(message: string, code?: string | undefined, status?: number | undefined);
|
|
15
|
+
}
|
|
16
|
+
export declare function fileCredentialReader(path: string, read?: (path: string) => Promise<string>): () => Promise<string>;
|
|
17
|
+
export declare class WorkloadContextSource {
|
|
18
|
+
private readonly config;
|
|
19
|
+
private cached;
|
|
20
|
+
private inflight;
|
|
21
|
+
private readonly refreshBeforeMs;
|
|
22
|
+
private readonly fetchImpl;
|
|
23
|
+
private readonly now;
|
|
24
|
+
constructor(config: WorkloadContextConfig);
|
|
25
|
+
getContext(): Promise<string>;
|
|
26
|
+
private fetchContext;
|
|
27
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WorkloadContextSource = exports.WorkloadContextError = void 0;
|
|
4
|
+
exports.fileCredentialReader = fileCredentialReader;
|
|
5
|
+
const promises_1 = require("node:fs/promises");
|
|
6
|
+
class WorkloadContextError extends Error {
|
|
7
|
+
code;
|
|
8
|
+
status;
|
|
9
|
+
constructor(message, code, status) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.status = status;
|
|
13
|
+
this.name = 'WorkloadContextError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.WorkloadContextError = WorkloadContextError;
|
|
17
|
+
function fileCredentialReader(path, read = (p) => (0, promises_1.readFile)(p, 'utf8')) {
|
|
18
|
+
return async () => {
|
|
19
|
+
const content = (await read(path)).trim();
|
|
20
|
+
if (content === '') {
|
|
21
|
+
throw new WorkloadContextError(`The attestation file '${path}' is empty.`);
|
|
22
|
+
}
|
|
23
|
+
return content;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const DEFAULT_REFRESH_BEFORE_EXPIRY_SECONDS = 60;
|
|
27
|
+
class WorkloadContextSource {
|
|
28
|
+
config;
|
|
29
|
+
cached = null;
|
|
30
|
+
inflight = null;
|
|
31
|
+
refreshBeforeMs;
|
|
32
|
+
fetchImpl;
|
|
33
|
+
now;
|
|
34
|
+
constructor(config) {
|
|
35
|
+
this.config = config;
|
|
36
|
+
for (const field of ['identityApiUrl', 'realm', 'audience']) {
|
|
37
|
+
const value = config[field];
|
|
38
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
39
|
+
throw new WorkloadContextError(`WorkloadContextConfig.${field} must be a non-empty string.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (typeof config.readCredential !== 'function') {
|
|
43
|
+
throw new WorkloadContextError('WorkloadContextConfig.readCredential must be a function.');
|
|
44
|
+
}
|
|
45
|
+
const refresh = config.refreshBeforeExpirySeconds ?? DEFAULT_REFRESH_BEFORE_EXPIRY_SECONDS;
|
|
46
|
+
if (!Number.isInteger(refresh) || refresh < 0) {
|
|
47
|
+
throw new WorkloadContextError('WorkloadContextConfig.refreshBeforeExpirySeconds must be a non-negative integer.');
|
|
48
|
+
}
|
|
49
|
+
this.refreshBeforeMs = refresh * 1000;
|
|
50
|
+
this.fetchImpl = config.fetch ?? fetch;
|
|
51
|
+
this.now = config.now ?? Date.now;
|
|
52
|
+
}
|
|
53
|
+
async getContext() {
|
|
54
|
+
if (this.cached !== null &&
|
|
55
|
+
this.now() < this.cached.expiresAtMs - this.refreshBeforeMs) {
|
|
56
|
+
return this.cached.context;
|
|
57
|
+
}
|
|
58
|
+
if (this.inflight === null) {
|
|
59
|
+
const started = this.fetchContext().finally(() => {
|
|
60
|
+
if (this.inflight === started) {
|
|
61
|
+
this.inflight = null;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
this.inflight = started;
|
|
65
|
+
}
|
|
66
|
+
return this.inflight;
|
|
67
|
+
}
|
|
68
|
+
async fetchContext() {
|
|
69
|
+
let credential;
|
|
70
|
+
try {
|
|
71
|
+
credential = await this.config.readCredential();
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
throw error instanceof WorkloadContextError
|
|
75
|
+
? error
|
|
76
|
+
: new WorkloadContextError(`The workload attestation could not be read: ${String(error)}`);
|
|
77
|
+
}
|
|
78
|
+
const url = `${this.config.identityApiUrl.replace(/\/+$/, '')}/internal/workload-context`;
|
|
79
|
+
let response;
|
|
80
|
+
try {
|
|
81
|
+
response = await this.fetchImpl(url, {
|
|
82
|
+
method: 'POST',
|
|
83
|
+
headers: { 'content-type': 'application/json' },
|
|
84
|
+
body: JSON.stringify({
|
|
85
|
+
credential,
|
|
86
|
+
audience: this.config.audience,
|
|
87
|
+
realm: this.config.realm,
|
|
88
|
+
...(this.config.organizationId !== undefined
|
|
89
|
+
? { organizationId: this.config.organizationId }
|
|
90
|
+
: {}),
|
|
91
|
+
}),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
throw new WorkloadContextError(`The identity boundary could not be reached: ${String(error)}`);
|
|
96
|
+
}
|
|
97
|
+
let body;
|
|
98
|
+
try {
|
|
99
|
+
body = await response.json();
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
body = undefined;
|
|
103
|
+
}
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
const refusal = body
|
|
106
|
+
?.error;
|
|
107
|
+
throw new WorkloadContextError(`The identity boundary refused the workload context (HTTP ${response.status})` +
|
|
108
|
+
(typeof refusal?.message === 'string' ? `: ${refusal.message}` : '.'), typeof refusal?.code === 'string' ? refusal.code : undefined, response.status);
|
|
109
|
+
}
|
|
110
|
+
const answer = body?.data;
|
|
111
|
+
const expiresAtMs = typeof answer?.expiresAt === 'string' ? Date.parse(answer.expiresAt) : NaN;
|
|
112
|
+
if (typeof answer?.context !== 'string' ||
|
|
113
|
+
answer.context === '' ||
|
|
114
|
+
Number.isNaN(expiresAtMs)) {
|
|
115
|
+
throw new WorkloadContextError('The identity boundary answered without a context and its expiry.');
|
|
116
|
+
}
|
|
117
|
+
this.cached = { context: answer.context, expiresAtMs };
|
|
118
|
+
return answer.context;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.WorkloadContextSource = WorkloadContextSource;
|
|
122
|
+
//# sourceMappingURL=workload-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workload-context.js","sourceRoot":"","sources":["../src/workload-context.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xemahq/identity-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "NestJS client library and standalone HTTP client for Identity API - service registration, credential management, and JWT token lifecycle",
|
|
5
5
|
"author": "Neuralchowder Inc. <developer@xema.dev> (https://xema.dev)",
|
|
6
6
|
"license": "LicenseRef-Xema-BSL-1.1",
|