@xemahq/authorization-internal-api-client 0.4.29 → 0.5.2
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/custom-fetch.d.ts +37 -8
- package/dist/custom-fetch.js +176 -16
- package/dist/models/assignRoleDto.d.ts +1 -1
- package/dist/models/authorityRowOwnerSpaceKind.d.ts +13 -0
- package/dist/models/authorityRowOwnerSpaceKind.js +12 -0
- package/dist/models/capabilityGrantDto.d.ts +8 -2
- package/dist/models/index.d.ts +2 -0
- package/dist/models/index.js +2 -0
- package/dist/models/openCapabilityAuthorityRequestDtoSubjectKind.d.ts +1 -0
- package/dist/models/openCapabilityAuthorityRequestDtoSubjectKind.js +1 -0
- package/dist/models/policyActingForDto.d.ts +10 -0
- package/dist/models/policyCheckRequestDto.d.ts +8 -0
- package/dist/models/policyDelegatedAuthorityDto.d.ts +25 -0
- package/dist/models/policyDelegatedAuthorityDto.js +2 -0
- package/dist/models/roleDto.d.ts +8 -1
- package/dist/models/subjectKind.d.ts +1 -0
- package/dist/models/subjectKind.js +1 -0
- package/package.json +2 -2
package/dist/custom-fetch.d.ts
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Configurable fetch wrapper for Orval-generated clients.
|
|
3
3
|
*
|
|
4
|
-
* GENERATED by `@xemahq/api-client-generator` —
|
|
5
|
-
* the fleet ships this file byte-for-byte; a
|
|
6
|
-
*
|
|
7
|
-
* differently from all of its siblings.
|
|
8
|
-
*
|
|
4
|
+
* AUTO-GENERATED by `@xemahq/api-client-generator` — DO NOT EDIT. Every client
|
|
5
|
+
* in the fleet ships this file byte-for-byte; a hand edit is erased by the next
|
|
6
|
+
* regeneration and, until then, makes this one client speak to the platform
|
|
7
|
+
* differently from all of its siblings.
|
|
8
|
+
*
|
|
9
|
+
* Canonical source: `CANONICAL_CUSTOM_FETCH` in
|
|
10
|
+
* `packages/sdks/api-client-generator/src/lib/custom-fetch-template.ts`
|
|
11
|
+
* (repository `xema-kernel-sdk`). Change it there.
|
|
12
|
+
*
|
|
13
|
+
* Regenerate, from the root of THIS repository:
|
|
14
|
+
* pnpm --filter <owning-service> run openapi
|
|
15
|
+
* pnpm --filter <owning-service> run client:generate
|
|
16
|
+
* A mirror of this client under `xema-host-web` is not regenerated there: it
|
|
17
|
+
* is written by the frontend bridge, `tooling/frontend-bridge` in the
|
|
18
|
+
* xema-monorepo aggregator.
|
|
9
19
|
*
|
|
10
20
|
* Consumers must call `configureClient()` before using any endpoint function.
|
|
11
21
|
* The baseUrl is prepended to the relative paths generated by Orval.
|
|
@@ -31,6 +41,21 @@ export interface RetryNotice {
|
|
|
31
41
|
/** HTTP method being re-requested. */
|
|
32
42
|
method: string;
|
|
33
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Per-request context handed to the callbacks this transport awaits BEFORE it
|
|
46
|
+
* sends the request.
|
|
47
|
+
*
|
|
48
|
+
* `signal` is the request's own `AbortSignal` (`options.signal`). It is the
|
|
49
|
+
* CALLER's cancellation: a callback may use it to stop work that is private to
|
|
50
|
+
* this request, but a callback serving several requests from one shared,
|
|
51
|
+
* single-flight acquisition (a token refresh) must NOT abort that shared work
|
|
52
|
+
* because one caller stopped — every other caller waiting on it would fail.
|
|
53
|
+
* The transport stops WAITING on its own regardless, so a callback that
|
|
54
|
+
* ignores the signal still cannot hold an aborted request.
|
|
55
|
+
*/
|
|
56
|
+
export interface ClientCallbackOptions {
|
|
57
|
+
signal?: AbortSignal;
|
|
58
|
+
}
|
|
34
59
|
export interface ClientConfig {
|
|
35
60
|
/**
|
|
36
61
|
* Static base URL (e.g. 'http://localhost:3140') — no trailing slash.
|
|
@@ -42,9 +67,13 @@ export interface ClientConfig {
|
|
|
42
67
|
* the service registry on EVERY request (boot-order-safe). Wired by
|
|
43
68
|
* `configureOrvalClientResolved` from `@xemahq/platform-common`.
|
|
44
69
|
*/
|
|
45
|
-
baseUrlResolver?: () => string | Promise<string>;
|
|
46
|
-
/**
|
|
47
|
-
|
|
70
|
+
baseUrlResolver?: (options?: ClientCallbackOptions) => string | Promise<string>;
|
|
71
|
+
/**
|
|
72
|
+
* Optional async callback to get an auth token. Auto-sets Authorization
|
|
73
|
+
* header on every request. Receives the request's signal — see
|
|
74
|
+
* {@link ClientCallbackOptions} for what it may and may not abort.
|
|
75
|
+
*/
|
|
76
|
+
getAuthToken?: (options?: ClientCallbackOptions) => Promise<string>;
|
|
48
77
|
/** Optional callback returning headers to inject on every request. Per-call headers take precedence. */
|
|
49
78
|
getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
|
|
50
79
|
/**
|
package/dist/custom-fetch.js
CHANGED
|
@@ -2,11 +2,21 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Configurable fetch wrapper for Orval-generated clients.
|
|
4
4
|
*
|
|
5
|
-
* GENERATED by `@xemahq/api-client-generator` —
|
|
6
|
-
* the fleet ships this file byte-for-byte; a
|
|
7
|
-
*
|
|
8
|
-
* differently from all of its siblings.
|
|
9
|
-
*
|
|
5
|
+
* AUTO-GENERATED by `@xemahq/api-client-generator` — DO NOT EDIT. Every client
|
|
6
|
+
* in the fleet ships this file byte-for-byte; a hand edit is erased by the next
|
|
7
|
+
* regeneration and, until then, makes this one client speak to the platform
|
|
8
|
+
* differently from all of its siblings.
|
|
9
|
+
*
|
|
10
|
+
* Canonical source: `CANONICAL_CUSTOM_FETCH` in
|
|
11
|
+
* `packages/sdks/api-client-generator/src/lib/custom-fetch-template.ts`
|
|
12
|
+
* (repository `xema-kernel-sdk`). Change it there.
|
|
13
|
+
*
|
|
14
|
+
* Regenerate, from the root of THIS repository:
|
|
15
|
+
* pnpm --filter <owning-service> run openapi
|
|
16
|
+
* pnpm --filter <owning-service> run client:generate
|
|
17
|
+
* A mirror of this client under `xema-host-web` is not regenerated there: it
|
|
18
|
+
* is written by the frontend bridge, `tooling/frontend-bridge` in the
|
|
19
|
+
* xema-monorepo aggregator.
|
|
10
20
|
*
|
|
11
21
|
* Consumers must call `configureClient()` before using any endpoint function.
|
|
12
22
|
* The baseUrl is prepended to the relative paths generated by Orval.
|
|
@@ -77,6 +87,11 @@ class ClientError extends Error {
|
|
|
77
87
|
// identity marker, not payload.
|
|
78
88
|
Object.defineProperty(this, CLIENT_ERROR_BRAND, { value: true });
|
|
79
89
|
}
|
|
90
|
+
// `override` because the member shadows `Function.prototype[Symbol.hasInstance]`,
|
|
91
|
+
// which a class constructor inherits: TypeScript 5.9+ reports TS4114 without it
|
|
92
|
+
// under `noImplicitOverride`. Measured to compile on 5.5.4, 5.9.3, 6.0.3 and
|
|
93
|
+
// 7.0.2 with the flag on AND off — pinned by
|
|
94
|
+
// tests/custom-fetch-compiles-standalone.test.cjs.
|
|
80
95
|
static [Symbol.hasInstance](candidate) {
|
|
81
96
|
return (typeof candidate === 'object' &&
|
|
82
97
|
candidate !== null &&
|
|
@@ -85,6 +100,50 @@ class ClientError extends Error {
|
|
|
85
100
|
}
|
|
86
101
|
exports.ClientError = ClientError;
|
|
87
102
|
let clientConfig = null;
|
|
103
|
+
/**
|
|
104
|
+
* THE MOUNT SCOPE — how one process can host several services without their
|
|
105
|
+
* clients speaking for each other.
|
|
106
|
+
*
|
|
107
|
+
* `clientConfig` below is a MODULE global, and in a single-service process
|
|
108
|
+
* that is correct: one writer, one configuration. Compose two services into one
|
|
109
|
+
* process and both call `configureClient` on THIS SAME module instance, so the
|
|
110
|
+
* second overwrites the first and every outbound call from BOTH services leaves
|
|
111
|
+
* as whichever wired itself last — wrong base URL, and, because
|
|
112
|
+
* `getAuthToken` is part of the config, WRONG BEARER. That is one tenant's
|
|
113
|
+
* service calling a peer holding another tenant's credential, and it is silent.
|
|
114
|
+
*
|
|
115
|
+
* A composing host installs a hook under this well-known symbol that answers
|
|
116
|
+
* one question: WHICH MOUNT is currently on the stack. Nothing else crosses.
|
|
117
|
+
* `configureClient` then files the config under that mount, and
|
|
118
|
+
* `getClientConfig` reads it back out under the same key.
|
|
119
|
+
*
|
|
120
|
+
* Three properties make this safe rather than clever:
|
|
121
|
+
*
|
|
122
|
+
* - The CONFIG is still built by the mount's own wiring, exactly as today.
|
|
123
|
+
* The hook never supplies one. So a mount's base URL and bearer are
|
|
124
|
+
* resolved FROM THE MOUNT; the scope only decides which drawer they go in.
|
|
125
|
+
* A hook that RETURNED configuration would be a mount taking its identity
|
|
126
|
+
* from ambient storage a neighbour can write — the inversion to refuse.
|
|
127
|
+
* - The key is an OPAQUE OBJECT and the store is a `WeakMap`, so a mount's
|
|
128
|
+
* configuration becomes unreachable when the host drops the mount, and no
|
|
129
|
+
* client can enumerate the mounts or reach a sibling's entry.
|
|
130
|
+
* - With NO hook installed — every process in the fleet today — both
|
|
131
|
+
* functions behave exactly as they did before this existed.
|
|
132
|
+
*
|
|
133
|
+
* `Symbol.for` is the seam because a generated client must keep its
|
|
134
|
+
* dependency surface at zero and a host cannot enumerate the clients a process
|
|
135
|
+
* happens to load. It is the same instrument, and the same reasoning, as the
|
|
136
|
+
* `ClientError` brand above.
|
|
137
|
+
*/
|
|
138
|
+
const XEMA_CLIENT_CONFIG_SCOPE = Symbol.for('xema.client-config-scope');
|
|
139
|
+
function mountScopeHook() {
|
|
140
|
+
const hook = globalThis[XEMA_CLIENT_CONFIG_SCOPE];
|
|
141
|
+
return typeof hook === 'function' ? hook : undefined;
|
|
142
|
+
}
|
|
143
|
+
function currentMountKey() {
|
|
144
|
+
return mountScopeHook()?.();
|
|
145
|
+
}
|
|
146
|
+
const perMountConfig = new WeakMap();
|
|
88
147
|
function configureClient(config) {
|
|
89
148
|
// Fail at WIRING time, not on the request that happens to be retried. A
|
|
90
149
|
// client configured to retry without an observer is the exact defect this
|
|
@@ -94,9 +153,38 @@ function configureClient(config) {
|
|
|
94
153
|
'reports is indistinguishable from a slow server, which is how two ' +
|
|
95
154
|
'silent re-attempts were read as a 3,312ms call.');
|
|
96
155
|
}
|
|
156
|
+
const hook = mountScopeHook();
|
|
157
|
+
if (hook !== undefined) {
|
|
158
|
+
const mount = hook();
|
|
159
|
+
if (mount === undefined) {
|
|
160
|
+
// A composing host is installed and no member is on the stack, so this
|
|
161
|
+
// configuration belongs to NO member. Filing it in the module global
|
|
162
|
+
// would hand it to every member that did not configure this client —
|
|
163
|
+
// someone else's base URL and bearer, silently.
|
|
164
|
+
throw new Error('configureClient: called in a composed process outside every member. ' +
|
|
165
|
+
'Configure the client inside the member that uses it (its providers ' +
|
|
166
|
+
'and factories already run there).');
|
|
167
|
+
}
|
|
168
|
+
perMountConfig.set(mount, config);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
97
171
|
clientConfig = config;
|
|
98
172
|
}
|
|
99
173
|
function getClientConfig() {
|
|
174
|
+
const mount = currentMountKey();
|
|
175
|
+
if (mount !== undefined) {
|
|
176
|
+
const scoped = perMountConfig.get(mount);
|
|
177
|
+
if (scoped) {
|
|
178
|
+
return scoped;
|
|
179
|
+
}
|
|
180
|
+
// A member that never configured THIS client behaves exactly like a
|
|
181
|
+
// dedicated service that did not either: it is refused. It used to fall
|
|
182
|
+
// through to the module global, which in a composed process can only have
|
|
183
|
+
// been written by some OTHER code — so the member called peers under a
|
|
184
|
+
// base URL and bearer that were never its own.
|
|
185
|
+
throw new Error('Client not configured for this member. Call configureClient({ baseUrl }) ' +
|
|
186
|
+
'inside the member before using endpoint functions.');
|
|
187
|
+
}
|
|
100
188
|
if (!clientConfig) {
|
|
101
189
|
throw new Error('Client not configured. Call configureClient({ baseUrl }) before using endpoint functions.');
|
|
102
190
|
}
|
|
@@ -155,11 +243,64 @@ const CORRELATION_ID_HEADER = 'X-Correlation-Id';
|
|
|
155
243
|
const BASE_BACKOFF_MS = 1000;
|
|
156
244
|
/** Ceiling on a single backoff, however many attempts have elapsed. */
|
|
157
245
|
const MAX_BACKOFF_MS = 30_000;
|
|
158
|
-
|
|
246
|
+
/*
|
|
247
|
+
* CALLER CANCELLATION REACHES EVERY WAIT BEFORE THE REQUEST IS SENT.
|
|
248
|
+
*
|
|
249
|
+
* `fetch` always honoured `options.signal`, but everything this transport
|
|
250
|
+
* awaits BEFORE `fetch` — base-URL resolution, the header callbacks, the auth
|
|
251
|
+
* token — did not, so a caller that aborted while a token was being minted sat
|
|
252
|
+
* out the mint and then, at best, had its request refused. The only way to
|
|
253
|
+
* cancel that wait was a process-wide interceptor aborting every outbound
|
|
254
|
+
* request, which also aborts a SHARED single-flight token refresh and so fails
|
|
255
|
+
* every other caller waiting on it.
|
|
256
|
+
*
|
|
257
|
+
* So each pre-send wait is RACED against the signal: the caller stops waiting
|
|
258
|
+
* at once, and the work it was waiting on carries on for anybody else. The
|
|
259
|
+
* rejection is the signal's own reason — exactly what `fetch` rejects with —
|
|
260
|
+
* so a caller sees ONE abort shape whenever it aborts. An aborted request is
|
|
261
|
+
* never retried. Without a signal nothing here changes.
|
|
262
|
+
*/
|
|
263
|
+
function abortedReason(signal) {
|
|
264
|
+
// `abort()` with no argument sets a DOMException reason, so this is only
|
|
265
|
+
// ever `undefined` for a hand-built signal; say so rather than throw it.
|
|
266
|
+
return signal.reason ?? new DOMException('This operation was aborted', 'AbortError');
|
|
267
|
+
}
|
|
268
|
+
function throwIfAborted(signal) {
|
|
269
|
+
if (signal?.aborted) {
|
|
270
|
+
throw abortedReason(signal);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function raceAbort(pending, signal) {
|
|
274
|
+
const promise = Promise.resolve(pending);
|
|
275
|
+
if (!signal) {
|
|
276
|
+
return promise;
|
|
277
|
+
}
|
|
278
|
+
if (signal.aborted) {
|
|
279
|
+
promise.catch(() => undefined);
|
|
280
|
+
return Promise.reject(abortedReason(signal));
|
|
281
|
+
}
|
|
282
|
+
return new Promise((resolve, reject) => {
|
|
283
|
+
const onAbort = () => {
|
|
284
|
+
// The pending work may be shared; it carries on, and its eventual
|
|
285
|
+
// rejection must not surface as an unhandled one on this side.
|
|
286
|
+
promise.catch(() => undefined);
|
|
287
|
+
reject(abortedReason(signal));
|
|
288
|
+
};
|
|
289
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
290
|
+
promise.then((value) => {
|
|
291
|
+
signal.removeEventListener('abort', onAbort);
|
|
292
|
+
resolve(value);
|
|
293
|
+
}, (err) => {
|
|
294
|
+
signal.removeEventListener('abort', onAbort);
|
|
295
|
+
reject(err);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
async function buildHeaders(config, callerHeaders, signal) {
|
|
159
300
|
const headers = new Headers(callerHeaders);
|
|
160
301
|
// Global headers from config (caller-provided headers take precedence)
|
|
161
302
|
if (config.getHeaders) {
|
|
162
|
-
const globalHeaders = await
|
|
303
|
+
const globalHeaders = await raceAbort(config.getHeaders(), signal);
|
|
163
304
|
for (const [key, value] of Object.entries(globalHeaders)) {
|
|
164
305
|
if (!headers.has(key)) {
|
|
165
306
|
headers.set(key, value);
|
|
@@ -178,14 +319,14 @@ async function buildHeaders(config, callerHeaders) {
|
|
|
178
319
|
// receiver mints and a new trace begins, which is the truthful outcome when
|
|
179
320
|
// there is nothing to continue.
|
|
180
321
|
if (config.getCorrelationId && !headers.has(CORRELATION_ID_HEADER)) {
|
|
181
|
-
const correlationId = await
|
|
322
|
+
const correlationId = await raceAbort(config.getCorrelationId(), signal);
|
|
182
323
|
if (correlationId) {
|
|
183
324
|
headers.set(CORRELATION_ID_HEADER, correlationId);
|
|
184
325
|
}
|
|
185
326
|
}
|
|
186
327
|
// Auth token (caller or global headers take precedence)
|
|
187
328
|
if (config.getAuthToken && !headers.has('Authorization')) {
|
|
188
|
-
const token = await config.getAuthToken();
|
|
329
|
+
const token = await raceAbort(config.getAuthToken(signal ? { signal } : undefined), signal);
|
|
189
330
|
headers.set('Authorization', `Bearer ${token}`);
|
|
190
331
|
}
|
|
191
332
|
return headers;
|
|
@@ -215,8 +356,10 @@ async function buildHeaders(config, callerHeaders) {
|
|
|
215
356
|
*/
|
|
216
357
|
const customFetch = async (url, options) => {
|
|
217
358
|
const config = getClientConfig();
|
|
359
|
+
const signal = options.signal ?? undefined;
|
|
360
|
+
throwIfAborted(signal);
|
|
218
361
|
const base = config.baseUrlResolver
|
|
219
|
-
? await config.baseUrlResolver()
|
|
362
|
+
? await raceAbort(config.baseUrlResolver(signal ? { signal } : undefined), signal)
|
|
220
363
|
: config.baseUrl;
|
|
221
364
|
if (base === undefined) {
|
|
222
365
|
throw new Error('Client not configured: set baseUrl or baseUrlResolver via configureClient().');
|
|
@@ -228,7 +371,7 @@ const customFetch = async (url, options) => {
|
|
|
228
371
|
// re-sending would replay the identical failing request with the identical
|
|
229
372
|
// credential: one wasted round trip, plus a global refresh nobody asked for.
|
|
230
373
|
const callerSuppliedAuth = new Headers(options.headers).has('Authorization');
|
|
231
|
-
const headers = await buildHeaders(config, options.headers);
|
|
374
|
+
const headers = await buildHeaders(config, options.headers, signal);
|
|
232
375
|
const requestInit = { ...options, headers };
|
|
233
376
|
let delay = BASE_BACKOFF_MS;
|
|
234
377
|
for (let attempt = 0;; attempt++) {
|
|
@@ -237,8 +380,8 @@ const customFetch = async (url, options) => {
|
|
|
237
380
|
config.onUnauthorized &&
|
|
238
381
|
!callerSuppliedAuth &&
|
|
239
382
|
attempt === 0) {
|
|
240
|
-
await config.onUnauthorized();
|
|
241
|
-
const refreshedHeaders = await buildHeaders(config, options.headers);
|
|
383
|
+
await raceAbort(config.onUnauthorized(), signal);
|
|
384
|
+
const refreshedHeaders = await buildHeaders(config, options.headers, signal);
|
|
242
385
|
const retryResponse = await fetch(fullUrl, {
|
|
243
386
|
...options,
|
|
244
387
|
headers: refreshedHeaders,
|
|
@@ -270,7 +413,7 @@ const customFetch = async (url, options) => {
|
|
|
270
413
|
url: fullUrl,
|
|
271
414
|
method: options.method ?? 'GET',
|
|
272
415
|
});
|
|
273
|
-
await sleep(waitMs);
|
|
416
|
+
await sleep(waitMs, signal);
|
|
274
417
|
delay = Math.min(delay * 2, MAX_BACKOFF_MS);
|
|
275
418
|
}
|
|
276
419
|
};
|
|
@@ -351,7 +494,24 @@ function parseRetryAfter(value) {
|
|
|
351
494
|
function addJitter(delay) {
|
|
352
495
|
return delay + (Math.random() * 2 - 1) * delay * 0.25;
|
|
353
496
|
}
|
|
354
|
-
|
|
355
|
-
|
|
497
|
+
/** A retry backoff; the caller's signal ends it at once and is never retried. */
|
|
498
|
+
function sleep(ms, signal) {
|
|
499
|
+
if (!signal) {
|
|
500
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
501
|
+
}
|
|
502
|
+
if (signal.aborted) {
|
|
503
|
+
return Promise.reject(abortedReason(signal));
|
|
504
|
+
}
|
|
505
|
+
return new Promise((resolve, reject) => {
|
|
506
|
+
const onAbort = () => {
|
|
507
|
+
clearTimeout(timer);
|
|
508
|
+
reject(abortedReason(signal));
|
|
509
|
+
};
|
|
510
|
+
const timer = setTimeout(() => {
|
|
511
|
+
signal.removeEventListener('abort', onAbort);
|
|
512
|
+
resolve();
|
|
513
|
+
}, ms);
|
|
514
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
515
|
+
});
|
|
356
516
|
}
|
|
357
517
|
exports.default = exports.customFetch;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import type { SubjectKind } from './subjectKind.js';
|
|
7
7
|
export interface AssignRoleDto {
|
|
8
8
|
/**
|
|
9
|
-
* The org this assignment is scoped to. For a custom role it must equal the role’s org; for a built-in
|
|
9
|
+
* The org this assignment is scoped to. For a custom role it must equal the role’s org; for a built-in (platform-owned) role it is the real consuming org.
|
|
10
10
|
* @minLength 1
|
|
11
11
|
*/
|
|
12
12
|
orgId: string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated by @xemahq/api-client-generator — do not edit manually.
|
|
3
|
+
* Authorization API
|
|
4
|
+
* OpenAPI spec version: 0.1.1
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Who owns this grant: `system` (the platform — kernel-seeded, shared by every org) or `org`. The admissible subset of the kernel `SpaceKind` for a role or a capability grant.
|
|
8
|
+
*/
|
|
9
|
+
export type AuthorityRowOwnerSpaceKind = typeof AuthorityRowOwnerSpaceKind[keyof typeof AuthorityRowOwnerSpaceKind];
|
|
10
|
+
export declare const AuthorityRowOwnerSpaceKind: {
|
|
11
|
+
readonly system: "system";
|
|
12
|
+
readonly org: "org";
|
|
13
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Generated by @xemahq/api-client-generator — do not edit manually.
|
|
4
|
+
* Authorization API
|
|
5
|
+
* OpenAPI spec version: 0.1.1
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.AuthorityRowOwnerSpaceKind = void 0;
|
|
9
|
+
exports.AuthorityRowOwnerSpaceKind = {
|
|
10
|
+
system: 'system',
|
|
11
|
+
org: 'org',
|
|
12
|
+
};
|
|
@@ -3,13 +3,19 @@
|
|
|
3
3
|
* Authorization API
|
|
4
4
|
* OpenAPI spec version: 0.1.1
|
|
5
5
|
*/
|
|
6
|
+
import type { AuthorityRowOwnerSpaceKind } from './authorityRowOwnerSpaceKind.js';
|
|
6
7
|
import type { BiomePermissionProfile } from './biomePermissionProfile.js';
|
|
7
8
|
import type { GrantConstraintsDto } from './grantConstraintsDto.js';
|
|
8
9
|
import type { SubjectKind } from './subjectKind.js';
|
|
9
10
|
export interface CapabilityGrantDto {
|
|
10
11
|
id: string;
|
|
11
|
-
/**
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* The owning organisation, or null when the PLATFORM owns this grant (`ownerSpaceKind` = system).
|
|
14
|
+
* @nullable
|
|
15
|
+
*/
|
|
16
|
+
orgId: string | null;
|
|
17
|
+
/** Who owns this grant: `system` (the platform — kernel-seeded, shared by every org) or `org`. The admissible subset of the kernel `SpaceKind` for a role or a capability grant. */
|
|
18
|
+
ownerSpaceKind: AuthorityRowOwnerSpaceKind;
|
|
13
19
|
subjectKind: SubjectKind;
|
|
14
20
|
subjectRef: string;
|
|
15
21
|
capability: string;
|
package/dist/models/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './agentProvisionDecision';
|
|
|
5
5
|
export * from './agentProvisionReason';
|
|
6
6
|
export * from './agentReachTier';
|
|
7
7
|
export * from './assignRoleDto';
|
|
8
|
+
export * from './authorityRowOwnerSpaceKind';
|
|
8
9
|
export * from './authorizationCheckRequestDto';
|
|
9
10
|
export * from './authorizationCheckResponseDto';
|
|
10
11
|
export * from './authorizationCheckResponseDtoDataEnvelope';
|
|
@@ -121,6 +122,7 @@ export * from './policyConstraintsDto';
|
|
|
121
122
|
export * from './policyDecisionDto';
|
|
122
123
|
export * from './policyDecisionDtoDataEnvelope';
|
|
123
124
|
export * from './policyDecisionKind';
|
|
125
|
+
export * from './policyDelegatedAuthorityDto';
|
|
124
126
|
export * from './policyEnvironmentDto';
|
|
125
127
|
export * from './policyObligationDto';
|
|
126
128
|
export * from './policyObligationKind';
|
package/dist/models/index.js
CHANGED
|
@@ -22,6 +22,7 @@ __exportStar(require("./agentProvisionDecision"), exports);
|
|
|
22
22
|
__exportStar(require("./agentProvisionReason"), exports);
|
|
23
23
|
__exportStar(require("./agentReachTier"), exports);
|
|
24
24
|
__exportStar(require("./assignRoleDto"), exports);
|
|
25
|
+
__exportStar(require("./authorityRowOwnerSpaceKind"), exports);
|
|
25
26
|
__exportStar(require("./authorizationCheckRequestDto"), exports);
|
|
26
27
|
__exportStar(require("./authorizationCheckResponseDto"), exports);
|
|
27
28
|
__exportStar(require("./authorizationCheckResponseDtoDataEnvelope"), exports);
|
|
@@ -138,6 +139,7 @@ __exportStar(require("./policyConstraintsDto"), exports);
|
|
|
138
139
|
__exportStar(require("./policyDecisionDto"), exports);
|
|
139
140
|
__exportStar(require("./policyDecisionDtoDataEnvelope"), exports);
|
|
140
141
|
__exportStar(require("./policyDecisionKind"), exports);
|
|
142
|
+
__exportStar(require("./policyDelegatedAuthorityDto"), exports);
|
|
141
143
|
__exportStar(require("./policyEnvironmentDto"), exports);
|
|
142
144
|
__exportStar(require("./policyObligationDto"), exports);
|
|
143
145
|
__exportStar(require("./policyObligationKind"), exports);
|
|
@@ -16,4 +16,14 @@ export interface PolicyActingForDto {
|
|
|
16
16
|
* @minLength 1
|
|
17
17
|
*/
|
|
18
18
|
clientId?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Mirrors kernel `ActingForRef.principalId` — the ISSUER-STAMPED,
|
|
21
|
+
* rotation-stable identity-api principal id of this hop (`principal_id`).
|
|
22
|
+
* `resolveActorChainFromClaims` stamps it on every hop whose claims carry
|
|
23
|
+
* one, so a gateway forwarding a verified chain sends it. Undeclared here,
|
|
24
|
+
* `forbidNonWhitelisted` refused the whole policy check with a 400 — which
|
|
25
|
+
* the gateway fails closed on — for any chain containing such a hop.
|
|
26
|
+
* @minLength 1
|
|
27
|
+
*/
|
|
28
|
+
principalId?: string;
|
|
19
29
|
}
|
|
@@ -10,6 +10,7 @@ import type { PolicyCallerDto } from './policyCallerDto.js';
|
|
|
10
10
|
import type { PolicyCapabilityDto } from './policyCapabilityDto.js';
|
|
11
11
|
import type { PolicyCheckRequestDtoAperture } from './policyCheckRequestDtoAperture.js';
|
|
12
12
|
import type { PolicyConstraintsDto } from './policyConstraintsDto.js';
|
|
13
|
+
import type { PolicyDelegatedAuthorityDto } from './policyDelegatedAuthorityDto.js';
|
|
13
14
|
import type { PolicyEnvironmentDto } from './policyEnvironmentDto.js';
|
|
14
15
|
import type { PolicyResourceDto } from './policyResourceDto.js';
|
|
15
16
|
import type { PolicySpaceRefDto } from './policySpaceRefDto.js';
|
|
@@ -31,6 +32,13 @@ export interface PolicyCheckRequestDto {
|
|
|
31
32
|
resource?: PolicyResourceDto;
|
|
32
33
|
constraints?: PolicyConstraintsDto;
|
|
33
34
|
actorChain?: PolicyActingForDto[];
|
|
35
|
+
/**
|
|
36
|
+
* The caller's VERIFIED delegated authority (kernel
|
|
37
|
+
* `ExecutionContext.delegation`). A CEILING, never a grant — see
|
|
38
|
+
* {@link PolicyDelegatedAuthorityDto} and the PDP stage that reads it
|
|
39
|
+
* (`AuthorizationService.applyDelegatedAuthorityCeiling`).
|
|
40
|
+
*/
|
|
41
|
+
delegation?: PolicyDelegatedAuthorityDto;
|
|
34
42
|
/**
|
|
35
43
|
* Opaque credential-binding id already selected for this invocation. Carried
|
|
36
44
|
* on the kernel envelope (a re-checked / replayed context round-trips it), so
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated by @xemahq/api-client-generator — do not edit manually.
|
|
3
|
+
* Authorization API
|
|
4
|
+
* OpenAPI spec version: 0.1.1
|
|
5
|
+
*/
|
|
6
|
+
import type { PolicyActingForDto } from './policyActingForDto.js';
|
|
7
|
+
export interface PolicyDelegatedAuthorityDto {
|
|
8
|
+
/** @minLength 1 */
|
|
9
|
+
delegationId: string;
|
|
10
|
+
actor: PolicyActingForDto;
|
|
11
|
+
/** @minItems 1 */
|
|
12
|
+
actorChain: PolicyActingForDto[];
|
|
13
|
+
/**
|
|
14
|
+
* @minItems 1
|
|
15
|
+
* @items.minLength 1
|
|
16
|
+
*/
|
|
17
|
+
capabilities: string[];
|
|
18
|
+
/**
|
|
19
|
+
* @minItems 1
|
|
20
|
+
* @items.minLength 1
|
|
21
|
+
*/
|
|
22
|
+
resourceScope?: string[];
|
|
23
|
+
/** @minLength 1 */
|
|
24
|
+
authorizedBy?: string;
|
|
25
|
+
}
|
package/dist/models/roleDto.d.ts
CHANGED
|
@@ -3,10 +3,17 @@
|
|
|
3
3
|
* Authorization API
|
|
4
4
|
* OpenAPI spec version: 0.1.1
|
|
5
5
|
*/
|
|
6
|
+
import type { AuthorityRowOwnerSpaceKind } from './authorityRowOwnerSpaceKind.js';
|
|
6
7
|
import type { ResourceManagedBy } from './resourceManagedBy.js';
|
|
7
8
|
export interface RoleDto {
|
|
8
9
|
id: string;
|
|
9
|
-
|
|
10
|
+
/**
|
|
11
|
+
* The owning organisation, or null when the PLATFORM owns this role (`ownerSpaceKind` = system).
|
|
12
|
+
* @nullable
|
|
13
|
+
*/
|
|
14
|
+
orgId: string | null;
|
|
15
|
+
/** Who owns this role: `system` (the platform — kernel-seeded, shared by every org) or `org`. The admissible subset of the kernel `SpaceKind` for a role or a capability grant. */
|
|
16
|
+
ownerSpaceKind: AuthorityRowOwnerSpaceKind;
|
|
10
17
|
slug: string;
|
|
11
18
|
displayName: string;
|
|
12
19
|
/** @nullable */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xemahq/authorization-internal-api-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"service": "authorization-api",
|
|
20
20
|
"biome": "authorization",
|
|
21
21
|
"target": "server",
|
|
22
|
-
"generator": "@xemahq/api-client-generator@1.1
|
|
22
|
+
"generator": "@xemahq/api-client-generator@2.1.1",
|
|
23
23
|
"source": "openapi.internal.json"
|
|
24
24
|
},
|
|
25
25
|
"license": "LicenseRef-Xema-BSL-1.1",
|