@enterprisestandard/core 0.0.20-beta.20260706.1 → 0.0.20
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/index.d.ts +428 -386
- package/dist/index.js +1 -1
- package/dist/server.d.ts +3491 -3136
- package/dist/server.js +1 -1
- package/dist/shared/core-9dvscte3.js +4 -0
- package/package.json +7 -1
- package/dist/shared/core-51h35vdb.js +0 -4
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,13 @@ import { version } from "../package.json";
|
|
|
3
3
|
* Shared types for paginated list operations across stores.
|
|
4
4
|
*
|
|
5
5
|
* List methods return a ListResult with total, count, items, size, page, and pages.
|
|
6
|
-
* Options accept optional start (0-based), limit (page size), and
|
|
6
|
+
* Options accept optional start (0-based), limit (page size), and filter.
|
|
7
|
+
*
|
|
8
|
+
* ORDERING CONTRACT: `list()` does NOT accept a caller-specified sort. Every store MUST return items
|
|
9
|
+
* in a stable, deterministic order (recommended: primary key ascending) so that offset pagination is
|
|
10
|
+
* coherent across pages — page N+1 must continue exactly where page N ended for an unchanged dataset.
|
|
11
|
+
* UI-style arbitrary sorting is the app's concern (sort the returned page, or push ORDER BY into a
|
|
12
|
+
* SQL/search-backed custom store); the SDK only guarantees deterministic paging.
|
|
7
13
|
*/
|
|
8
14
|
/**
|
|
9
15
|
* Result of a paginated list operation.
|
|
@@ -24,13 +30,6 @@ interface ListResult<T> {
|
|
|
24
30
|
/** Total number of pages at the given size. */
|
|
25
31
|
pages: number;
|
|
26
32
|
}
|
|
27
|
-
/** Sort direction for list options. */
|
|
28
|
-
type SortDirection = "asc" | "desc";
|
|
29
|
-
/** Single sort option for paginated list operations. */
|
|
30
|
-
interface SortOptions<TField extends string = string> {
|
|
31
|
-
field: TField;
|
|
32
|
-
direction: SortDirection;
|
|
33
|
-
}
|
|
34
33
|
/**
|
|
35
34
|
* Optional server-side filter for list operations. Stores that understand a field apply it before
|
|
36
35
|
* pagination so callers get correctly-totalled, filtered pages; unknown fields are ignored.
|
|
@@ -40,22 +39,14 @@ interface ListFilter {
|
|
|
40
39
|
requestable?: boolean;
|
|
41
40
|
}
|
|
42
41
|
/** Shared options for paginated list operations. */
|
|
43
|
-
interface ListOptions
|
|
42
|
+
interface ListOptions {
|
|
44
43
|
/** 0-based index of first item. Default 0. */
|
|
45
44
|
start?: number;
|
|
46
45
|
/** Max items to return. Omitted = implementation-defined (InMemory: no limit). */
|
|
47
46
|
limit?: number;
|
|
48
|
-
/** Sort order (applied in array order). */
|
|
49
|
-
sort?: SortOptions<TField>[];
|
|
50
47
|
/** Optional server-side filter applied before pagination. */
|
|
51
48
|
filter?: ListFilter;
|
|
52
49
|
}
|
|
53
|
-
type GroupSortOptions = SortOptions;
|
|
54
|
-
type GroupListOptions = ListOptions;
|
|
55
|
-
type UserSortOptions = SortOptions;
|
|
56
|
-
type UserListOptions = ListOptions;
|
|
57
|
-
type TenantSortOptions = SortOptions;
|
|
58
|
-
type TenantListOptions = ListOptions;
|
|
59
50
|
/**
|
|
60
51
|
* Shared minimal identity fields used to build both the workforce user
|
|
61
52
|
* record (`BaseUser`) and the CIAM customer record (`BaseCustomer`), as well
|
|
@@ -510,22 +501,73 @@ declare const infoLogger: Logger;
|
|
|
510
501
|
* Logger that logs messages warn and error to the console.
|
|
511
502
|
*/
|
|
512
503
|
declare const warnLogger: Logger;
|
|
504
|
+
/** Synchronous, in-memory read surface for one code catalog entity kind. */
|
|
505
|
+
type CodeCatalogNamespace<TEntity> = {
|
|
506
|
+
get(id: string): TEntity | undefined;
|
|
507
|
+
getByExternalId(externalId: string): TEntity | undefined;
|
|
508
|
+
list(): readonly TEntity[];
|
|
509
|
+
};
|
|
510
|
+
/**
|
|
511
|
+
* Normalized, frozen code-declared catalog produced by {@link defineCatalog}. All entities are
|
|
512
|
+
* deep-frozen, id-indexed, and carry `externalId` (defaulted to `id`).
|
|
513
|
+
*/
|
|
514
|
+
type CodeCatalog = {
|
|
515
|
+
groups: CodeCatalogNamespace<Group>;
|
|
516
|
+
roles: CodeCatalogNamespace<Role>;
|
|
517
|
+
permissions: CodeCatalogNamespace<Permission>;
|
|
518
|
+
};
|
|
519
|
+
/** Declarative input for {@link defineCatalog} (plain arrays authored in app code). */
|
|
520
|
+
type CodeCatalogInput = {
|
|
521
|
+
groups?: readonly Group[];
|
|
522
|
+
roles?: readonly Role[];
|
|
523
|
+
permissions?: readonly Permission[];
|
|
524
|
+
};
|
|
525
|
+
/** True when the value is already a normalized {@link CodeCatalog} (vs a declarative input). */
|
|
526
|
+
declare function isCodeCatalog(value: CodeCatalog | CodeCatalogInput): value is CodeCatalog;
|
|
527
|
+
/** Normalize an `authz.catalog` config value: pass through a {@link CodeCatalog}, build one from input. */
|
|
528
|
+
declare function toCodeCatalog(value: CodeCatalog | CodeCatalogInput): CodeCatalog;
|
|
529
|
+
/**
|
|
530
|
+
* Build a validated, frozen {@link CodeCatalog} from declarative arrays. Call it once at module
|
|
531
|
+
* scope in a pure authz module (no store imports) and wire the result via
|
|
532
|
+
* `FrameworkConfig.authz.catalog`.
|
|
533
|
+
*
|
|
534
|
+
* Validation (throws {@link Error} at module evaluation on the first violation):
|
|
535
|
+
* - ids are globally unique across groups, roles, AND permissions (one SCIM Groups id space);
|
|
536
|
+
* - `externalId`s (after defaulting to `id`) are globally unique (SCIM `externalId eq` contract);
|
|
537
|
+
* - every group -> group/role/permission reference (string id or embedded object) resolves to an
|
|
538
|
+
* entity declared in the catalog arrays, and every role -> permission reference likewise
|
|
539
|
+
* (`resources` refs are NOT validated here — resources live in the app's `ResourceProvider`);
|
|
540
|
+
* - nested group composition is acyclic;
|
|
541
|
+
* - `recommendedSubjectTypes` is a subset of `assignableSubjectTypes`.
|
|
542
|
+
*
|
|
543
|
+
* Side effects: entities missing `externalId` are stamped with `externalId = id`, then every
|
|
544
|
+
* entity (and its arrays/metadata) is frozen.
|
|
545
|
+
*/
|
|
546
|
+
declare function defineCatalog(input: CodeCatalogInput): CodeCatalog;
|
|
547
|
+
/**
|
|
548
|
+
* {@link AccessCatalogStore}-shaped READ union over the code-declared catalog and the optional
|
|
549
|
+
* backing store (lookup order code -> store, per kind). This is the single surface SCIM Groups
|
|
550
|
+
* reads and OAA projection enumerate so code entities are first-class entitlements to IAM tooling
|
|
551
|
+
* without ever being stored. Returns undefined when neither source is wired.
|
|
552
|
+
*/
|
|
553
|
+
declare function unionCatalogRead(code: CodeCatalog | undefined, store: AccessCatalogStore | undefined): AccessCatalogStore | undefined;
|
|
513
554
|
import { StandardSchemaV1 as StandardSchemaV15 } from "@standard-schema/spec";
|
|
514
555
|
/**
|
|
515
556
|
* IAM delta egress mode (RemoteConfig/ESI intent). Selects how access changes that occur inside the
|
|
516
557
|
* application are surfaced to the enterprise's IAM/governance layer:
|
|
517
558
|
*
|
|
518
559
|
* - `'patch'`: outbound SCIM into the IAM tool (per-resource PATCH/POST, externalId-only). The IAM
|
|
519
|
-
* tool's view stays fresh as access changes in the app
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
* mutating the IAM tool's state. See the README "IAM delta egress" section and
|
|
523
|
-
* `examples/express-pm`.
|
|
560
|
+
* tool's view stays fresh as access changes in the app, and the tool can reconcile the echo
|
|
561
|
+
* against the originating request (an unmatched change is an out-of-band access grant for the
|
|
562
|
+
* enterprise's policy to handle). See the README "IAM delta egress" section.
|
|
524
563
|
*
|
|
525
|
-
*
|
|
526
|
-
*
|
|
564
|
+
* Origin/trust: every push is authenticated with the app's outgoing workload client (OAuth bearer);
|
|
565
|
+
* the receiver treats the authenticated workload identity as the verified origin. Audit
|
|
566
|
+
* accountability lives with the IdP that authenticated the workload and the IAM tool that granted
|
|
567
|
+
* it access. The SDK only surfaces the signal; it never dictates the enterprise's workflow or
|
|
568
|
+
* policy (flag, auto-revoke + notify, or simply audit).
|
|
527
569
|
*/
|
|
528
|
-
type IamDeltaMode = "
|
|
570
|
+
type IamDeltaMode = "patch";
|
|
529
571
|
/** SCIM resource types the delta patch adapter addresses. */
|
|
530
572
|
type IamDeltaResourceType = "user" | "group";
|
|
531
573
|
/**
|
|
@@ -561,17 +603,20 @@ type IamDeltaReconcileResult = {
|
|
|
561
603
|
/**
|
|
562
604
|
* Projects access-root changes to the configured IAM delta destination. Implemented by the server
|
|
563
605
|
* package; threaded into the access-mutation chokepoint so every grant/revoke that flows through the
|
|
564
|
-
* SDK (including direct SCIM calls) is surfaced. `onGrant`/`onRevoke`
|
|
565
|
-
*
|
|
606
|
+
* SDK (including direct SCIM calls) is surfaced. `onGrant`/`onRevoke` resolve when the projection
|
|
607
|
+
* completes (or resolve immediately when not ready). They are best-effort egress: the SCIM mutation
|
|
608
|
+
* path awaits them (bounded) inside the request so no work is left detached (serverless-safe), but a
|
|
609
|
+
* rejection is caught and reported as degraded egress — it never turns a committed store mutation
|
|
610
|
+
* into a SCIM error. A rejected promise signals the projection failed so the caller can report it.
|
|
566
611
|
*
|
|
567
612
|
* Readiness follows the shared contract: `isReady()` is a synchronous check; `ready(timeout?)`
|
|
568
613
|
* resolves once the emitter first becomes usable.
|
|
569
614
|
*/
|
|
570
615
|
interface IamDeltaEmitter {
|
|
571
|
-
/**
|
|
572
|
-
onGrant(change: AccessChange): void
|
|
573
|
-
/**
|
|
574
|
-
onRevoke(change: AccessChange): void
|
|
616
|
+
/** Project a granted root; resolves on completion (or immediately when not ready), rejects on push failure. */
|
|
617
|
+
onGrant(change: AccessChange): Promise<void>;
|
|
618
|
+
/** Project a revoked root; resolves on completion (or immediately when not ready), rejects on push failure. */
|
|
619
|
+
onRevoke(change: AccessChange): Promise<void>;
|
|
575
620
|
/** Re-push all active roots to the destination (app-driven full reconcile). */
|
|
576
621
|
reconcile(roots: AsyncIterable<AccessChange> | Iterable<AccessChange>): Promise<IamDeltaReconcileResult>;
|
|
577
622
|
isReady(): boolean;
|
|
@@ -710,7 +755,7 @@ interface Address {
|
|
|
710
755
|
/**
|
|
711
756
|
* SCIM Group reference (used within User resources)
|
|
712
757
|
*/
|
|
713
|
-
interface
|
|
758
|
+
interface Group2 {
|
|
714
759
|
/**
|
|
715
760
|
* The identifier of the User's group
|
|
716
761
|
*/
|
|
@@ -790,7 +835,7 @@ interface GroupResource {
|
|
|
790
835
|
/**
|
|
791
836
|
* SCIM Role
|
|
792
837
|
*/
|
|
793
|
-
interface
|
|
838
|
+
interface Role2 {
|
|
794
839
|
/**
|
|
795
840
|
* The value of the role
|
|
796
841
|
*/
|
|
@@ -992,7 +1037,7 @@ interface User {
|
|
|
992
1037
|
/**
|
|
993
1038
|
* A list of groups to which the user belongs
|
|
994
1039
|
*/
|
|
995
|
-
groups?:
|
|
1040
|
+
groups?: Group2[];
|
|
996
1041
|
/**
|
|
997
1042
|
* A list of entitlements for the User
|
|
998
1043
|
*/
|
|
@@ -1005,7 +1050,7 @@ interface User {
|
|
|
1005
1050
|
/**
|
|
1006
1051
|
* A list of roles for the User
|
|
1007
1052
|
*/
|
|
1008
|
-
roles?:
|
|
1053
|
+
roles?: Role2[];
|
|
1009
1054
|
/**
|
|
1010
1055
|
* A list of certificates issued to the User
|
|
1011
1056
|
*/
|
|
@@ -1069,6 +1114,13 @@ type ModuleReadiness = {
|
|
|
1069
1114
|
* Canonical Enterprise Standard module names used by the holistic readiness report and the
|
|
1070
1115
|
* `requireReady([...])` helper. These are the config-driven module handles whose readiness can be
|
|
1071
1116
|
* composed; `es.isReady()` itself stays the narrow "config applied" signal and is NOT one of these.
|
|
1117
|
+
*
|
|
1118
|
+
* IAM-delta egress is intentionally NOT a member. Delta patch-back is best-effort and non-fatal (a
|
|
1119
|
+
* failed push only logs `degraded` and is reconciled by a later full sync — the Batch 7 drift-signal
|
|
1120
|
+
* contract), so folding it into `iam` readiness would let a delta-target outage make
|
|
1121
|
+
* `requireReady(['iam'])` false and take the app out of rotation for a signal that is designed not to
|
|
1122
|
+
* block. Apps that DO treat delta as a hard dependency can gate on `es.iam.delta.isReady()` /
|
|
1123
|
+
* `es.iam.delta.ready()` explicitly instead.
|
|
1072
1124
|
*/
|
|
1073
1125
|
type EsModuleName = "sso" | "ciam" | "iam" | "workload" | "otel" | "secrets" | "authz";
|
|
1074
1126
|
/** Per-module readiness snapshot in {@link ReadinessReport}. */
|
|
@@ -1585,7 +1637,7 @@ type FrameworkWorkloadIncomingOutgoing = {
|
|
|
1585
1637
|
type FrameworkWorkloadConfig = Partial<WorkloadConfig> | FrameworkWorkloadIncomingOutgoing;
|
|
1586
1638
|
/**
|
|
1587
1639
|
* Unified `getToken` call signature shared by the per-client {@link Workload} handle and the
|
|
1588
|
-
* aggregate `es.workload` (
|
|
1640
|
+
* aggregate `es.workload` (AUDIT_HISTORY.md §16.5). Both overloads are exposed so `es.workload.getToken(scope?)`
|
|
1589
1641
|
* (default/server client) and `es.workload.getToken('client', scope)` (a named outgoing client) both
|
|
1590
1642
|
* type-check off the same handle without a cast. The aggregate dispatches on arity at runtime
|
|
1591
1643
|
* (`getToken(...args)`); a per-client handle ignores a stray client argument.
|
|
@@ -1705,15 +1757,12 @@ type IAMConfig = {
|
|
|
1705
1757
|
groups?: IAMEndpointFlag;
|
|
1706
1758
|
/**
|
|
1707
1759
|
* RemoteConfig/ESI intent: how access changes that occur inside the application are surfaced to the
|
|
1708
|
-
* enterprise IAM/governance layer. Not configurable from application code
|
|
1709
|
-
* company's IAM tool supports SCIM Events vs. SCIM PATCH-based aggregation).
|
|
1760
|
+
* enterprise IAM/governance layer. Not configurable from application code.
|
|
1710
1761
|
*
|
|
1711
|
-
*
|
|
1712
|
-
*
|
|
1713
|
-
*
|
|
1714
|
-
*
|
|
1715
|
-
* by `externalId` only (no mapping store). Records an immutable fact rather than mutating the
|
|
1716
|
-
* IAM tool's state. See the README "IAM delta egress" section and `examples/express-pm`.
|
|
1762
|
+
* `'patch'`: outbound SCIM into the IAM tool keyed strictly by `externalId` (uses `url` as the
|
|
1763
|
+
* destination base and `deltaAudience` for the outgoing workload client). Keeps the IAM tool's
|
|
1764
|
+
* view fresh as the app grants/revokes access directly, so the tool can reconcile the echo
|
|
1765
|
+
* against the originating request. See the README "IAM delta egress" section.
|
|
1717
1766
|
*
|
|
1718
1767
|
* When omitted, delta egress is disabled. The SDK only emits the signal; the enterprise's IAM
|
|
1719
1768
|
* tooling owns the response (flag, auto-revoke + notify, or audit). See `IamDeltaMode`.
|
|
@@ -2144,12 +2193,8 @@ type Session<TExtended = object> = {
|
|
|
2144
2193
|
*/
|
|
2145
2194
|
createdAt: Date;
|
|
2146
2195
|
/**
|
|
2147
|
-
*
|
|
2148
|
-
*
|
|
2149
|
-
*/
|
|
2150
|
-
lastActivityAt: Date;
|
|
2151
|
-
/**
|
|
2152
|
-
* Optional absolute expiration for the browser/session credential.
|
|
2196
|
+
* Optional absolute expiration for the browser/session credential. Drives the store TTL (Redis `EX`)
|
|
2197
|
+
* and the session cookie expiry; a record whose `expiresAt` has passed is treated as signed out.
|
|
2153
2198
|
* Stores may serialize this as a Date or ISO string.
|
|
2154
2199
|
*/
|
|
2155
2200
|
expiresAt?: Date | string;
|
|
@@ -2231,7 +2276,9 @@ interface SessionStore<TExtended = object> {
|
|
|
2231
2276
|
/**
|
|
2232
2277
|
* Update an existing session with partial data.
|
|
2233
2278
|
*
|
|
2234
|
-
*
|
|
2279
|
+
* Used at trust boundaries (e.g. token refresh) to merge new token material/claims/expiry, or to
|
|
2280
|
+
* add custom fields. A store SHOULD refresh its TTL from the merged `expiresAt`. The authenticated
|
|
2281
|
+
* read path does NOT call this — reads never write.
|
|
2235
2282
|
*
|
|
2236
2283
|
* @param sid - The session.sid to update
|
|
2237
2284
|
* @param data - Partial session data to merge
|
|
@@ -2310,133 +2357,6 @@ type BeforeLogoutHook<TUser = AuthenticatedUser> = (ctx: BeforeLogoutContext<TUs
|
|
|
2310
2357
|
/** The `afterLogout` hook: runs after teardown. Return a destination `string`, a `Response`, or nothing (→ `/`). */
|
|
2311
2358
|
type AfterLogoutHook = (ctx: AfterLogoutContext) => RedirectResult | Promise<RedirectResult>;
|
|
2312
2359
|
/**
|
|
2313
|
-
* The verdict a single {@link RedirectRule} returns for a candidate destination:
|
|
2314
|
-
* - `'deny'` — a hard veto that ALWAYS wins, even if another rule allowed (use for protocol/format
|
|
2315
|
-
* hygiene such as `javascript:`, `//evil`, `/\evil`).
|
|
2316
|
-
* - `'allow'` — this rule authorizes the destination (some allow is required to pass).
|
|
2317
|
-
* - `'abstain'` — this rule has no opinion; defer to the others.
|
|
2318
|
-
*/
|
|
2319
|
-
type RedirectVerdict = "allow" | "deny" | "abstain";
|
|
2320
|
-
/** Parsed context handed to every {@link RedirectRule}. */
|
|
2321
|
-
interface RedirectRuleContext {
|
|
2322
|
-
/** The raw candidate string exactly as supplied (hook return value / captured query param). */
|
|
2323
|
-
candidate: string;
|
|
2324
|
-
/**
|
|
2325
|
-
* The candidate resolved against the current request URL the same way a browser resolves a
|
|
2326
|
-
* `Location` header (so `/foo` is same-origin, `//evil` and `https://evil` are cross-origin).
|
|
2327
|
-
* `null` when the candidate cannot be parsed into a URL at all.
|
|
2328
|
-
*/
|
|
2329
|
-
url: URL | null;
|
|
2330
|
-
/** Origin of the current request (the app's own origin), or `''` if `requestUrl` was unparseable. */
|
|
2331
|
-
requestOrigin: string;
|
|
2332
|
-
}
|
|
2333
|
-
/**
|
|
2334
|
-
* One composable redirect policy rule. Build policies by layering rules (a hard-veto hygiene rule
|
|
2335
|
-
* plus one or more allow rules) and evaluating them with {@link resolveRedirect} / {@link isRedirectAllowed}.
|
|
2336
|
-
*/
|
|
2337
|
-
type RedirectRule = (ctx: RedirectRuleContext) => RedirectVerdict;
|
|
2338
|
-
/**
|
|
2339
|
-
* Hard-veto hygiene rule. Denies the URL shapes that enable open redirects / XSS regardless of any
|
|
2340
|
-
* allow rule: control characters, backslash tricks (`/\evil`), protocol-relative URLs (`//evil`),
|
|
2341
|
-
* unparseable candidates, non-`http(s)` schemes (`javascript:`, `data:`, …), and embedded
|
|
2342
|
-
* `user:pass@` credentials. Put this FIRST in every policy.
|
|
2343
|
-
*/
|
|
2344
|
-
declare function blockDangerousUrls(): RedirectRule;
|
|
2345
|
-
/** Allow in-app deep links: a clean relative path (`/foo`), but not `//host` or `/\host`. */
|
|
2346
|
-
declare function allowRelativePaths(): RedirectRule;
|
|
2347
|
-
/** Allow destinations on the same origin as the current request. */
|
|
2348
|
-
declare function allowSameOrigin(): RedirectRule;
|
|
2349
|
-
/** Allow destinations whose origin is in the given allowlist (e.g. `allowOrigins('https://app.example.com')`). */
|
|
2350
|
-
declare function allowOrigins(...origins: string[]): RedirectRule;
|
|
2351
|
-
/**
|
|
2352
|
-
* Allow destinations whose host is in the given allowlist. A host prefixed with `.` matches that
|
|
2353
|
-
* host and all its subdomains (e.g. `allowHosts('.example.com')` allows `app.example.com`).
|
|
2354
|
-
*/
|
|
2355
|
-
declare function allowHosts(...hosts: string[]): RedirectRule;
|
|
2356
|
-
/**
|
|
2357
|
-
* The default same-origin policy: hygiene veto + relative paths + same-origin absolute URLs. This is
|
|
2358
|
-
* the floor the SDK applies to any `string` an `after*` hook returns. Pass it to
|
|
2359
|
-
* {@link resolveRedirect} / {@link isRedirectAllowed}, or spread it and add `allowOrigins(...)` /
|
|
2360
|
-
* `allowHosts(...)` to permit specific cross-origin destinations.
|
|
2361
|
-
*/
|
|
2362
|
-
declare function sameOriginRedirectRules(): RedirectRule[];
|
|
2363
|
-
/**
|
|
2364
|
-
* Returns `true` when `candidate` is permitted by the given `rules` (deny-by-default; any `'deny'`
|
|
2365
|
-
* vetoes; at least one `'allow'` is required). Useful to validate a deep link at capture time, e.g.
|
|
2366
|
-
* inside `beforeLogin` before storing it in the login state cookie.
|
|
2367
|
-
*/
|
|
2368
|
-
declare function isRedirectAllowed(candidate: string | undefined, rules: RedirectRule[], requestUrl: string): boolean;
|
|
2369
|
-
/**
|
|
2370
|
-
* Resolve a candidate destination against a redirect policy: returns `candidate` when the `rules`
|
|
2371
|
-
* allow it, otherwise `fallback`. This is the composable replacement for the old fixed same-origin
|
|
2372
|
-
* floor — pass {@link sameOriginRedirectRules} for the default behavior, or your own rule list.
|
|
2373
|
-
*/
|
|
2374
|
-
declare function resolveRedirect(candidate: string | undefined, options: {
|
|
2375
|
-
rules: RedirectRule[];
|
|
2376
|
-
fallback: string;
|
|
2377
|
-
requestUrl: string;
|
|
2378
|
-
}): string;
|
|
2379
|
-
/**
|
|
2380
|
-
* A reusable redirect policy: the ordered {@link RedirectRule}s plus the `fallback` destination used
|
|
2381
|
-
* when a candidate is missing or rejected. Bundling rules + fallback keeps the capture hook
|
|
2382
|
-
* ({@link captureRedirect}) and the resolve hook ({@link resolveCapturedRedirect}) in lock-step so a
|
|
2383
|
-
* deep link that passes at capture time resolves the same way after the IdP round-trip.
|
|
2384
|
-
*/
|
|
2385
|
-
interface RedirectPolicy {
|
|
2386
|
-
rules: RedirectRule[];
|
|
2387
|
-
fallback: string;
|
|
2388
|
-
}
|
|
2389
|
-
/**
|
|
2390
|
-
* The canonical context shape written by {@link captureRedirect} and read by
|
|
2391
|
-
* {@link resolveCapturedRedirect}: a single same-origin deep link stored under `redirect`.
|
|
2392
|
-
*/
|
|
2393
|
-
interface RedirectContext {
|
|
2394
|
-
redirect?: string;
|
|
2395
|
-
}
|
|
2396
|
-
/**
|
|
2397
|
-
* The default {@link RedirectPolicy} that fits virtually every app: the hard-veto hygiene rule
|
|
2398
|
-
* ({@link blockDangerousUrls}) plus same-origin absolute URLs and in-app relative paths, falling back
|
|
2399
|
-
* to `/`. Pass it straight to {@link captureRedirect} / {@link resolveCapturedRedirect}. Treat it as
|
|
2400
|
-
* read-only; to customize, spread it — override the fallback with
|
|
2401
|
-
* `{ ...defaultRedirectPolicies, fallback: \`/${tenant.id}/\` }`, or allow specific cross-origin
|
|
2402
|
-
* destinations with `{ ...defaultRedirectPolicies, rules: [...defaultRedirectPolicies.rules, allowOrigins('https://app.example.com')] }`.
|
|
2403
|
-
*/
|
|
2404
|
-
declare const defaultRedirectPolicies: RedirectPolicy;
|
|
2405
|
-
/**
|
|
2406
|
-
* `beforeLogin` helper. Reads the `param` query string (default `redirect`) from `request`, validates
|
|
2407
|
-
* it against `policy.rules` at capture time, and returns it as `{ redirect }` context for the SDK to
|
|
2408
|
-
* carry across the IdP round-trip — or `undefined` when the param is absent or rejected (so nothing is
|
|
2409
|
-
* stored). Pair with {@link resolveCapturedRedirect}. Example: `beforeLogin: ({ request }) =>
|
|
2410
|
-
* captureRedirect(request, redirectPolicy)`.
|
|
2411
|
-
*/
|
|
2412
|
-
declare function captureRedirect(request: Request, policy: RedirectPolicy, param?: string): RedirectContext | undefined;
|
|
2413
|
-
/**
|
|
2414
|
-
* `afterLogin` helper. Reads the captured `redirect` from `ctx.context` (an UNSIGNED state cookie —
|
|
2415
|
-
* untrusted) and re-resolves it against `policy`, returning the destination string or `policy.fallback`
|
|
2416
|
-
* when it is missing/rejected. Pair with {@link captureRedirect}. Example: `afterLogin: (ctx) =>
|
|
2417
|
-
* ctx.ok ? resolveCapturedRedirect(ctx, redirectPolicy) : '/?auth_error=login_failed'`.
|
|
2418
|
-
*/
|
|
2419
|
-
declare function resolveCapturedRedirect(ctx: {
|
|
2420
|
-
request: Request;
|
|
2421
|
-
context?: unknown;
|
|
2422
|
-
}, policy: RedirectPolicy): string;
|
|
2423
|
-
/**
|
|
2424
|
-
* Resolve a hook's {@link RedirectResult} into either a ready `Response` (when the hook
|
|
2425
|
-
* returned one) or a same-origin-floored `location` string (string or fallback).
|
|
2426
|
-
*/
|
|
2427
|
-
declare function resolveAfterRedirect(result: RedirectResult, fallback: string, requestUrl: string): {
|
|
2428
|
-
location: string;
|
|
2429
|
-
response?: undefined;
|
|
2430
|
-
} | {
|
|
2431
|
-
location?: undefined;
|
|
2432
|
-
response: Response;
|
|
2433
|
-
};
|
|
2434
|
-
/**
|
|
2435
|
-
* Return a copy of `response` with the given `Set-Cookie` header values appended. Used to apply
|
|
2436
|
-
* SDK-owned cookie clears/sets to a `Response` an `after*` hook returned.
|
|
2437
|
-
*/
|
|
2438
|
-
declare function withSetCookies(response: Response, setCookies: string[]): Response;
|
|
2439
|
-
/**
|
|
2440
2360
|
* Outcome of resolving an authenticated principal (workforce user or customer) from a request.
|
|
2441
2361
|
*
|
|
2442
2362
|
* This is the degraded-aware companion to the `get*` helpers (`getUser`/`getCustomer`), which
|
|
@@ -2444,7 +2364,7 @@ declare function withSetCookies(response: Response, setCookies: string[]): Respo
|
|
|
2444
2364
|
* "no credential present" (`unauthenticated` — the visitor is genuinely signed out) apart from
|
|
2445
2365
|
* "we could not verify the credential" (`degraded` — a JWKS outage / misconfiguration). Treating the
|
|
2446
2366
|
* latter as anonymous is a fail-open trap: a request handler should usually answer `503` on
|
|
2447
|
-
* `degraded` rather than render a signed-out experience (
|
|
2367
|
+
* `degraded` rather than render a signed-out experience (AUDIT_HISTORY.md §4.4).
|
|
2448
2368
|
*
|
|
2449
2369
|
* It is a plain value (never thrown), consistent with the SDK's "ask a question, get an answer" auth
|
|
2450
2370
|
* helper contract.
|
|
@@ -2595,19 +2515,27 @@ type SSOConfig<
|
|
|
2595
2515
|
* @default 600
|
|
2596
2516
|
*/
|
|
2597
2517
|
loginStateTtl?: number;
|
|
2518
|
+
/**
|
|
2519
|
+
* Grace window (seconds) for the superseded session record after a refresh rotates the `sid`.
|
|
2520
|
+
* On refresh the SDK mints a new `sid` (new record + cookie) and re-TTLs the OLD record to this
|
|
2521
|
+
* window with its `refresh_token` stripped, so in-flight requests still holding the old cookie
|
|
2522
|
+
* complete (read-only) while the stale token material is reaped promptly by the store TTL. `0`
|
|
2523
|
+
* deletes the old record immediately. Ops-governed (ConfigSource); clamped to `[0, 600]`.
|
|
2524
|
+
* @default 60
|
|
2525
|
+
*/
|
|
2526
|
+
rotationGraceSeconds?: number;
|
|
2598
2527
|
} & SSOHandlerConfig;
|
|
2599
2528
|
type StateCookie = {
|
|
2600
2529
|
state: string;
|
|
2601
2530
|
codeVerifier: string;
|
|
2531
|
+
/** OIDC `nonce` issued at initiation and enforced against the ID token at the callback (AUDIT_HISTORY.md v2 §1.8). */
|
|
2532
|
+
nonce: string;
|
|
2602
2533
|
/**
|
|
2603
2534
|
* Appdev context returned by `beforeLogin`, carried across the IdP round-trip. UNSIGNED and
|
|
2604
2535
|
* therefore untrusted: validate before using for anything security-sensitive.
|
|
2605
2536
|
*/
|
|
2606
2537
|
context?: unknown;
|
|
2607
2538
|
};
|
|
2608
|
-
declare function listSsoClientIdsFromCookies(requestOrCookieHeader: Request | string | null | undefined, options?: {
|
|
2609
|
-
cookiePrefix?: string;
|
|
2610
|
-
}): string[];
|
|
2611
2539
|
type SSOHandlerConfig = {
|
|
2612
2540
|
loginUrl?: string;
|
|
2613
2541
|
userUrl?: string;
|
|
@@ -3035,6 +2963,22 @@ type VaultLfvSecretsConfig = {
|
|
|
3035
2963
|
/** Warning interval in milliseconds for LFV retry logs. Set to 0 to disable warnings. */
|
|
3036
2964
|
warnInterval?: number;
|
|
3037
2965
|
/**
|
|
2966
|
+
* Freshness bound (in seconds) for inbound signed callbacks. Delivery/events callbacks carry a
|
|
2967
|
+
* signed `issued_at`; a callback older than this window is rejected as stale, and a previously
|
|
2968
|
+
* accepted callback signature within the window is rejected as a replay. Generous by default to
|
|
2969
|
+
* tolerate clock skew. Defaults to 300 seconds.
|
|
2970
|
+
*/
|
|
2971
|
+
callbackMaxAgeSeconds?: number;
|
|
2972
|
+
/**
|
|
2973
|
+
* Optional maximum age (in seconds) for a cached secret before a read forces a fresh re-fetch.
|
|
2974
|
+
* LFV is push-based — deliveries/events keep the cache current — so the cache is unbounded by
|
|
2975
|
+
* default. This knob is defense-in-depth against a silently missed event (e.g. a dropped events
|
|
2976
|
+
* callback): once an entry is older than this, the next read bypasses the cache hit and joins the
|
|
2977
|
+
* per-path single-flight re-read instead of serving a potentially stale value. Unset/<=0 means no
|
|
2978
|
+
* age bound.
|
|
2979
|
+
*/
|
|
2980
|
+
cacheMaxAgeSeconds?: number;
|
|
2981
|
+
/**
|
|
3038
2982
|
* Optional logger for request/response tracing.
|
|
3039
2983
|
*/
|
|
3040
2984
|
log?: Logger;
|
|
@@ -3379,12 +3323,28 @@ type AuthzConfig = {
|
|
|
3379
3323
|
* provenance. Never written to a remote store at init.
|
|
3380
3324
|
*/
|
|
3381
3325
|
trustedProvisioningClients?: TrustedProvisioningClient[];
|
|
3326
|
+
/**
|
|
3327
|
+
* Code-declared catalog (Framework-only; a ConfigSource can never supply it). An in-memory,
|
|
3328
|
+
* read-path definition source for code-authored groups/roles/permissions: never seeded or
|
|
3329
|
+
* written to any store, unified with `catalogStore` and resource-derived entitlements on every
|
|
3330
|
+
* read (lookup order code -> store -> derived), and immutable through SCIM (member grant/revoke
|
|
3331
|
+
* allowed; metadata writes return 403 `mutability`). Accepts declarative arrays or a
|
|
3332
|
+
* `defineCatalog(...)` result; validated/normalized at config apply. See `defineCatalog`.
|
|
3333
|
+
*/
|
|
3334
|
+
catalog?: CodeCatalog | CodeCatalogInput;
|
|
3335
|
+
/** Durable catalog store for SCIM/IAM-sourced entitlement definitions (full SCIM CRUD). */
|
|
3382
3336
|
catalogStore?: AccessCatalogStore;
|
|
3383
3337
|
/** Granted roots (source of truth) used by SCIM/IAM orchestration and OAA projection. */
|
|
3384
3338
|
accessStore?: AccessAssignmentStore;
|
|
3385
3339
|
/** Derived closure index for fast `has*` checks; materialized from accessStore + catalogStore. */
|
|
3386
3340
|
accessIndex?: AccessIndex;
|
|
3387
3341
|
/**
|
|
3342
|
+
* Read-through provider over the application's own resource data (teams, projects, ...), including
|
|
3343
|
+
* optional derived-entitlement functions. The SDK never stores resources itself; see
|
|
3344
|
+
* {@link ResourceProvider}.
|
|
3345
|
+
*/
|
|
3346
|
+
resources?: ResourceProvider;
|
|
3347
|
+
/**
|
|
3388
3348
|
* Opt-in transform applied to a permission before OAA projection to derive its `permission_type`.
|
|
3389
3349
|
* Applied identically on incremental push and full sync. Undefined => identity (use the
|
|
3390
3350
|
* permission's own `permissionTypes`/`action`).
|
|
@@ -3394,9 +3354,9 @@ type AuthzConfig = {
|
|
|
3394
3354
|
* Opt-in transform applied to a group before OAA projection (e.g. computed `custom_properties`,
|
|
3395
3355
|
* redaction). Applied identically on incremental push and full sync. Undefined => identity.
|
|
3396
3356
|
*/
|
|
3397
|
-
mapGroup?: (group:
|
|
3357
|
+
mapGroup?: (group: Group) => Group;
|
|
3398
3358
|
/** Opt-in transform applied to a role before OAA projection. Undefined => identity. */
|
|
3399
|
-
mapRole?: (role:
|
|
3359
|
+
mapRole?: (role: Role) => Role;
|
|
3400
3360
|
/** Opt-in transform applied to a resource before OAA projection. Undefined => identity. */
|
|
3401
3361
|
mapResource?: (resource: Resource) => Resource;
|
|
3402
3362
|
/**
|
|
@@ -3444,7 +3404,7 @@ type FrameworkWorkloadConfigFromCode = WorkloadServerConfigFromCode | {
|
|
|
3444
3404
|
incoming?: WorkloadServerConfigFromCode;
|
|
3445
3405
|
outgoing?: FrameworkWorkloadIncomingOutgoing["outgoing"];
|
|
3446
3406
|
};
|
|
3447
|
-
type CIAMConfigFromCodeInput = Omit<CIAMConfig, "
|
|
3407
|
+
type CIAMConfigFromCodeInput = Omit<CIAMConfig, "providers" | "magicLinkUrl" | "magicLinkLoginUrl" | "customerUrl" | "customerLoginUrl" | "customerCallbackUrl" | "customerProvidersUrl" | "logoutUrl">;
|
|
3448
3408
|
/**
|
|
3449
3409
|
* The application-facing configuration surface for `enterpriseStandard(source, config)`.
|
|
3450
3410
|
* Identical to {@link FrameworkConfig} except endpoint URLs are removed (derived from `basePath`)
|
|
@@ -3539,16 +3499,6 @@ type CacheConfig = {
|
|
|
3539
3499
|
};
|
|
3540
3500
|
/** Session-related caching knobs. Portable. */
|
|
3541
3501
|
session?: {
|
|
3542
|
-
/**
|
|
3543
|
-
* Minimum seconds between `lastActivityAt` persists for an active session. Contract:
|
|
3544
|
-
* `lastActivityAt` MUST be persisted at least once per interval of continued activity and MUST
|
|
3545
|
-
* NOT be persisted more often than once per interval; `0` persists on every authenticated
|
|
3546
|
-
* request (pre-tuning behavior). Evaluated statelessly against the just-read session record, so
|
|
3547
|
-
* it is correct with or without session affinity.
|
|
3548
|
-
*
|
|
3549
|
-
* Clamp: [0, 86400] (default 60).
|
|
3550
|
-
*/
|
|
3551
|
-
activityUpdateSeconds?: number;
|
|
3552
3502
|
/**
|
|
3553
3503
|
* Instance-local read-through cache for `sessionStore.get`. DISABLED by default. Contract: when
|
|
3554
3504
|
* enabled, an implementation MAY serve `get(sid)` from a local cache for up to `ttlSeconds`,
|
|
@@ -3573,7 +3523,11 @@ type FrameworkStores = {
|
|
|
3573
3523
|
customerStore?: CustomerStore<unknown>;
|
|
3574
3524
|
accessStore?: AccessAssignmentStore<unknown>;
|
|
3575
3525
|
accessIndex?: AccessIndex;
|
|
3526
|
+
/** Code-declared catalog (read-path, in-memory; never stored). See `AuthzConfig.catalog`. */
|
|
3527
|
+
catalog?: CodeCatalog | CodeCatalogInput;
|
|
3576
3528
|
catalogStore?: AccessCatalogStore;
|
|
3529
|
+
/** Read-through {@link ResourceProvider} over the app's own resource data (never SDK-stored). */
|
|
3530
|
+
resources?: ResourceProvider;
|
|
3577
3531
|
magicLinkStore?: MagicLinkStore<unknown>;
|
|
3578
3532
|
workloadTokenStore?: WorkloadTokenStore;
|
|
3579
3533
|
/**
|
|
@@ -3656,8 +3610,6 @@ type RemoteConfigRetryOptions = {
|
|
|
3656
3610
|
jitterRatio?: number;
|
|
3657
3611
|
/** Timeout for each ConfigSource load attempt. Defaults to 30000ms. */
|
|
3658
3612
|
loadTimeoutMs?: number;
|
|
3659
|
-
/** Called before each retry is scheduled. Throw to stop retrying and reject ready(). */
|
|
3660
|
-
onRetry?: RemoteConfigRetryHook;
|
|
3661
3613
|
};
|
|
3662
3614
|
type ConfigSubscriptionOptions = {
|
|
3663
3615
|
/**
|
|
@@ -3793,11 +3745,6 @@ type CIAMConfig<
|
|
|
3793
3745
|
*/
|
|
3794
3746
|
ciamId?: string;
|
|
3795
3747
|
/**
|
|
3796
|
-
* Signing key for CIAM JWT tokens. Must be provided via Vault only (never in code).
|
|
3797
|
-
* Store in Vault under ciam.signingKey.
|
|
3798
|
-
*/
|
|
3799
|
-
signingKey?: string;
|
|
3800
|
-
/**
|
|
3801
3748
|
* Server-side session store for CIAM sessions (required for server-side session
|
|
3802
3749
|
* tracking and first-party logout).
|
|
3803
3750
|
*/
|
|
@@ -3871,14 +3818,13 @@ type CIAM<
|
|
|
3871
3818
|
ready?: (timeout?: number) => Promise<void>;
|
|
3872
3819
|
};
|
|
3873
3820
|
/**
|
|
3874
|
-
* CIAM config that code may provide; excludes vault-only secrets (`
|
|
3875
|
-
*
|
|
3876
|
-
* `customerCallbackUrl`, `customerProvidersUrl`).
|
|
3821
|
+
* CIAM config that code may provide; excludes vault-only secrets (`providers`) and ES-derived
|
|
3822
|
+
* endpoint URLs (`customerLoginUrl`, `customerCallbackUrl`, `customerProvidersUrl`).
|
|
3877
3823
|
*/
|
|
3878
3824
|
type CIAMConfigFromCode<
|
|
3879
3825
|
TMagicLinkData = Record<string, never>,
|
|
3880
3826
|
TCustomerData = Record<string, never>
|
|
3881
|
-
> = Omit<CIAMConfig<TMagicLinkData, TCustomerData>, "
|
|
3827
|
+
> = Omit<CIAMConfig<TMagicLinkData, TCustomerData>, "providers" | "customerLoginUrl" | "customerCallbackUrl" | "customerProvidersUrl">;
|
|
3882
3828
|
/** Read Users and Groups via the SCIM endpoints. Gates `GET /iam/Users` and `GET /iam/Groups`. */
|
|
3883
3829
|
declare const ES_IAM_READ: Permission;
|
|
3884
3830
|
/**
|
|
@@ -3908,7 +3854,7 @@ declare const ES_SDK_PERMISSIONS: readonly Permission[];
|
|
|
3908
3854
|
/**
|
|
3909
3855
|
* The logical SDK endpoint operations that require authorization, mapped to the Permission and the
|
|
3910
3856
|
* principal scope to check. This is the single source of truth the router/guards consult so the
|
|
3911
|
-
* enforcement contract lives in one place rather than scattered per route (
|
|
3857
|
+
* enforcement contract lives in one place rather than scattered per route (AUDIT_HISTORY.md §1.32). The IAM
|
|
3912
3858
|
* permission for a SCIM request is chosen from `iam.read` / `iam.users.write` / `iam.groups.write`
|
|
3913
3859
|
* by SCIM resource + HTTP method (no request-body introspection).
|
|
3914
3860
|
*/
|
|
@@ -3994,8 +3940,16 @@ type ESResolvedRoute = {
|
|
|
3994
3940
|
* before the handler runs: the caller must hold the {@link EsEndpointPermission.permission} as a
|
|
3995
3941
|
* granted entitlement, or—when `RemoteConfig.authz.scopesAsEntitlements` is enabled—carry the
|
|
3996
3942
|
* matching OAuth scope. Login/public/discovery routes omit it.
|
|
3997
|
-
|
|
3998
|
-
|
|
3943
|
+
*
|
|
3944
|
+
* Three states, chosen so a custom `resolve` cannot silently drop authorization by omission:
|
|
3945
|
+
* - a permission object → enforce it;
|
|
3946
|
+
* - `undefined` (omitted) → when this route replaces a default route that DID carry a permission,
|
|
3947
|
+
* the router inherits the default's permission (see `routeRequest`); otherwise the route is public;
|
|
3948
|
+
* - `null` → an EXPLICIT opt-out ("this route is intentionally public"): inheritance is suppressed
|
|
3949
|
+
* even when it shadows a protected default. Making the caller write `null` keeps the downgrade a
|
|
3950
|
+
* conscious act rather than a forgotten spread.
|
|
3951
|
+
*/
|
|
3952
|
+
requiredPermission?: EsEndpointPermission | null;
|
|
3999
3953
|
handler: (request: Request) => Promise<Response>;
|
|
4000
3954
|
};
|
|
4001
3955
|
type ESRouteFilterResult = "continue" | "not_handled" | Response;
|
|
@@ -4009,10 +3963,17 @@ type ESRoutingOptions = {
|
|
|
4009
3963
|
*/
|
|
4010
3964
|
filter?: (request: Request, es: EnterpriseStandard) => Promise<ESRouteFilterResult | undefined> | ESRouteFilterResult;
|
|
4011
3965
|
/**
|
|
4012
|
-
* Resolve/replace route target. Return undefined to use default resolution.
|
|
4013
|
-
*
|
|
3966
|
+
* Resolve/replace route target. Return `undefined` to use default resolution.
|
|
3967
|
+
*
|
|
3968
|
+
* `defaultRoute` is the SDK's default match for this request (already resolved), or `undefined`
|
|
3969
|
+
* when no default route matches. When you REPLACE a default route (same path, custom handler), the
|
|
3970
|
+
* router inherits the default's `requiredPermission` unless your returned route sets
|
|
3971
|
+
* `requiredPermission` explicitly (a permission to override it, or `null` to make the route public).
|
|
3972
|
+
* Spreading the default (`{ ...defaultRoute, handler }`) also carries the gate. This is why the
|
|
3973
|
+
* default is passed as a resolved object rather than a thunk: dropping authorization must be
|
|
3974
|
+
* deliberate, not the result of forgetting to copy a field.
|
|
4014
3975
|
*/
|
|
4015
|
-
resolve?: (request: Request, es: EnterpriseStandard,
|
|
3976
|
+
resolve?: (request: Request, es: EnterpriseStandard, defaultRoute: ESResolvedRoute | undefined) => Promise<ESResolvedRoute | undefined> | ESResolvedRoute | undefined;
|
|
4016
3977
|
/**
|
|
4017
3978
|
* Wrap the final handler (logging, metrics, policy, etc.).
|
|
4018
3979
|
*/
|
|
@@ -4153,6 +4114,37 @@ type BaseTenant = {
|
|
|
4153
4114
|
configLocator: TenantConfigLocator;
|
|
4154
4115
|
};
|
|
4155
4116
|
type TenantEsFactory<TTenant extends BaseTenant = BaseTenant> = (tenant: TTenant) => EnterpriseStandard;
|
|
4117
|
+
/**
|
|
4118
|
+
* A single-flight cache of per-tenant {@link EnterpriseStandard} instances, supplied by the app.
|
|
4119
|
+
*
|
|
4120
|
+
* The SDK does NOT cache tenant runtimes itself: constructing an `EnterpriseStandard` opens a
|
|
4121
|
+
* ConfigSource load/subscribe (a vault round-trip / websocket join) and holds timers, so one
|
|
4122
|
+
* instance per tenant-routed request would be both a per-request cold start and an unbounded leak.
|
|
4123
|
+
* Instead, apps bring a cache — `lru-cache` is the recommended implementation, and this type is
|
|
4124
|
+
* deliberately structurally compatible with `LRUCache<string, EnterpriseStandard>` so an app can
|
|
4125
|
+
* pass its cache instance straight through:
|
|
4126
|
+
*
|
|
4127
|
+
* ```ts
|
|
4128
|
+
* const esCache = new LRUCache<string, EnterpriseStandard>({
|
|
4129
|
+
* max: 100,
|
|
4130
|
+
* ttl: 1000 * 60 * 60,
|
|
4131
|
+
* dispose: (es) => es.close(), // full lifecycle: evicted/invalidated runtimes are closed
|
|
4132
|
+
* fetchMethod: async (id) => {
|
|
4133
|
+
* const tenant = await tenants.get(id); // `tenants` assigned below; resolved at call time
|
|
4134
|
+
* return tenant ? createTenantEs(tenant) : undefined;
|
|
4135
|
+
* },
|
|
4136
|
+
* });
|
|
4137
|
+
* const tenants = new InMemoryTenantStore({ esCache });
|
|
4138
|
+
* ```
|
|
4139
|
+
*
|
|
4140
|
+
* `fetch` MUST be single-flight (concurrent calls for one id share one construction) — `lru-cache`
|
|
4141
|
+
* guarantees this. `delete` is called by the store on `upsert`/`delete` so a changed/removed tenant
|
|
4142
|
+
* record invalidates (and, via `dispose`, closes) the stale runtime.
|
|
4143
|
+
*/
|
|
4144
|
+
type TenantEsCache = {
|
|
4145
|
+
fetch(id: string): Promise<EnterpriseStandard | undefined>;
|
|
4146
|
+
delete(id: string): unknown;
|
|
4147
|
+
};
|
|
4156
4148
|
interface TenantStore<TTenant extends BaseTenant = BaseTenant> {
|
|
4157
4149
|
get(id: string): Promise<TTenant | undefined>;
|
|
4158
4150
|
list(options?: ListOptions): Promise<ListResult<TTenant>>;
|
|
@@ -4160,20 +4152,13 @@ interface TenantStore<TTenant extends BaseTenant = BaseTenant> {
|
|
|
4160
4152
|
delete(id: string): Promise<number>;
|
|
4161
4153
|
getEs(id: string): Promise<EnterpriseStandard | undefined>;
|
|
4162
4154
|
}
|
|
4163
|
-
type InMemoryTenantStoreOptions
|
|
4164
|
-
|
|
4155
|
+
type InMemoryTenantStoreOptions = {
|
|
4156
|
+
/**
|
|
4157
|
+
* App-owned cache of per-tenant `EnterpriseStandard` instances (see {@link TenantEsCache}).
|
|
4158
|
+
* Required to use {@link InMemoryTenantStore.getEs}; the store never constructs runtimes itself.
|
|
4159
|
+
*/
|
|
4160
|
+
esCache?: TenantEsCache;
|
|
4165
4161
|
};
|
|
4166
|
-
declare class InMemoryTenantStore<TTenant extends BaseTenant = BaseTenant> implements TenantStore<TTenant> {
|
|
4167
|
-
private readonly store;
|
|
4168
|
-
private readonly createEs?;
|
|
4169
|
-
constructor(options?: InMemoryTenantStoreOptions<TTenant>);
|
|
4170
|
-
get(id: string): Promise<TTenant | undefined>;
|
|
4171
|
-
list(options?: ListOptions): Promise<ListResult<TTenant>>;
|
|
4172
|
-
upsert(tenant: TTenant): Promise<TTenant>;
|
|
4173
|
-
delete(id: string): Promise<number>;
|
|
4174
|
-
getEs(id: string): Promise<EnterpriseStandard | undefined>;
|
|
4175
|
-
}
|
|
4176
|
-
declare function sendTenantWebhook(webhookUrl: string, payload: TenantWebhookPayload, log: Logger): Promise<void>;
|
|
4177
4162
|
/**
|
|
4178
4163
|
* Persisted workforce user record with identity fields and tracking metadata.
|
|
4179
4164
|
*
|
|
@@ -4286,12 +4271,12 @@ type BaseUser<TExtended = object> = BaseUserFields & {
|
|
|
4286
4271
|
* Optional SCIM roles.
|
|
4287
4272
|
* Commonly set by IAM inbound SCIM provisioning flows.
|
|
4288
4273
|
*/
|
|
4289
|
-
roles?:
|
|
4274
|
+
roles?: Role2[];
|
|
4290
4275
|
/**
|
|
4291
4276
|
* Optional SCIM groups.
|
|
4292
4277
|
* Commonly set by IAM inbound SCIM provisioning flows.
|
|
4293
4278
|
*/
|
|
4294
|
-
groups?:
|
|
4279
|
+
groups?: Group2[];
|
|
4295
4280
|
/**
|
|
4296
4281
|
* Optional SCIM entitlements.
|
|
4297
4282
|
* Commonly set by IAM inbound SCIM provisioning flows.
|
|
@@ -4447,21 +4432,19 @@ type Permission = AuthzEntityBase & SubjectTypeScoping & {
|
|
|
4447
4432
|
/** When true, the permission also applies to a resource's sub-resources (maps to OAA `apply_to_sub_resources`). */
|
|
4448
4433
|
applyToSubResources?: boolean;
|
|
4449
4434
|
};
|
|
4450
|
-
type
|
|
4435
|
+
type Role = AuthzEntityBase & SubjectTypeScoping & {
|
|
4451
4436
|
/** True when this catalog entry should be exposed as requestable access in IAM tooling. */
|
|
4452
4437
|
requestable?: boolean;
|
|
4453
|
-
/**
|
|
4454
|
-
roles?: Array<string | Role2>;
|
|
4455
|
-
/** Permissions this role confers (definitional). */
|
|
4438
|
+
/** Permissions this role confers (definitional). Roles are flat bundles — OAA has no nested-role edge. */
|
|
4456
4439
|
permissions?: Array<string | Permission>;
|
|
4457
4440
|
};
|
|
4458
|
-
type
|
|
4441
|
+
type Group = AuthzEntityBase & SubjectTypeScoping & {
|
|
4459
4442
|
/** True when this catalog entry should be exposed as requestable access in IAM tooling. */
|
|
4460
4443
|
requestable?: boolean;
|
|
4461
4444
|
/** Nested child groups composed into this group (definitional). */
|
|
4462
|
-
groups?: Array<string |
|
|
4445
|
+
groups?: Array<string | Group>;
|
|
4463
4446
|
/** Roles this group confers (group is the principal). Projected as OAA `local_group` role assignments. */
|
|
4464
|
-
roles?: Array<string |
|
|
4447
|
+
roles?: Array<string | Role>;
|
|
4465
4448
|
/** Permissions this group confers (group is the principal). Projected as OAA `local_group` application permissions. */
|
|
4466
4449
|
permissions?: Array<string | Permission>;
|
|
4467
4450
|
/**
|
|
@@ -4484,7 +4467,7 @@ type OaaAccessTargetType = "group" | "role" | "permission";
|
|
|
4484
4467
|
*/
|
|
4485
4468
|
type EntitlementType = OaaAccessTargetType;
|
|
4486
4469
|
/** A catalog Entitlement: a group, role, or permission (see {@link EntitlementType}). */
|
|
4487
|
-
type Entitlement =
|
|
4470
|
+
type Entitlement = Group | Role | Permission;
|
|
4488
4471
|
declare const ENTERPRISE_AUTHZ_GROUP_SCHEMA = "urn:enterprisestandard:params:scim:schemas:extension:authz:2.0:Group";
|
|
4489
4472
|
type AuthzScimGroupType = OaaAccessTargetType;
|
|
4490
4473
|
type AuthzScimGroupExtension = {
|
|
@@ -4529,24 +4512,27 @@ interface EntityStore<TEntity> {
|
|
|
4529
4512
|
list(options?: ListOptions): Promise<ListResult<TEntity>>;
|
|
4530
4513
|
/**
|
|
4531
4514
|
* Optional `externalId` secondary lookup. When implemented, the SDK resolves SCIM
|
|
4532
|
-
* `externalId eq "..."` filters through this index instead of a full `list()` scan (
|
|
4515
|
+
* `externalId eq "..."` filters through this index instead of a full `list()` scan (AUDIT_HISTORY.md §7.4).
|
|
4533
4516
|
* Returns the single entity with the given `externalId`, or `undefined` when none matches. Stores
|
|
4534
4517
|
* that omit it fall back to scanning `list()`.
|
|
4535
4518
|
*/
|
|
4536
4519
|
getByExternalId?(externalId: string): Promise<TEntity | undefined>;
|
|
4537
4520
|
}
|
|
4538
4521
|
/** The catalog entity kind a {@link CatalogChange} refers to. */
|
|
4539
|
-
type CatalogChangeKind = OaaAccessTargetType
|
|
4522
|
+
type CatalogChangeKind = OaaAccessTargetType;
|
|
4540
4523
|
/**
|
|
4541
4524
|
* A reactive catalog change emitted AFTER a durable `set()`/`delete()` lands on the backing store.
|
|
4542
4525
|
* `set` carries the persisted entity so subscribers can project exactly what was stored without an
|
|
4543
4526
|
* extra read; `delete` carries only the id, which the SDK projects as an incremental OAA entity
|
|
4544
4527
|
* delete (full incremental CRUD). A later full `oaa.sync` remains the reconciliation safety net.
|
|
4528
|
+
*
|
|
4529
|
+
* Resource changes are NOT catalog changes: resources live in the application's own store and are
|
|
4530
|
+
* signaled through {@link ResourceProvider.changed} instead.
|
|
4545
4531
|
*/
|
|
4546
4532
|
type CatalogChange = {
|
|
4547
4533
|
op: "set";
|
|
4548
4534
|
kind: CatalogChangeKind;
|
|
4549
|
-
entity:
|
|
4535
|
+
entity: Group | Role | Permission;
|
|
4550
4536
|
} | {
|
|
4551
4537
|
op: "delete";
|
|
4552
4538
|
kind: CatalogChangeKind;
|
|
@@ -4555,10 +4541,9 @@ type CatalogChange = {
|
|
|
4555
4541
|
/** Listener invoked with a {@link CatalogChange} after a durable catalog write lands. */
|
|
4556
4542
|
type CatalogChangeListener = (change: CatalogChange) => void;
|
|
4557
4543
|
type AccessCatalogStore = {
|
|
4558
|
-
groups: EntityStore<
|
|
4559
|
-
roles: EntityStore<
|
|
4544
|
+
groups: EntityStore<Group>;
|
|
4545
|
+
roles: EntityStore<Role>;
|
|
4560
4546
|
permissions: EntityStore<Permission>;
|
|
4561
|
-
resources: EntityStore<Resource>;
|
|
4562
4547
|
/**
|
|
4563
4548
|
* Reactive change subscription (the catalog analog of {@link ReactiveHandle}). When implemented,
|
|
4564
4549
|
* the SDK subscribes once at wiring time and projects each change to OAA. Stores that omit it do
|
|
@@ -4567,6 +4552,64 @@ type AccessCatalogStore = {
|
|
|
4567
4552
|
*/
|
|
4568
4553
|
afterChange?(listener: CatalogChangeListener): () => void;
|
|
4569
4554
|
};
|
|
4555
|
+
/** A resource change signaled by a {@link ResourceProvider} after the app's own write lands. */
|
|
4556
|
+
type ResourceChange = {
|
|
4557
|
+
id: string;
|
|
4558
|
+
deleted?: boolean;
|
|
4559
|
+
};
|
|
4560
|
+
/** Listener invoked with a {@link ResourceChange}; see {@link ResourceProvider.changed}. */
|
|
4561
|
+
type ResourceChangeListener = (change: ResourceChange) => void;
|
|
4562
|
+
/**
|
|
4563
|
+
* Read-through view over the application's own resource data (teams, projects, regions, ...).
|
|
4564
|
+
*
|
|
4565
|
+
* Resources are app-domain rows the application already persists in its own database/ORM — they are
|
|
4566
|
+
* NOT authorization state, so the SDK never stores a copy. Instead the app wires a `ResourceProvider`
|
|
4567
|
+
* (via `FrameworkStores.resources` / `AuthzConfig.resources`) and the SDK reads through it for
|
|
4568
|
+
* closure expansion, SCIM Group projection, and OAA projection. There is no seeding step, no
|
|
4569
|
+
* dual-write on CRUD routes, and no lifecycle to keep in sync: `db.insert(...)` (plus a `changed`
|
|
4570
|
+
* signal) is the whole integration.
|
|
4571
|
+
*
|
|
4572
|
+
* **Resource-derived entitlements.** `entitlements(resource)` is an app-authored PURE function that
|
|
4573
|
+
* derives the per-resource requestable entitlement {@link Group}s (e.g. "Team X (member)") on demand.
|
|
4574
|
+
* Unlike catalog entitlements (definitions authored as rows in the {@link AccessCatalogStore}),
|
|
4575
|
+
* resource-derived groups are rules, not rows: their definitions are never stored, they appear in
|
|
4576
|
+
* SCIM Groups list/get and OAA projection automatically, and member grants against their ids expand
|
|
4577
|
+
* with the group's `resources` scope like any catalog group (grants against both kinds are stored
|
|
4578
|
+
* identically as access roots). Keep the function next to your catalog entitlement definitions so the
|
|
4579
|
+
* logic stays grep-able and debuggable — it is plain code the SDK calls, not configuration.
|
|
4580
|
+
* `entitlement(id)` is the deliberate, app-authored reverse resolver (derived group id -> group);
|
|
4581
|
+
* both must be provided together.
|
|
4582
|
+
*/
|
|
4583
|
+
type ResourceProvider = {
|
|
4584
|
+
/** Point lookup by resource id (e.g. `'team:t1'`). */
|
|
4585
|
+
get(id: string): Promise<Resource | undefined>;
|
|
4586
|
+
/** Offset-paginated enumeration of all resources (standard `start`/`limit`/`total` ListResult). */
|
|
4587
|
+
list(options?: ListOptions): Promise<ListResult<Resource>>;
|
|
4588
|
+
/**
|
|
4589
|
+
* Direct children of a resource (for nested resource trees, e.g. a team's projects). When omitted,
|
|
4590
|
+
* the SDK falls back to the `Resource.resources` refs returned by `get`/`list`.
|
|
4591
|
+
*/
|
|
4592
|
+
children?(id: string): Promise<Resource[]>;
|
|
4593
|
+
/**
|
|
4594
|
+
* Pure, synchronous derivation of a resource's requestable entitlement {@link Group}s. Called on
|
|
4595
|
+
* demand (results are memoized alongside catalog adjacency and invalidated by `changed`); must be
|
|
4596
|
+
* deterministic for a given resource. Requires `entitlement` to be provided as well.
|
|
4597
|
+
*/
|
|
4598
|
+
entitlements?(resource: Resource): Group[];
|
|
4599
|
+
/**
|
|
4600
|
+
* Reverse resolution of a resource-derived entitlement id to its {@link Group} (or `undefined`
|
|
4601
|
+
* when the id is not a resource-derived entitlement). App-authored on purpose — the id scheme is
|
|
4602
|
+
* the app's, and an explicit resolver keeps derivation traceable. Required when `entitlements` is
|
|
4603
|
+
* provided.
|
|
4604
|
+
*/
|
|
4605
|
+
entitlement?(id: string): Promise<Group | undefined>;
|
|
4606
|
+
/**
|
|
4607
|
+
* Change signal invoked after the app's own resource write/delete lands. Drives adjacency-cache
|
|
4608
|
+
* invalidation, targeted index reconciliation, and incremental OAA resource projection. Returns an
|
|
4609
|
+
* unsubscribe function. Without it, drift is only repaired by a later full reconcile/sync.
|
|
4610
|
+
*/
|
|
4611
|
+
changed?(listener: ResourceChangeListener): () => void;
|
|
4612
|
+
};
|
|
4570
4613
|
/**
|
|
4571
4614
|
* Audit provenance captured for a granted root. The active OpenTelemetry trace is the
|
|
4572
4615
|
* primary correlator; vendor request/correlation ids are retained alongside it.
|
|
@@ -4614,7 +4657,7 @@ type SubjectScope = SubjectType | SubjectType[] | "any";
|
|
|
4614
4657
|
* Platform-wide ceiling of principal kinds the SDK currently allows to hold an entitlement. This is
|
|
4615
4658
|
* the upper bound on {@link SubjectTypeScoping.assignableSubjectTypes}: even an unset (unrestricted)
|
|
4616
4659
|
* entitlement is implicitly capped to these kinds. `customer` is intentionally excluded until the
|
|
4617
|
-
* customer-grant model (
|
|
4660
|
+
* customer-grant model (AUDIT_HISTORY.md §1.30) is resolved; granting a `customer` is rejected platform-wide.
|
|
4618
4661
|
*/
|
|
4619
4662
|
declare const PLATFORM_ASSIGNABLE_SUBJECT_TYPES: SubjectType[];
|
|
4620
4663
|
/**
|
|
@@ -4635,8 +4678,8 @@ declare function assertValidSubjectTypeScoping(entity: SubjectTypeScoping & {
|
|
|
4635
4678
|
*/
|
|
4636
4679
|
type AccessChange<
|
|
4637
4680
|
TUser = BaseUser,
|
|
4638
|
-
TGroup =
|
|
4639
|
-
TRole =
|
|
4681
|
+
TGroup = Group,
|
|
4682
|
+
TRole = Role,
|
|
4640
4683
|
TPermission = Permission
|
|
4641
4684
|
> = {
|
|
4642
4685
|
/** Deterministic id derived from `subjectType:subject:targetType:target[:scope]`; assigned by stores/orchestration. */
|
|
@@ -4683,7 +4726,7 @@ interface AccessAssignmentStore<TAccess = AccessChange> {
|
|
|
4683
4726
|
/**
|
|
4684
4727
|
* Optional batched form of {@link listByTarget}: return the active roots for many targets in one
|
|
4685
4728
|
* call, keyed by the input `"${targetType}:${target}"` string. When implemented, SCIM list projects
|
|
4686
|
-
* a whole page of entitlement members without an N+1 `listByTarget` fan-out (
|
|
4729
|
+
* a whole page of entitlement members without an N+1 `listByTarget` fan-out (AUDIT_HISTORY.md §7.4). Stores
|
|
4687
4730
|
* that omit it fall back to per-target `listByTarget`.
|
|
4688
4731
|
*/
|
|
4689
4732
|
listByTargets?(targets: Array<{
|
|
@@ -4703,7 +4746,7 @@ type SubjectRef = {
|
|
|
4703
4746
|
subjectType?: SubjectType;
|
|
4704
4747
|
};
|
|
4705
4748
|
/** A single check target, optionally scoped to a resource. */
|
|
4706
|
-
type AccessCheckTarget<TTarget =
|
|
4749
|
+
type AccessCheckTarget<TTarget = Group | Role | Permission> = {
|
|
4707
4750
|
targetType: OaaAccessTargetType;
|
|
4708
4751
|
target: AccessRef<TTarget>;
|
|
4709
4752
|
resource?: AccessRef<Resource>;
|
|
@@ -4732,9 +4775,9 @@ type EffectiveEdge = {
|
|
|
4732
4775
|
* Revoking one role removes only its rows — overlapping permissions from the other role remain.
|
|
4733
4776
|
*/
|
|
4734
4777
|
interface AccessIndex {
|
|
4735
|
-
has(subject: AccessRef<BaseUser>, targetType: OaaAccessTargetType, target: AccessRef<
|
|
4736
|
-
hasGroup(subject: AccessRef<BaseUser>, group: AccessRef<
|
|
4737
|
-
hasRole(subject: AccessRef<BaseUser>, role: AccessRef<
|
|
4778
|
+
has(subject: AccessRef<BaseUser>, targetType: OaaAccessTargetType, target: AccessRef<Group | Role | Permission>, resource?: AccessRef<Resource>, subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
4779
|
+
hasGroup(subject: AccessRef<BaseUser>, group: AccessRef<Group>, resource?: AccessRef<Resource>, subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
4780
|
+
hasRole(subject: AccessRef<BaseUser>, role: AccessRef<Role>, resource?: AccessRef<Resource>, subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
4738
4781
|
hasPermission(subject: AccessRef<BaseUser>, permission: AccessRef<Permission>, resource?: AccessRef<Resource>, subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
4739
4782
|
hasAny(subject: AccessRef<BaseUser>, targets: AccessCheckTarget[], subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
4740
4783
|
hasAll(subject: AccessRef<BaseUser>, targets: AccessCheckTarget[], subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
@@ -4750,6 +4793,18 @@ interface AccessIndex {
|
|
|
4750
4793
|
* enumerate subjects simply restrict full reconcile to subjects known from the assignment store.
|
|
4751
4794
|
*/
|
|
4752
4795
|
listSubjects?(): Promise<SubjectRef[]>;
|
|
4796
|
+
/**
|
|
4797
|
+
* Set or clear the subject-disabled marker. While set, every `has*` check for the subject MUST
|
|
4798
|
+
* deny (`allowed: false`, `metadata.reason: 'subject_disabled'`) without touching the subject's
|
|
4799
|
+
* grants — re-enabling restores the previous decisions unchanged. Driven by SCIM lifecycle
|
|
4800
|
+
* (`active: false` sets it, `active: true` clears it, delete clears it after revoking roots);
|
|
4801
|
+
* session invalidation stays the IdP's job (back-channel logout), this only blocks authorization.
|
|
4802
|
+
* The marker is independent of edge materialization: `materialize`/`removeByRoot`/`clear` and
|
|
4803
|
+
* reconcile never set or clear it. Optional, but implement it on any index used with SCIM Users.
|
|
4804
|
+
*/
|
|
4805
|
+
setSubjectDisabled?(subject: string, subjectType: SubjectType, disabled: boolean): Promise<void>;
|
|
4806
|
+
/** Whether the subject-disabled marker is currently set (see {@link setSubjectDisabled}). */
|
|
4807
|
+
isSubjectDisabled?(subject: string, subjectType?: SubjectType): Promise<boolean>;
|
|
4753
4808
|
}
|
|
4754
4809
|
type OaaSyncOptions = {
|
|
4755
4810
|
mode?: "snapshot" | "incremental";
|
|
@@ -4773,21 +4828,26 @@ type OaaSyncInput<
|
|
|
4773
4828
|
TResource
|
|
4774
4829
|
> = {
|
|
4775
4830
|
users?: Iterable<TUser> | AsyncIterable<TUser>;
|
|
4776
|
-
groups?: Iterable<TGroup |
|
|
4777
|
-
roles?: Iterable<
|
|
4831
|
+
groups?: Iterable<TGroup | Group> | AsyncIterable<TGroup | Group>;
|
|
4832
|
+
roles?: Iterable<Role> | AsyncIterable<Role>;
|
|
4778
4833
|
permissions?: Iterable<Permission> | AsyncIterable<Permission>;
|
|
4779
4834
|
resources?: Iterable<TResource> | AsyncIterable<TResource>;
|
|
4780
4835
|
access?: Iterable<AccessChange> | AsyncIterable<AccessChange>;
|
|
4781
4836
|
};
|
|
4837
|
+
/** One item in a batched incremental access push ({@link OaaClient.pushAccessChanges}). */
|
|
4838
|
+
type OaaAccessChangeBatchItem = {
|
|
4839
|
+
change: AccessChange;
|
|
4840
|
+
op: "add" | "delete";
|
|
4841
|
+
};
|
|
4782
4842
|
interface OaaClient<
|
|
4783
4843
|
TUser = BaseUser,
|
|
4784
|
-
TGroup =
|
|
4785
|
-
TRole =
|
|
4844
|
+
TGroup = Group,
|
|
4845
|
+
TRole = Role,
|
|
4786
4846
|
TPermission = Permission,
|
|
4787
4847
|
TResource = Resource
|
|
4788
4848
|
> {
|
|
4789
4849
|
pushUser(user: TUser): Promise<void>;
|
|
4790
|
-
pushGroup(group: TGroup |
|
|
4850
|
+
pushGroup(group: TGroup | Group): Promise<void>;
|
|
4791
4851
|
pushRole(role: TRole): Promise<void>;
|
|
4792
4852
|
pushPermission(permission: TPermission): Promise<void>;
|
|
4793
4853
|
pushResource(resource: TResource): Promise<void>;
|
|
@@ -4805,6 +4865,15 @@ interface OaaClient<
|
|
|
4805
4865
|
deleteResource(id: string): Promise<void>;
|
|
4806
4866
|
grant(change: AccessChange): Promise<void>;
|
|
4807
4867
|
revoke(change: AccessChange): Promise<void>;
|
|
4868
|
+
/**
|
|
4869
|
+
* Project a batch of access grants/revokes as ONE incremental payload (many
|
|
4870
|
+
* `identity_to_permissions` / `local_users` entries in a single request), rather than one HTTPS
|
|
4871
|
+
* push per change. Used by the SCIM mutation path so a group PUT with N member changes is O(1)
|
|
4872
|
+
* pushes, not O(N). Referentially-closed like {@link OaaClient.grant}: each `add` item's conferred
|
|
4873
|
+
* definitions are merged into the payload. Best-effort — a failure is non-fatal to the SCIM
|
|
4874
|
+
* response (a later full `sync` reconciles), same contract as the single-change methods.
|
|
4875
|
+
*/
|
|
4876
|
+
pushAccessChanges(items: OaaAccessChangeBatchItem[]): Promise<void>;
|
|
4808
4877
|
sync(input: OaaSyncInput<TUser, TGroup, TResource>, options?: OaaSyncOptions): Promise<OaaSyncResult>;
|
|
4809
4878
|
/**
|
|
4810
4879
|
* Synchronous readiness check. Returns true once OAA config (url, providerId,
|
|
@@ -4843,40 +4912,40 @@ type AccessMutationResult<TChange = AccessChange> = {
|
|
|
4843
4912
|
type ScimMutationSummary<TChange = AccessChange> = {
|
|
4844
4913
|
metadataApplied: boolean;
|
|
4845
4914
|
access: AccessMutationResult<TChange>[];
|
|
4915
|
+
/**
|
|
4916
|
+
* Best-effort egress outcome for the mutation, populated after the store loop commits. Egress (OAA
|
|
4917
|
+
* incremental push and IAM-delta patch-back) is awaited inside the request but is NON-fatal: a
|
|
4918
|
+
* failure sets `degraded` here and warn-logs, but never turns a committed store mutation into a SCIM
|
|
4919
|
+
* error. Absent when the mutation failed before egress ran or nothing was committed. The IAM server
|
|
4920
|
+
* relies on periodic full sync / its own aggregation to reconcile a degraded egress.
|
|
4921
|
+
*/
|
|
4922
|
+
egress?: EgressOutcome;
|
|
4923
|
+
};
|
|
4924
|
+
/**
|
|
4925
|
+
* Outcome of the best-effort egress fan-out that runs after a SCIM mutation's store writes commit.
|
|
4926
|
+
* Each channel is `ok` when it either succeeded or was not attempted (not configured). `degraded`
|
|
4927
|
+
* with a `reason` when the awaited push/patch-back failed.
|
|
4928
|
+
*/
|
|
4929
|
+
type EgressOutcome = {
|
|
4930
|
+
oaa: EgressChannelOutcome;
|
|
4931
|
+
delta: EgressChannelOutcome;
|
|
4932
|
+
};
|
|
4933
|
+
type EgressChannelOutcome = {
|
|
4934
|
+
status: "ok" | "degraded" | "skipped";
|
|
4935
|
+
reason?: string;
|
|
4846
4936
|
};
|
|
4847
4937
|
type AuthzDecision = {
|
|
4848
4938
|
allow: boolean;
|
|
4849
4939
|
matched?: AccessChange[];
|
|
4850
4940
|
metadata?: Record<string, unknown>;
|
|
4851
4941
|
};
|
|
4852
|
-
/**
|
|
4853
|
-
* Scope for {@link Authz.reconcile}. The `AccessIndex` is a disposable derivation of
|
|
4854
|
-
* `AccessAssignmentStore` roots + `AccessCatalogStore`; reconcile re-derives it (idempotently) at one
|
|
4855
|
-
* of three scopes:
|
|
4856
|
-
* - **per-root**: re-expand and re-materialize a single root (idempotent; the inline grant path).
|
|
4857
|
-
* - **per-subject**: clear the subject's index rows, then re-materialize its live roots. One pass
|
|
4858
|
-
* handles both adds and removes and bounds any deny window to that subject. Basis for SCIM delete
|
|
4859
|
-
* and partial-failure repair.
|
|
4860
|
-
* - **full** (`{ all: true }`): reconcile the union of assignment subjects and index subjects;
|
|
4861
|
-
* index subjects with no live roots are cleared to empty (sweeps orphans). Avoids a global clear so
|
|
4862
|
-
* there is no all-denied window. This is the rebuild that rides the periodic OAA full-sync cadence.
|
|
4863
|
-
*/
|
|
4864
|
-
type ReconcileScope = {
|
|
4865
|
-
root: AccessChange | string;
|
|
4866
|
-
} | {
|
|
4867
|
-
subject: string;
|
|
4868
|
-
subjectType?: SubjectType;
|
|
4869
|
-
} | {
|
|
4870
|
-
all: true;
|
|
4871
|
-
};
|
|
4872
|
-
/** Result of an {@link Authz.reconcile} run. */
|
|
4942
|
+
/** Result of an {@link Authz.reconcile} run (a full reconciliation). */
|
|
4873
4943
|
type ReconcileReport = {
|
|
4874
|
-
|
|
4875
|
-
/** Subjects reconciled (1 for per-subject; the union size for full; 0 for per-root). */
|
|
4944
|
+
/** Subjects reconciled (the union of assignment-store subjects and index subjects). */
|
|
4876
4945
|
subjects: number;
|
|
4877
4946
|
/** Roots re-expanded + re-materialized. */
|
|
4878
4947
|
roots: number;
|
|
4879
|
-
/** Subjects cleared because they had no live roots (orphans swept
|
|
4948
|
+
/** Subjects cleared because they had no live roots (orphans swept). */
|
|
4880
4949
|
cleared: number;
|
|
4881
4950
|
};
|
|
4882
4951
|
/**
|
|
@@ -4889,20 +4958,48 @@ type Authz = {
|
|
|
4889
4958
|
oaa: OaaClient;
|
|
4890
4959
|
/** The wired closure index powering `has*`, when the app provided one via stores. */
|
|
4891
4960
|
accessIndex?: AccessIndex;
|
|
4892
|
-
has(subject: AccessRef<BaseUser>, targetType: OaaAccessTargetType, target: AccessRef<
|
|
4893
|
-
hasGroup(subject: AccessRef<BaseUser>, group: AccessRef<
|
|
4894
|
-
hasRole(subject: AccessRef<BaseUser>, role: AccessRef<
|
|
4961
|
+
has(subject: AccessRef<BaseUser>, targetType: OaaAccessTargetType, target: AccessRef<Group | Role | Permission>, resource?: AccessRef<Resource>, subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
4962
|
+
hasGroup(subject: AccessRef<BaseUser>, group: AccessRef<Group>, resource?: AccessRef<Resource>, subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
4963
|
+
hasRole(subject: AccessRef<BaseUser>, role: AccessRef<Role>, resource?: AccessRef<Resource>, subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
4895
4964
|
hasPermission(subject: AccessRef<BaseUser>, permission: AccessRef<Permission>, resource?: AccessRef<Resource>, subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
4896
4965
|
hasAny(subject: AccessRef<BaseUser>, targets: AccessCheckTarget[], subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
4897
4966
|
hasAll(subject: AccessRef<BaseUser>, targets: AccessCheckTarget[], subjectType?: SubjectType): Promise<AuthzDecision>;
|
|
4898
4967
|
/**
|
|
4899
|
-
*
|
|
4900
|
-
*
|
|
4901
|
-
*
|
|
4902
|
-
*
|
|
4903
|
-
*
|
|
4968
|
+
* Run a **full reconciliation**: re-derive the entire `AccessIndex` from `AccessAssignmentStore`
|
|
4969
|
+
* roots + `AccessCatalogStore`. It enumerates the union of every assignment-store subject and every
|
|
4970
|
+
* index subject, re-expands every one of their roots through the catalog closure (`expandRoot`), and
|
|
4971
|
+
* sweeps orphaned index rows (subjects with no live roots). It is idempotent and SDK-owned; stores
|
|
4972
|
+
* only provide persistence.
|
|
4973
|
+
*
|
|
4974
|
+
* This is DELIBERATELY the only reconcile scope on the public surface, and it is EXPENSIVE: its time
|
|
4975
|
+
* and memory cost grow with the total number of grants (it lists and re-expands every root in the
|
|
4976
|
+
* system). Treat it as a maintenance/backstop operation, NOT a per-mutation step.
|
|
4977
|
+
*
|
|
4978
|
+
* WHEN to call it:
|
|
4979
|
+
* - From a cron job, scheduled worker, or queue task on a maintenance cadence (drift/orphan sweep).
|
|
4980
|
+
* - Via the SDK-owned, Ops-gated `POST ${basePath}/authz/oaa/sync` endpoint (which runs this full
|
|
4981
|
+
* reconcile and then a full OAA snapshot sync).
|
|
4982
|
+
*
|
|
4983
|
+
* When NOT to call it:
|
|
4984
|
+
* - NEVER inline with CRUD-style mutations. Catalog edits (`AccessCatalogStore` `afterChange`),
|
|
4985
|
+
* resource changes ({@link ResourceProvider.changed}), and SCIM grant/revoke/delete — including
|
|
4986
|
+
* automatic repair of a partially-applied SCIM mutation — are reconciled by the SDK internally
|
|
4987
|
+
* and targeted to the affected subjects. App code does not need to call `reconcile()` after a
|
|
4988
|
+
* catalog, resource, or membership write.
|
|
4989
|
+
*
|
|
4990
|
+
* Resolves to a {@link ReconcileReport}. No-op (empty report) when no `accessIndex`/`catalogStore`
|
|
4991
|
+
* is wired. Always run it off the request path.
|
|
4992
|
+
*/
|
|
4993
|
+
reconcile(): Promise<ReconcileReport>;
|
|
4994
|
+
/**
|
|
4995
|
+
* Resolve once the internal reconcile queue is drained (every catalog-/resource-change reconcile
|
|
4996
|
+
* enqueued so far has finished). Those reconciles are serialized and coalescing (a queued full
|
|
4997
|
+
* reconcile absorbs later ones); `settle()` returns the current queue tail so a caller can guarantee
|
|
4998
|
+
* request-triggered reconciles complete inside the request lifecycle (serverless-safe — no detached
|
|
4999
|
+
* reconcile survives the response). The SCIM mutation path awaits this after its store writes. It
|
|
5000
|
+
* never rejects (queued reconcile failures are isolated and logged).
|
|
4904
5001
|
*/
|
|
4905
|
-
|
|
5002
|
+
settle(): Promise<void>;
|
|
4906
5003
|
};
|
|
4907
5004
|
/** Why an {@link AccessCheckResult} resolved the way it did. */
|
|
4908
5005
|
type AccessCheckReason = "ok" | "unauthenticated" | "forbidden" | "not_configured";
|
|
@@ -4947,7 +5044,7 @@ declare function configTrustedClientGrants(authz: AuthzConfig | null | undefined
|
|
|
4947
5044
|
/**
|
|
4948
5045
|
* Resolve an access subject/target/resource reference (a string id or an object carrying one) to its
|
|
4949
5046
|
* canonical, trimmed string id. This is the single id-resolution rule shared across the authz stack
|
|
4950
|
-
* (
|
|
5047
|
+
* (AUDIT_HISTORY.md §8.4): `accessRootId`, the access stores, the access index, and SCIM diff keys all key off
|
|
4951
5048
|
* the same normalization so distinct roots never collapse and identical references never diverge.
|
|
4952
5049
|
* Returns `''` when no id can be resolved.
|
|
4953
5050
|
*/
|
|
@@ -4958,63 +5055,6 @@ declare function accessRefId(value: unknown): string;
|
|
|
4958
5055
|
* default, or `applyToApplication`) collapses to the `app` scope key.
|
|
4959
5056
|
*/
|
|
4960
5057
|
declare function accessRootId(change: AccessChange): string;
|
|
4961
|
-
/**
|
|
4962
|
-
* Memoizes catalog node reads (`groups/roles/permissions/resources.get`) and resolved sub-resource
|
|
4963
|
-
* trees across multiple `expandRoot` calls so that re-expanding many roots that share catalog nodes
|
|
4964
|
-
* (the reconcile path after a catalog change, AUDIT §7.4) does not re-read the same nodes once per
|
|
4965
|
-
* root. The cache is scoped to a single {@link AccessCatalogStore} instance (never module-global) so
|
|
4966
|
-
* it cannot bleed catalog state across tenants. Invalidate it (or `clear()` it) whenever the catalog
|
|
4967
|
-
* changes; the SDK wires this to the catalog's `afterChange` stream.
|
|
4968
|
-
*/
|
|
4969
|
-
declare class CatalogAdjacencyCache {
|
|
4970
|
-
private readonly catalog;
|
|
4971
|
-
private readonly nodes;
|
|
4972
|
-
private readonly subResources;
|
|
4973
|
-
constructor(catalog: AccessCatalogStore);
|
|
4974
|
-
getNode(kind: "group" | "role" | "permission" | "resource", id: string): Promise<Group2 | Role2 | Permission | Resource | undefined>;
|
|
4975
|
-
resourceAndSubResourceIds(resourceId: string): Promise<string[]>;
|
|
4976
|
-
/**
|
|
4977
|
-
* Drop memoized entries affected by a catalog change. Catalog edits are infrequent relative to
|
|
4978
|
-
* reads, and graph/resource-tree edges are interdependent, so we clear conservatively: the changed
|
|
4979
|
-
* node plus the whole resource sub-tree memo (a single edit can change many sub-trees).
|
|
4980
|
-
*/
|
|
4981
|
-
invalidate(_change?: CatalogChange): void;
|
|
4982
|
-
clear(): void;
|
|
4983
|
-
}
|
|
4984
|
-
/**
|
|
4985
|
-
* Expand a granted root into the set of effective edges it justifies, traversing the catalog
|
|
4986
|
-
* composition graph (`Group.groups/roles/permissions`, `Role.roles/permissions`). Cycles are
|
|
4987
|
-
* tolerated via a per-root visited set. Resource-scoped permissions that declare
|
|
4988
|
-
* `applyToSubResources` are expanded across the resource's sub-resource tree.
|
|
4989
|
-
*
|
|
4990
|
-
* Catalog-graph or resource-tree drift is repaired off the request path via
|
|
4991
|
-
* `es.authz.reconcile` (catalog `afterChange` triggers targeted or full reconcile).
|
|
4992
|
-
*
|
|
4993
|
-
* Pass a {@link CatalogAdjacencyCache} to memoize catalog node reads across many roots (the
|
|
4994
|
-
* reconcile path, AUDIT §7.4); omit it to read the catalog directly per node.
|
|
4995
|
-
*/
|
|
4996
|
-
declare function expandRoot(root: AccessChange, catalog: AccessCatalogStore, cache?: CatalogAdjacencyCache): Promise<EffectiveEdge[]>;
|
|
4997
|
-
/**
|
|
4998
|
-
* The catalog entity definitions transitively referenced by an entitlement (group or role): the
|
|
4999
|
-
* conferred roles (and their nested roles), permissions, nested groups, and resource scopes. Used to
|
|
5000
|
-
* make an incremental OAA push referentially closed — every id an entitlement references is
|
|
5001
|
-
* accompanied by its definition so the downstream projection never carries a dangling reference.
|
|
5002
|
-
*/
|
|
5003
|
-
type ReferencedDefinitions = {
|
|
5004
|
-
groups: Group2[];
|
|
5005
|
-
roles: Role2[];
|
|
5006
|
-
permissions: Permission[];
|
|
5007
|
-
resources: Resource[];
|
|
5008
|
-
};
|
|
5009
|
-
/**
|
|
5010
|
-
* Collect the catalog definitions reachable from an entitlement's own references, EXCLUDING the root
|
|
5011
|
-
* entity itself (the caller pushes that separately). Walks `Group.groups/roles/permissions/resources`
|
|
5012
|
-
* and `Role.roles/permissions`, plus each resource's sub-resource tree. String references are
|
|
5013
|
-
* resolved through the catalog (or the shared {@link CatalogAdjacencyCache}); inline object
|
|
5014
|
-
* references are used directly. Unresolvable string ids are skipped (a later full sync reconciles).
|
|
5015
|
-
* Cycle-safe via a per-call visited set.
|
|
5016
|
-
*/
|
|
5017
|
-
declare function collectReferencedDefinitions(root: Group2 | Role2, rootKind: "group" | "role", catalog: AccessCatalogStore, cache?: CatalogAdjacencyCache): Promise<ReferencedDefinitions>;
|
|
5018
5058
|
type EsCapabilityKey = "sso.login" | "sso.jit" | "sso.logout" | "sso.back_channel_logout" | "ciam.magic_link" | "ciam.oidc_login" | "ciam.customer" | "ciam.logout" | "iam.users" | "iam.groups" | "workload.incoming" | "workload.outgoing" | "authz.oaa";
|
|
5019
5059
|
type EsCapabilityEndpointUrls = {
|
|
5020
5060
|
readyzUrl: string;
|
|
@@ -5061,6 +5101,48 @@ type EsCapabilitiezManifest = {
|
|
|
5061
5101
|
capabilities: Record<EsCapabilityKey, EsCapabilityState>;
|
|
5062
5102
|
};
|
|
5063
5103
|
/**
|
|
5104
|
+
* Fields a {@link ConfigSource} may attach to a thrown error so the SDK can classify load/subscribe
|
|
5105
|
+
* failures structurally instead of by fragile message-substring matching (§2.1). All fields are
|
|
5106
|
+
* optional except `kind`; a custom source SHOULD set as many as it knows.
|
|
5107
|
+
*/
|
|
5108
|
+
type ConfigSourceErrorInit = {
|
|
5109
|
+
/** Best-effort classification of the failure. */
|
|
5110
|
+
kind: RemoteConfigLoadErrorKind;
|
|
5111
|
+
/**
|
|
5112
|
+
* Explicit recoverability. When set, it wins over any heuristic: `true` forces a retry, `false`
|
|
5113
|
+
* forces the initial load to reject `ready()` permanently. Omit to let the SDK decide (retry unless
|
|
5114
|
+
* provably unrecoverable).
|
|
5115
|
+
*/
|
|
5116
|
+
recoverable?: boolean;
|
|
5117
|
+
/** Transport/error code when known (e.g. `'ECONNREFUSED'`, `'not_found'`). */
|
|
5118
|
+
code?: string;
|
|
5119
|
+
/** HTTP-like status when known (e.g. `401`, `503`). */
|
|
5120
|
+
status?: number;
|
|
5121
|
+
/** Config path/key when known. */
|
|
5122
|
+
path?: string;
|
|
5123
|
+
/** Config source transport when known (e.g. `'vault'`, `'azure'`). */
|
|
5124
|
+
sourceType?: ConfigSourceType | string;
|
|
5125
|
+
/** Underlying cause, preserved on the standard `Error.cause` chain. */
|
|
5126
|
+
cause?: unknown;
|
|
5127
|
+
};
|
|
5128
|
+
/**
|
|
5129
|
+
* Structured error a {@link ConfigSource} can throw from `load()`/`subscribe()` so the SDK classifies
|
|
5130
|
+
* and retries it based on typed fields rather than message substrings. The vault source's typed errors
|
|
5131
|
+
* already carry `code`/`status`/`sourceType`; custom sources SHOULD throw this (or an error carrying
|
|
5132
|
+
* the same fields) for the initial-load retry policy to make the right call. See
|
|
5133
|
+
* https://enterprisestandard.com/llms-configuration.txt.
|
|
5134
|
+
*/
|
|
5135
|
+
declare class ConfigSourceError extends Error {
|
|
5136
|
+
readonly kind: RemoteConfigLoadErrorKind;
|
|
5137
|
+
readonly recoverable?: boolean;
|
|
5138
|
+
readonly code?: string;
|
|
5139
|
+
readonly status?: number;
|
|
5140
|
+
readonly path?: string;
|
|
5141
|
+
readonly sourceType?: ConfigSourceType | string;
|
|
5142
|
+
constructor(message: string, init: ConfigSourceErrorInit);
|
|
5143
|
+
}
|
|
5144
|
+
declare function isConfigSourceError(value: unknown): value is ConfigSourceError;
|
|
5145
|
+
/**
|
|
5064
5146
|
* Enterprise Controlled ID (ECID) helpers.
|
|
5065
5147
|
*
|
|
5066
5148
|
* The ECID is a stable, system-of-record-owned identifier for a single identity (a person or a
|
|
@@ -5148,25 +5230,6 @@ type LfvEd25519PrivateJwk = LfvEd25519PublicJwk & {
|
|
|
5148
5230
|
type LfvJwks = {
|
|
5149
5231
|
keys: LfvEd25519PublicJwk[];
|
|
5150
5232
|
};
|
|
5151
|
-
declare function buildLfvSigningInput(requestId: string, rawBody: string | Uint8Array): Uint8Array;
|
|
5152
|
-
declare function parseLfvJwks(jwksJson: string): LfvJwks;
|
|
5153
|
-
declare function stringifyLfvJwks(jwks: LfvJwks): string;
|
|
5154
|
-
declare function verifyLfvSignature(params: {
|
|
5155
|
-
jwks: string | LfvJwks;
|
|
5156
|
-
kid: string;
|
|
5157
|
-
signatureB64Url: string;
|
|
5158
|
-
requestId: string;
|
|
5159
|
-
rawBody: string;
|
|
5160
|
-
}): Promise<boolean>;
|
|
5161
|
-
declare function signLfvPayload(params: {
|
|
5162
|
-
privateKeyJwk: LfvEd25519PrivateJwk;
|
|
5163
|
-
requestId: string;
|
|
5164
|
-
rawBody: string;
|
|
5165
|
-
}): Promise<string>;
|
|
5166
|
-
declare function generateLfvEd25519KeyPair(kid: string): Promise<{
|
|
5167
|
-
privateJwk: LfvEd25519PrivateJwk;
|
|
5168
|
-
publicJwks: LfvJwks;
|
|
5169
|
-
}>;
|
|
5170
5233
|
/**
|
|
5171
5234
|
* List result from total count, sliced items, start index, and optional limit.
|
|
5172
5235
|
* When limit is omitted, size is set to total (one logical page), page and pages are 1.
|
|
@@ -5190,27 +5253,6 @@ declare function listGenerator<T>(listFn: (start: number, limit: number) => Prom
|
|
|
5190
5253
|
* {@link ReadyAccessCatalogEntry.ready} is awaited.
|
|
5191
5254
|
*/
|
|
5192
5255
|
declare function readyCatalogEntry<TEntity extends object>(entity: TEntity, write: Promise<void>): ReadyAccessCatalogEntry<TEntity>;
|
|
5193
|
-
type SessionResponse = {
|
|
5194
|
-
sid: string;
|
|
5195
|
-
authType: "sso" | "ciam";
|
|
5196
|
-
tenantId?: string;
|
|
5197
|
-
sub: string;
|
|
5198
|
-
expiresAt?: Date | string;
|
|
5199
|
-
createdAt: Date | string;
|
|
5200
|
-
lastActivityAt: Date | string;
|
|
5201
|
-
claims?: Record<string, unknown>;
|
|
5202
|
-
};
|
|
5203
|
-
type SessionDiscoveryOptions = {
|
|
5204
|
-
/**
|
|
5205
|
-
* Restrict discovery to session cookies whose name is `${cookiesPrefix}.session`. Pass the
|
|
5206
|
-
* SSO/CIAM `cookiesPrefix` (or several prefixes) so an app-owned switcher on a SHARED session
|
|
5207
|
-
* store only surfaces its own sessions instead of every `*.session` cookie present on the host.
|
|
5208
|
-
* When omitted, any `*.session` cookie is considered (single-app/dev convenience).
|
|
5209
|
-
*/
|
|
5210
|
-
cookiesPrefix?: string | string[];
|
|
5211
|
-
};
|
|
5212
|
-
declare function discoverSessions(request: Request, sessionStore: SessionStore, options?: SessionDiscoveryOptions): Promise<SessionResponse[]>;
|
|
5213
|
-
declare function discoverSessionRecords(request: Request, sessionStore: SessionStore, options?: SessionDiscoveryOptions): Promise<Session[]>;
|
|
5214
5256
|
/**
|
|
5215
5257
|
* Typed store-layer conflict (§5.9). Persistence stores throw this instead of a generic `Error` when
|
|
5216
5258
|
* a create/uniqueness invariant is violated, so callers (SCIM, iam-delta, app code) can distinguish a
|
|
@@ -5369,4 +5411,4 @@ type LfvErrorResponse = {
|
|
|
5369
5411
|
};
|
|
5370
5412
|
/** Generates a ULID */
|
|
5371
5413
|
declare function generateULID(prefix?: string): string;
|
|
5372
|
-
export { workloadTokenResponseSchema, withValidate,
|
|
5414
|
+
export { workloadTokenResponseSchema, withValidate, warnLogger, waitOn, version, validationFailureResponse, userSchema, unionCatalogRead, trustedClientPermissionsForPrincipal, trimTrailingSlash, tokenResponseSchema, toCodeCatalog, stripJsonComments, stableConfigHash, silentLogger, serializeESConfig, readyCatalogEntry, parseJsonc, parseEcid, oidcCallbackSchema, normalizeTenantRoutingStrategy, normalizeTenantPathNamespace, must, mergeConfig, matchTenantPath, listGenerator, list, jwtAssertionClaimsSchema, isStoreConflictError, isEcid, isConfigSourceError, isConfigLocator, isCodeCatalog, infoLogger, idTokenClaimsSchema, groupResourceSchema, generateULID, formatEcid, defineCatalog, defaultLogger, deepEqualPlain, decodeUser, debugLogger, configTrustedClientGrants, claimsToUser, buildTenantPath, assertValidSubjectTypeScoping, assertEcid, accessRootId, accessRefId, X509Certificate, WorkloadValidators, WorkloadTokenStore, WorkloadTokenResponse, WorkloadPrincipal, WorkloadIncomingOutgoing, WorkloadIdentityStore, WorkloadIdentity, WorkloadGetToken, WorkloadConfigMap, WorkloadConfig, WorkloadClient, Workload, WorkforceUser, VaultWorkloadAuthConfig, VaultWebSocketSecretsConfig, VaultWebSocketAuthHeader, VaultSecretsConfig, VaultLfvSecretsConfig, VaultConfigLocator, ValidateResult, UsersInboundHandlerConfig, UserStoreOptions, UserStore, UpdateTenantRequest, TrustedProvisioningClient, TrustedIdp, TokenValidationResult, TokenResponse, TenantWebhookPayload, TenantValidators, TenantStore, TenantStatus, TenantRoutingStrategy, TenantResponse, TenantPathRoutingStrategy, TenantPathNamespace, TenantPathMatch, TenantEsFactory, TenantEsCache, TenantConfigLocator, SubscriptionMode, SubjectTypeScoping, SubjectType, SubjectScope, SubjectRef, StoreConflictKind, StoreConflictError, StateCookie, StandardSchemaWithValidate, SessionStore, Session, ServerOnlyWorkloadConfig, SecretsValidators, SecretsSubscriptionOptions, SecretsSourceType, SecretsSourceMap, SecretsSourceConfig, SecretsSource, SecretsOperationOptions, SecretsModuleConfig, Secrets, SecretRequestSeverity, SecretLifecycleRequest, Secret, User as ScimUser, ScimServiceProviderConfig, ScimSchemaDefinition, ScimSchemaAttributeDefinition, Role2 as ScimRole, ScimResult, ScimResourceTypeSchemaExtension, ScimResourceType, ScimMutationSummary, ScimListResponse, Group2 as ScimGroup, ScimError, ScimAuthenticationScheme, SSOValidators, SSOHandlerConfig, SSOConfigFromCode, SSOConfig, SSOAppValidators, SSOAppRegistry, SSO, Role, ResourceProvider, ResourceChangeListener, ResourceChange, Resource, ResolvedVaultLfvSecretsConfig, RequireReadyResult, RemoteConfigRetryOptions, RemoteConfigRetryHook, RemoteConfigRetryContext, RemoteConfigLoadErrorKind, RemoteConfig, RegisterSSOAppResult, RegisterSSOAppPayload, RegisterSSOAppError, RegisterIAMAppResult, RegisterIAMAppPayload, RegisterIAMAppError, ReconcileReport, ReadyzEndpointConfig, ReadyAccessCatalogEntry, ReadinessReport, ReactiveHandle, Photo, PhoneNumber, Permission, ParsedEcid, PLATFORM_ASSIGNABLE_SUBJECT_TYPES, OtelSignalName, OtelSignalConfig, OtelProviderType, OtelProtocol, OtelOAuthClientCredentialsConfig, OtelMetricsSignalConfig, OtelLogRecord, OtelLogLevel, OtelLevels, OtelConfig, OtelAttributes, OtelAttributeValue, Otel, OidcCallbackParams, OaaSyncResult, OaaSyncOptions, OaaSyncInput, OaaClient, OaaAccessTargetType, OaaAccessChangeBatchItem, Name, ModuleReadinessState, ModuleReadiness, ModifiableFrameworkConfig, MetaData, MagicLinkStore, MagicLink, Logger, ListResult, ListOptions, ListFilter, LfvOtpResponse, LfvOtpRequest, LfvJwks, LfvErrorResponse, LfvErrorCode, LfvEd25519PublicJwk, LfvEd25519PrivateJwk, LfvActionRequestBase, LfvActionName, LfvActionAcceptedResponse, JwtBearerWorkloadConfig, JWTAssertionClaims, InMemoryTenantStoreOptions, IdentityResolution, IdTokenClaims, IamDeltaResourceType, IamDeltaReconcileResult, IamDeltaMode, IamDeltaIdMapStore, IamDeltaIdMapKey, IamDeltaEmitter, IAMValidators, IAMUsersInbound, IAMInboundUsersConfig, IAMInboundUserContext, IAMHandlerConfig, IAMGroupsOutbound, IAMGroupsInbound, IAMDiscoveryHandlerConfig, IAMDiscoveryContext, IAMDiscoveryConfig, IAMConfigFromCode, IAMConfig, IAMAppValidators, IAMAppRegistry, IAM, GroupsInboundHandlerConfig, GroupResource, GroupMember, Group, GcpSecretsConfig, GcpConfigLocator, FrameworkWorkloadIncomingOutgoing, FrameworkWorkloadConfigFromCode, FrameworkWorkloadConfig, FrameworkStores, FrameworkSecretsSourceConfig, FrameworkSecretsModuleConfig, FrameworkOtelConfig, FrameworkConfigInput, FrameworkConfig, EsUserExtension, EsModuleName, EsEndpointPermission, EsEndpointOperation, EsCapabilityState, EsCapabilityKey, EsCapabilityEndpointUrls, EsCapabilitiezManifest, EnvironmentType, EntityStore, EntitlementType, Entitlement, EnterpriseStandardBase, EnterpriseStandard, EnterpriseExtension, Email, EgressOutcome, EgressChannelOutcome, EffectiveEdge, EcidFormatError, ES_TENANT_MANAGE, ES_SDK_PERMISSIONS, ES_SCIM_USER_EXTENSION_URN, ES_IAM_USERS_WRITE, ES_IAM_READ, ES_IAM_GROUPS_WRITE, ES_ENDPOINT_PERMISSIONS, ES_CIAM_MAGIC_LINK_CREATE, ES_CAPABILITIEZ_READ, ES_AUTHZ_OAA_SYNC, ESValidators, ESRoutingOptions, ESRouteModule, ESRouteFilterResult, ESResolvedRoute, ESErrorOptions, ESError, ESConfigChangeResult, ESConfigChangeOptions, ESConfigChangeCallback, ESConfig, ENTERPRISE_AUTHZ_GROUP_SCHEMA, ECID_SCHEME, DevSecretsConfig, DEFAULT_TENANT_UI_NAMESPACE, DEFAULT_TENANT_API_NAMESPACE, CustomerStoreOptions, CustomerStore, Customer, CreateUserOptions, CreateTenantRequest, CreateGroupOptions, ConfigSubscriptionOptions, ConfigSourceType, ConfigSourceResolver, ConfigSourceErrorInit, ConfigSourceError, ConfigSourceEnv, ConfigSource, ConfigLocator, ConfigErrorKind, ConfigApplyStatus, CodeCatalogNamespace, CodeCatalogInput, CodeCatalog, ClientCredentialsWorkloadConfig, ChangeListener, CatalogChangeListener, CatalogChangeKind, CatalogChange, CachedWorkloadToken, CacheConfig, CIAMValidators, CIAMProviderType, CIAMProviderDescriptor, CIAMProviderConfig, CIAMProviderColors, CIAMProviderBranding, CIAMConfigFromCodeInput, CIAMConfigFromCode, CIAMConfig, CIAM, BaseWorkloadIdentity, BaseUser, BaseTenant, BaseCustomer, AzureSecretsConfig, AzureConfigLocator, AzureAuthMethod, AwsSecretsConfig, AwsConfigLocator, AuthzScimGroupType, AuthzScimGroupExtension, AuthzOaaConfig, AuthzEntityBase, AuthzDecision, AuthzConfig, Authz, AuthenticatedUser, AuthenticatedPrincipal, ApplicationValidators, Address, AccessStatus, AccessRef, AccessProvenance, AccessMutationStatus, AccessMutationResult, AccessIndex, AccessCheckTarget, AccessCheckResult, AccessCheckReason, AccessChange, AccessCatalogStore, AccessAssignmentStore };
|