@ionite/core 0.0.22 → 0.0.23-beta.20260729.1
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 +14 -14
- package/dist/index.js +1 -1
- package/dist/server.d.ts +10 -10
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1136,7 +1136,7 @@ type ModuleReadinessState = {
|
|
|
1136
1136
|
* Holistic, read-only readiness snapshot for an ionite instance. Returned by
|
|
1137
1137
|
* `ion.readiness()` and used by the built-in `${basePath}/readyz` endpoint. This is composition
|
|
1138
1138
|
* DATA, not a request gate: applications combine it (via `ion.requireReady([...])`) with their own
|
|
1139
|
-
* non-
|
|
1139
|
+
* non-ionite dependency checks to build their health endpoints.
|
|
1140
1140
|
*/
|
|
1141
1141
|
type ReadinessReport = {
|
|
1142
1142
|
/** True when config has been applied (`applied`) and every ACTIVE module is ready. */
|
|
@@ -1615,7 +1615,7 @@ type TrustedIdp = {
|
|
|
1615
1615
|
* Workload config with separate incoming (server) and outgoing (client) roles.
|
|
1616
1616
|
* - **incoming**: Server-only config for validating tokens presented to this app. Either a single
|
|
1617
1617
|
* `{ jwksUri, issuer }` config, or a list of {@link TrustedIdp} entries for multi-IdP trust.
|
|
1618
|
-
* - **outgoing**: Map of named clients for outbound calls; use getWorkloadToken(client, ion, scope?) from server (client is required and must be one of the outgoing names; pass the
|
|
1618
|
+
* - **outgoing**: Map of named clients for outbound calls; use getWorkloadToken(client, ion, scope?) from server (client is required and must be one of the outgoing names; pass the Ionite instance).
|
|
1619
1619
|
*/
|
|
1620
1620
|
type WorkloadIncomingOutgoing = {
|
|
1621
1621
|
incoming?: Partial<WorkloadConfig> | TrustedIdp[];
|
|
@@ -2424,7 +2424,7 @@ declare function stripJsonComments(content: string): string;
|
|
|
2424
2424
|
declare function parseJsonc<T>(content: string): T;
|
|
2425
2425
|
/**
|
|
2426
2426
|
* Trim trailing slashes from a routing path while preserving the lone root `'/'`. This is the single
|
|
2427
|
-
* shared rule used by the
|
|
2427
|
+
* shared rule used by the ionite routing surfaces (router, tenant-manager, adaptive-framework URL
|
|
2428
2428
|
* derivation, IAM discovery) so trailing-slash normalization can never drift between them (§8.4).
|
|
2429
2429
|
*
|
|
2430
2430
|
* Note: this is intentionally NOT used by the redirect/LFV path-COMPARE helpers (which deliberately
|
|
@@ -3227,7 +3227,7 @@ type ConfigLocator = VaultConfigLocator | AwsConfigLocator | AzureConfigLocator
|
|
|
3227
3227
|
* - `path`: the tenant-specific secret path within that source.
|
|
3228
3228
|
* - `ttl` (optional): poll interval (ms) for the tenant config subscription.
|
|
3229
3229
|
*
|
|
3230
|
-
* This keeps credentials/connection wiring on the root
|
|
3230
|
+
* This keeps credentials/connection wiring on the root Ionite (ConfigSource-owned) and out of the tenant
|
|
3231
3231
|
* store, and forces apps to declare their secrets sources up front rather than spinning them up
|
|
3232
3232
|
* ad-hoc per tenant.
|
|
3233
3233
|
*/
|
|
@@ -3238,7 +3238,7 @@ type TenantConfigLocator = {
|
|
|
3238
3238
|
};
|
|
3239
3239
|
/**
|
|
3240
3240
|
* Minimal handle needed to materialize a tenant's {@link ConfigSource} from a {@link TenantConfigLocator}.
|
|
3241
|
-
* Structurally satisfied by an `Ionite` instance (`
|
|
3241
|
+
* Structurally satisfied by an `Ionite` instance (`ion`): the default `secret` client plus
|
|
3242
3242
|
* the optional named `secrets` sources.
|
|
3243
3243
|
*/
|
|
3244
3244
|
type ConfigSourceResolver = {
|
|
@@ -3280,7 +3280,7 @@ type AuthzOaaConfig = {
|
|
|
3280
3280
|
};
|
|
3281
3281
|
};
|
|
3282
3282
|
/**
|
|
3283
|
-
* A config-declared workload client that is pre-authorized to hold specific `
|
|
3283
|
+
* A config-declared workload client that is pre-authorized to hold specific `ion:*` (or app) permissions
|
|
3284
3284
|
* WITHOUT a stored grant in the AccessAssignmentStore. This is a read-path overlay used for bootstrap
|
|
3285
3285
|
* and provisioning identities (e.g. the deployer, tenant provisioning, SCIM aggregators) so the SDK
|
|
3286
3286
|
* never has to write seed grants to a remote store at initialization (see
|
|
@@ -3389,7 +3389,7 @@ type FrameworkConfig = {
|
|
|
3389
3389
|
validators: IoniteValidators;
|
|
3390
3390
|
};
|
|
3391
3391
|
/**
|
|
3392
|
-
*
|
|
3392
|
+
* ionite-mounted endpoint paths are deterministic from `basePath` and are NOT customizable in code.
|
|
3393
3393
|
* The `*FromCode` types below strip those endpoint URLs from the module config that application
|
|
3394
3394
|
* code may pass. App-owned redirect behavior comes from the `beforeLogin`/`afterLogin`/`beforeLogout`/
|
|
3395
3395
|
* `afterLogout` callbacks, which are code-only and therefore kept. RemoteConfig-only intent flags (e.g. IAM `users`/`groups`
|
|
@@ -3812,7 +3812,7 @@ type CIAM<
|
|
|
3812
3812
|
ready?: (timeout?: number) => Promise<void>;
|
|
3813
3813
|
};
|
|
3814
3814
|
/**
|
|
3815
|
-
* CIAM config that code may provide; excludes vault-only secrets (`providers`) and
|
|
3815
|
+
* CIAM config that code may provide; excludes vault-only secrets (`providers`) and ionite-derived
|
|
3816
3816
|
* endpoint URLs (`customerLoginUrl`, `customerCallbackUrl`, `customerProvidersUrl`).
|
|
3817
3817
|
*/
|
|
3818
3818
|
type CIAMConfigFromCode<
|
|
@@ -3903,7 +3903,7 @@ type IoniteBase = {
|
|
|
3903
3903
|
/**
|
|
3904
3904
|
* Holistic, read-only readiness snapshot: per-module readiness plus config-application status.
|
|
3905
3905
|
* Composition data for building health endpoints; does not gate the request path. Combine with
|
|
3906
|
-
* `requireReady([...])` and your own non-
|
|
3906
|
+
* `requireReady([...])` and your own non-ionite service checks in your `/readyz` handler.
|
|
3907
3907
|
*/
|
|
3908
3908
|
readiness(): ReadinessReport;
|
|
3909
3909
|
/**
|
|
@@ -3976,7 +3976,7 @@ type RoutingOptions = {
|
|
|
3976
3976
|
/**
|
|
3977
3977
|
* Optional hooks for config application lifecycle in `ionite(...)`.
|
|
3978
3978
|
* - beforeChange runs before applying config and can return overrides.
|
|
3979
|
-
* - afterChange runs after applying config and receives the configured
|
|
3979
|
+
* - afterChange runs after applying config and receives the configured Ionite instance.
|
|
3980
3980
|
*/
|
|
3981
3981
|
type ConfigChangeOptions = {
|
|
3982
3982
|
beforeChange?: ConfigChangeCallback;
|
|
@@ -4101,8 +4101,8 @@ type BaseTenant = {
|
|
|
4101
4101
|
updatedAt: Date;
|
|
4102
4102
|
/**
|
|
4103
4103
|
* Serializable pointer used to materialize this tenant's ConfigSource. Resolves against the root
|
|
4104
|
-
*
|
|
4105
|
-
* Required: every tenant has config, so `
|
|
4104
|
+
* ionite secrets sources ({@link TenantConfigLocator}); carries no connection details or credentials.
|
|
4105
|
+
* Required: every tenant has config, so `createIon`/`tenantConfigSource` can rely on it without a
|
|
4106
4106
|
* runtime presence guard.
|
|
4107
4107
|
*/
|
|
4108
4108
|
configLocator: TenantConfigLocator;
|
|
@@ -4122,7 +4122,7 @@ type TenantFactory<TTenant extends BaseTenant = BaseTenant> = (tenant: TTenant)
|
|
|
4122
4122
|
* const ionCache = new LRUCache<string, Ionite>({
|
|
4123
4123
|
* max: 100,
|
|
4124
4124
|
* ttl: 1000 * 60 * 60,
|
|
4125
|
-
* dispose: (
|
|
4125
|
+
* dispose: (ion) => ion.close(), // full lifecycle: evicted/invalidated runtimes are closed
|
|
4126
4126
|
* fetchMethod: async (id) => {
|
|
4127
4127
|
* const tenant = await tenants.get(id); // `tenants` assigned below; resolved at call time
|
|
4128
4128
|
* return tenant ? createTenantIon(tenant) : undefined;
|
|
@@ -4182,7 +4182,7 @@ type BaseUser<TExtended = object> = BaseUserFields & {
|
|
|
4182
4182
|
* Optional Enterprise Controlled ID: a system-of-record-owned identity correlator formatted as
|
|
4183
4183
|
* `ecid:<realm>:<opaque>` (realm = the minting authority's id). Correlates this account to a
|
|
4184
4184
|
* single identity across systems. Minted by the enterprise SOR (via an ECI), never by the app;
|
|
4185
|
-
* received on the SCIM
|
|
4185
|
+
* received on the SCIM ionite extension or the `ecid` JWT claim. Never an authorization subject.
|
|
4186
4186
|
* See https://ionite.com/docs/llms-ecid.txt.
|
|
4187
4187
|
*/
|
|
4188
4188
|
ecid?: string;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as K0,B as C0,C as W0,D as P0,E as D0,F as k0,G as E0,H as v0,I as w0,J as S0,K as R0,L as T0,M as b0,N as L0,Q as I0,R as N0,S as y0,T as A0,U as _0,V as f0,a as r,b as t,c as s,d as e,e as Q0,f as X0,l as $0,m as J0,n as V0,o as B0,p as x0,q as Z0,r as F0,s as H0,t as q0,u as G0,v as U0,w as j0,x as Y0,y as z0,z as M0}from"./shared/core-02035cvg.js";var S="0.0.22";class j extends Error{kind;recoverable;code;status;path;sourceType;constructor($,J){super($,J.cause!==void 0?{cause:J.cause}:void 0);this.name="ConfigSourceError",this.kind=J.kind,this.recoverable=J.recoverable,this.code=J.code,this.status=J.status,this.path=J.path,this.sourceType=J.sourceType,Object.setPrototypeOf(this,j.prototype)}}function R($){return $ instanceof j}var Z=["workload"],Y={id:"ion:iam:read",name:"Read Identities (SCIM)",description:"Authorizes a workload to list and read Users and Groups via the SCIM endpoints.",requestable:!1,permissionTypes:["DataRead"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},z={id:"ion:iam:users:write",name:"Manage Identities (SCIM Users)",description:"Authorizes a workload to create, replace, modify (including attribute changes), and delete Users via SCIM, including access-root revocation on user delete.",requestable:!1,permissionTypes:["DataCreate","DataWrite","DataDelete"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},M={id:"ion:iam:groups:write",name:"Manage Groups & Access (SCIM Groups)",description:"Authorizes a workload to create, replace, modify, and delete Groups via SCIM, including membership changes that grant or revoke entitlements.",requestable:!1,permissionTypes:["DataCreate","DataWrite","DataDelete"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},K={id:"ion:capabilitiez:read",name:"Read Capability Manifest",description:"Authorizes a workload to read the capability manifest at the capabilitiez endpoint (only when RemoteConfig.capabilitiez is enabled).",requestable:!1,permissionTypes:["DataRead"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},C={id:"ion:ciam:magic-link:create",name:"Issue CIAM Magic Links",description:"Authorizes a caller to mint customer magic-link login credentials via the magic-link endpoint. Grant narrowly.",requestable:!1,permissionTypes:["DataCreate"],assignableSubjectTypes:["workload","user"],recommendedSubjectTypes:Z},W={id:"ion:authz:oaa:sync",name:"Trigger OAA Full Sync",description:"Authorizes a workload (Ops/ECI client) to trigger a full OAA reconcile via the authz OAA sync endpoint (only when RemoteConfig.authz.oaa.fullSync.enabled is true).",requestable:!1,permissionTypes:["DataWrite"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},P={id:"ion:tenant:manage",name:"Manage Tenants",description:"Authorizes a workload (ECI/TMS client) to create, read, update, and delete tenant records via the tenant-management endpoints.",requestable:!1,permissionTypes:["DataCreate","DataRead","DataWrite","DataDelete"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},T=[Y,z,M,K,C,W,P],b={"iam.read":{permission:Y,subjectType:["workload"]},"iam.users.write":{permission:z,subjectType:["workload"]},"iam.groups.write":{permission:M,subjectType:["workload"]},"capabilitiez.read":{permission:K,subjectType:["workload"]},"ciam.magic-link.create":{permission:C,subjectType:["workload","user"]},"authz.oaa.sync":{permission:W,subjectType:["workload"]},"tenant.manage":{permission:P,subjectType:["workload"]}};var L=["sessionStore","userStore","customerStore","accessStore","tokenStore","magicLinkStore"];function D($){if($===null||typeof $!=="object")return $;let J={};for(let[Q,X]of Object.entries($)){if(L.includes(Q)||Q==="validators"||Q==="setStores")continue;J[Q]=X!==null&&typeof X==="object"&&!Array.isArray(X)&&Object.getPrototypeOf(X)===Object.prototype?D(X):X}return J}function I($){return D($)}var k={trace:()=>{},debug:()=>{},info:()=>{},warn:()=>{},error:()=>{}},N=k,y={trace:()=>{},debug:console.debug,info:console.info,warn:console.warn,error:console.error},A={trace:()=>{},debug:()=>{},info:console.info,warn:console.warn,error:console.error},_={trace:()=>{},debug:()=>{},info:()=>{},warn:console.warn,error:console.error};function f($,J){if(typeof J!=="number"||J<=0)return $;return new Promise((Q,X)=>{let B=setTimeout(()=>{X(Error(`Authz catalog entry did not become ready within ${J}ms`))},J);$.then(()=>{clearTimeout(B),Q()},(x)=>{clearTimeout(B),X(x)})})}function O($,J){let Q=!1,X,B=J.then(()=>{Q=!0},(F)=>{Q=!1,X=F}),x=$;return Object.defineProperty(x,"ready",{enumerable:!1,configurable:!0,value:(F)=>f(B.then(()=>{if(!Q)throw X}),F)}),Object.defineProperty(x,"isReady",{enumerable:!1,configurable:!0,value:()=>Q}),x}var h={beforeTenantSegments:["ui"]},p={beforeTenantSegments:["api"]};function E($){return($??[]).map((J)=>J.trim()).filter(Boolean)}function g($){let J=$.trim();if(!J)return"/";let Q=J.replace(/\\/g,"/").replace(/\/+/g,"/");return Q.startsWith("/")?Q:`/${Q}`}function v($){return g($).split("/").filter(Boolean)}function U($){return{beforeTenantSegments:E($?.beforeTenantSegments),afterTenantSegments:E($?.afterTenantSegments)}}function d($){return{type:"path",ui:U($?.ui),api:U($?.api)}}function c($,J){let Q=U(J),X=Q.beforeTenantSegments??[],B=Q.afterTenantSegments??[],x=v($),F=X.length+1+B.length;if(x.length<F)return null;for(let H=0;H<X.length;H++)if(x[H]!==X[H])return null;let q=X.length,V=x[q];if(!V)return null;for(let H=0;H<B.length;H++)if(x[q+1+H]!==B[H])return null;let G=x.slice(q+1+B.length);return{id:decodeURIComponent(V),restSegments:G,restPath:G.length>0?`/${G.join("/")}`:"/"}}function m($,J="/",Q){let X=U(Q),B=X.beforeTenantSegments??[],x=X.afterTenantSegments??[],F=v(J),q=[...B,encodeURIComponent($),...x,...F];return q.length>0?`/${q.join("/")}`:"/"}function u($){return{"~standard":{version:1,vendor:$,validate:(J)=>{if(typeof J!=="object"||J===null)return{issues:[{message:"Expected an object"}]};let Q=J,X=[],B={...Q},x=["iss","sub"];for(let V of x)if(V in Q){if(typeof Q[V]!=="string")X.push({message:`${V} must be a string`,path:[V]})}else X.push({message:`${V} is required`,path:[V]});if("aud"in Q&&Q.aud!==void 0){let V=Q.aud;if(typeof V!=="string"&&!Array.isArray(V))X.push({message:"aud must be a string or array of strings",path:["aud"]});else if(Array.isArray(V)&&!V.every((G)=>typeof G==="string"))X.push({message:"aud array must contain only strings",path:["aud"]})}let F=["jti","scope"];for(let V of F)if(V in Q&&Q[V]!==void 0){if(typeof Q[V]!=="string")X.push({message:`${V} must be a string`,path:[V]})}let q=["exp","iat"];for(let V of q)if(V in Q){if(typeof Q[V]!=="number")X.push({message:`${V} must be a number`,path:[V]})}else X.push({message:`${V} is required`,path:[V]});if(X.length>0)return{issues:X};return{value:B}}}}}function l($){return{"~standard":{version:1,vendor:$,validate:(J)=>{if(typeof J!=="object"||J===null)return{issues:[{message:"Expected an object"}]};let Q=J,X=[],B={};if("access_token"in Q)if(typeof Q.access_token==="string")B.access_token=Q.access_token;else X.push({message:"access_token must be a string",path:["access_token"]});else X.push({message:"access_token is required",path:["access_token"]});if("token_type"in Q)if(typeof Q.token_type==="string")B.token_type=Q.token_type;else X.push({message:"token_type must be a string",path:["token_type"]});else X.push({message:"token_type is required",path:["token_type"]});if("scope"in Q)if(typeof Q.scope==="string"||Q.scope===void 0)B.scope=Q.scope;else X.push({message:"scope must be a string",path:["scope"]});if("refresh_token"in Q)if(typeof Q.refresh_token==="string"||Q.refresh_token===void 0)B.refresh_token=Q.refresh_token;else X.push({message:"refresh_token must be a string",path:["refresh_token"]});if("expires"in Q)if(typeof Q.expires==="string"||Q.expires===void 0)B.expires=Q.expires;else X.push({message:"expires must be a string",path:["expires"]});if("expires_in"in Q)if(typeof Q.expires_in==="number"||Q.expires_in===void 0)B.expires_in=Q.expires_in;else X.push({message:"expires_in must be a number",path:["expires_in"]});if(X.length>0)return{issues:X};return{value:B}}}}}function n($){let J=new Uint8Array($);return crypto.getRandomValues(J),J}function a($){let J="",Q=n($);for(let X=0;X<$;X++){let B=Q[X]%32;J+="0123456789ABCDEFGHJKMNPQRSTVWXYZ".charAt(B)}return J}function o($,J){let Q="";for(let X=J;X>0;X--){let B=$%32;Q="0123456789ABCDEFGHJKMNPQRSTVWXYZ".charAt(B)+Q,$=Math.floor($/32)}return Q}function i($){let J=Date.now(),Q=o(J,10),X=a(16);return`${$??""}${Q}${X}`}export{l as workloadTokenResponseSchema,z0 as withValidate,_ as warnLogger,v0 as waitOn,S as version,K0 as validationFailureResponse,_0 as userSchema,B0 as unionCatalogRead,r as trustedClientPermissionsForPrincipal,D0 as trimTrailingSlash,j0 as tokenResponseSchema,J0 as toCodeCatalog,W0 as stripJsonComments,E0 as stableConfigHash,k as silentLogger,I as serializeConfig,O as readyCatalogEntry,P0 as parseJsonc,q0 as parseEcid,U0 as oidcCallbackSchema,d as normalizeTenantRoutingStrategy,U as normalizeTenantPathNamespace,M0 as must,C0 as mergeConfig,c as matchTenantPath,e as listGenerator,s as list,u as jwtAssertionClaimsSchema,T0 as isStoreConflictError,F0 as isEcid,R as isConfigSourceError,L0 as isConfigLocator,$0 as isCodeCatalog,A as infoLogger,Y0 as idTokenClaimsSchema,f0 as groupResourceSchema,i as generateULID,H0 as formatEcid,V0 as defineCatalog,N as defaultLogger,k0 as deepEqualPlain,S0 as decodeUser,y as debugLogger,t as configTrustedClientGrants,w0 as claimsToUser,m as buildTenantPath,y0 as assertValidSubjectTypeScoping,G0 as assertEcid,X0 as accessRootId,Q0 as accessRefId,R0 as StoreConflictError,N0 as PLATFORM_ASSIGNABLE_SUBJECT_TYPES,b0 as IoniteError,P as ION_TENANT_MANAGE,T as ION_SDK_PERMISSIONS,A0 as ION_SCIM_USER_EXTENSION_URN,z as ION_IAM_USERS_WRITE,Y as ION_IAM_READ,M as ION_IAM_GROUPS_WRITE,b as ION_ENDPOINT_PERMISSIONS,C as ION_CIAM_MAGIC_LINK_CREATE,K as ION_CAPABILITIEZ_READ,W as ION_AUTHZ_OAA_SYNC,I0 as ION_AUTHZ_GROUP_SCHEMA,Z0 as EcidFormatError,x0 as ECID_SCHEME,h as DEFAULT_TENANT_UI_NAMESPACE,p as DEFAULT_TENANT_API_NAMESPACE,j as ConfigSourceError};
|
|
1
|
+
import{A as K0,B as C0,C as W0,D as P0,E as D0,F as k0,G as E0,H as v0,I as w0,J as S0,K as R0,L as T0,M as b0,N as L0,Q as I0,R as N0,S as y0,T as A0,U as _0,V as f0,a as r,b as t,c as s,d as e,e as Q0,f as X0,l as $0,m as J0,n as V0,o as B0,p as x0,q as Z0,r as F0,s as H0,t as q0,u as G0,v as U0,w as j0,x as Y0,y as z0,z as M0}from"./shared/core-02035cvg.js";var S="0.0.23-beta.20260729.1";class j extends Error{kind;recoverable;code;status;path;sourceType;constructor($,J){super($,J.cause!==void 0?{cause:J.cause}:void 0);this.name="ConfigSourceError",this.kind=J.kind,this.recoverable=J.recoverable,this.code=J.code,this.status=J.status,this.path=J.path,this.sourceType=J.sourceType,Object.setPrototypeOf(this,j.prototype)}}function R($){return $ instanceof j}var Z=["workload"],Y={id:"ion:iam:read",name:"Read Identities (SCIM)",description:"Authorizes a workload to list and read Users and Groups via the SCIM endpoints.",requestable:!1,permissionTypes:["DataRead"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},z={id:"ion:iam:users:write",name:"Manage Identities (SCIM Users)",description:"Authorizes a workload to create, replace, modify (including attribute changes), and delete Users via SCIM, including access-root revocation on user delete.",requestable:!1,permissionTypes:["DataCreate","DataWrite","DataDelete"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},M={id:"ion:iam:groups:write",name:"Manage Groups & Access (SCIM Groups)",description:"Authorizes a workload to create, replace, modify, and delete Groups via SCIM, including membership changes that grant or revoke entitlements.",requestable:!1,permissionTypes:["DataCreate","DataWrite","DataDelete"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},K={id:"ion:capabilitiez:read",name:"Read Capability Manifest",description:"Authorizes a workload to read the capability manifest at the capabilitiez endpoint (only when RemoteConfig.capabilitiez is enabled).",requestable:!1,permissionTypes:["DataRead"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},C={id:"ion:ciam:magic-link:create",name:"Issue CIAM Magic Links",description:"Authorizes a caller to mint customer magic-link login credentials via the magic-link endpoint. Grant narrowly.",requestable:!1,permissionTypes:["DataCreate"],assignableSubjectTypes:["workload","user"],recommendedSubjectTypes:Z},W={id:"ion:authz:oaa:sync",name:"Trigger OAA Full Sync",description:"Authorizes a workload (Ops/ECI client) to trigger a full OAA reconcile via the authz OAA sync endpoint (only when RemoteConfig.authz.oaa.fullSync.enabled is true).",requestable:!1,permissionTypes:["DataWrite"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},P={id:"ion:tenant:manage",name:"Manage Tenants",description:"Authorizes a workload (ECI/TMS client) to create, read, update, and delete tenant records via the tenant-management endpoints.",requestable:!1,permissionTypes:["DataCreate","DataRead","DataWrite","DataDelete"],assignableSubjectTypes:Z,recommendedSubjectTypes:Z},T=[Y,z,M,K,C,W,P],b={"iam.read":{permission:Y,subjectType:["workload"]},"iam.users.write":{permission:z,subjectType:["workload"]},"iam.groups.write":{permission:M,subjectType:["workload"]},"capabilitiez.read":{permission:K,subjectType:["workload"]},"ciam.magic-link.create":{permission:C,subjectType:["workload","user"]},"authz.oaa.sync":{permission:W,subjectType:["workload"]},"tenant.manage":{permission:P,subjectType:["workload"]}};var L=["sessionStore","userStore","customerStore","accessStore","tokenStore","magicLinkStore"];function D($){if($===null||typeof $!=="object")return $;let J={};for(let[Q,X]of Object.entries($)){if(L.includes(Q)||Q==="validators"||Q==="setStores")continue;J[Q]=X!==null&&typeof X==="object"&&!Array.isArray(X)&&Object.getPrototypeOf(X)===Object.prototype?D(X):X}return J}function I($){return D($)}var k={trace:()=>{},debug:()=>{},info:()=>{},warn:()=>{},error:()=>{}},N=k,y={trace:()=>{},debug:console.debug,info:console.info,warn:console.warn,error:console.error},A={trace:()=>{},debug:()=>{},info:console.info,warn:console.warn,error:console.error},_={trace:()=>{},debug:()=>{},info:()=>{},warn:console.warn,error:console.error};function f($,J){if(typeof J!=="number"||J<=0)return $;return new Promise((Q,X)=>{let B=setTimeout(()=>{X(Error(`Authz catalog entry did not become ready within ${J}ms`))},J);$.then(()=>{clearTimeout(B),Q()},(x)=>{clearTimeout(B),X(x)})})}function O($,J){let Q=!1,X,B=J.then(()=>{Q=!0},(F)=>{Q=!1,X=F}),x=$;return Object.defineProperty(x,"ready",{enumerable:!1,configurable:!0,value:(F)=>f(B.then(()=>{if(!Q)throw X}),F)}),Object.defineProperty(x,"isReady",{enumerable:!1,configurable:!0,value:()=>Q}),x}var h={beforeTenantSegments:["ui"]},p={beforeTenantSegments:["api"]};function E($){return($??[]).map((J)=>J.trim()).filter(Boolean)}function g($){let J=$.trim();if(!J)return"/";let Q=J.replace(/\\/g,"/").replace(/\/+/g,"/");return Q.startsWith("/")?Q:`/${Q}`}function v($){return g($).split("/").filter(Boolean)}function U($){return{beforeTenantSegments:E($?.beforeTenantSegments),afterTenantSegments:E($?.afterTenantSegments)}}function d($){return{type:"path",ui:U($?.ui),api:U($?.api)}}function c($,J){let Q=U(J),X=Q.beforeTenantSegments??[],B=Q.afterTenantSegments??[],x=v($),F=X.length+1+B.length;if(x.length<F)return null;for(let H=0;H<X.length;H++)if(x[H]!==X[H])return null;let q=X.length,V=x[q];if(!V)return null;for(let H=0;H<B.length;H++)if(x[q+1+H]!==B[H])return null;let G=x.slice(q+1+B.length);return{id:decodeURIComponent(V),restSegments:G,restPath:G.length>0?`/${G.join("/")}`:"/"}}function m($,J="/",Q){let X=U(Q),B=X.beforeTenantSegments??[],x=X.afterTenantSegments??[],F=v(J),q=[...B,encodeURIComponent($),...x,...F];return q.length>0?`/${q.join("/")}`:"/"}function u($){return{"~standard":{version:1,vendor:$,validate:(J)=>{if(typeof J!=="object"||J===null)return{issues:[{message:"Expected an object"}]};let Q=J,X=[],B={...Q},x=["iss","sub"];for(let V of x)if(V in Q){if(typeof Q[V]!=="string")X.push({message:`${V} must be a string`,path:[V]})}else X.push({message:`${V} is required`,path:[V]});if("aud"in Q&&Q.aud!==void 0){let V=Q.aud;if(typeof V!=="string"&&!Array.isArray(V))X.push({message:"aud must be a string or array of strings",path:["aud"]});else if(Array.isArray(V)&&!V.every((G)=>typeof G==="string"))X.push({message:"aud array must contain only strings",path:["aud"]})}let F=["jti","scope"];for(let V of F)if(V in Q&&Q[V]!==void 0){if(typeof Q[V]!=="string")X.push({message:`${V} must be a string`,path:[V]})}let q=["exp","iat"];for(let V of q)if(V in Q){if(typeof Q[V]!=="number")X.push({message:`${V} must be a number`,path:[V]})}else X.push({message:`${V} is required`,path:[V]});if(X.length>0)return{issues:X};return{value:B}}}}}function l($){return{"~standard":{version:1,vendor:$,validate:(J)=>{if(typeof J!=="object"||J===null)return{issues:[{message:"Expected an object"}]};let Q=J,X=[],B={};if("access_token"in Q)if(typeof Q.access_token==="string")B.access_token=Q.access_token;else X.push({message:"access_token must be a string",path:["access_token"]});else X.push({message:"access_token is required",path:["access_token"]});if("token_type"in Q)if(typeof Q.token_type==="string")B.token_type=Q.token_type;else X.push({message:"token_type must be a string",path:["token_type"]});else X.push({message:"token_type is required",path:["token_type"]});if("scope"in Q)if(typeof Q.scope==="string"||Q.scope===void 0)B.scope=Q.scope;else X.push({message:"scope must be a string",path:["scope"]});if("refresh_token"in Q)if(typeof Q.refresh_token==="string"||Q.refresh_token===void 0)B.refresh_token=Q.refresh_token;else X.push({message:"refresh_token must be a string",path:["refresh_token"]});if("expires"in Q)if(typeof Q.expires==="string"||Q.expires===void 0)B.expires=Q.expires;else X.push({message:"expires must be a string",path:["expires"]});if("expires_in"in Q)if(typeof Q.expires_in==="number"||Q.expires_in===void 0)B.expires_in=Q.expires_in;else X.push({message:"expires_in must be a number",path:["expires_in"]});if(X.length>0)return{issues:X};return{value:B}}}}}function n($){let J=new Uint8Array($);return crypto.getRandomValues(J),J}function a($){let J="",Q=n($);for(let X=0;X<$;X++){let B=Q[X]%32;J+="0123456789ABCDEFGHJKMNPQRSTVWXYZ".charAt(B)}return J}function o($,J){let Q="";for(let X=J;X>0;X--){let B=$%32;Q="0123456789ABCDEFGHJKMNPQRSTVWXYZ".charAt(B)+Q,$=Math.floor($/32)}return Q}function i($){let J=Date.now(),Q=o(J,10),X=a(16);return`${$??""}${Q}${X}`}export{l as workloadTokenResponseSchema,z0 as withValidate,_ as warnLogger,v0 as waitOn,S as version,K0 as validationFailureResponse,_0 as userSchema,B0 as unionCatalogRead,r as trustedClientPermissionsForPrincipal,D0 as trimTrailingSlash,j0 as tokenResponseSchema,J0 as toCodeCatalog,W0 as stripJsonComments,E0 as stableConfigHash,k as silentLogger,I as serializeConfig,O as readyCatalogEntry,P0 as parseJsonc,q0 as parseEcid,U0 as oidcCallbackSchema,d as normalizeTenantRoutingStrategy,U as normalizeTenantPathNamespace,M0 as must,C0 as mergeConfig,c as matchTenantPath,e as listGenerator,s as list,u as jwtAssertionClaimsSchema,T0 as isStoreConflictError,F0 as isEcid,R as isConfigSourceError,L0 as isConfigLocator,$0 as isCodeCatalog,A as infoLogger,Y0 as idTokenClaimsSchema,f0 as groupResourceSchema,i as generateULID,H0 as formatEcid,V0 as defineCatalog,N as defaultLogger,k0 as deepEqualPlain,S0 as decodeUser,y as debugLogger,t as configTrustedClientGrants,w0 as claimsToUser,m as buildTenantPath,y0 as assertValidSubjectTypeScoping,G0 as assertEcid,X0 as accessRootId,Q0 as accessRefId,R0 as StoreConflictError,N0 as PLATFORM_ASSIGNABLE_SUBJECT_TYPES,b0 as IoniteError,P as ION_TENANT_MANAGE,T as ION_SDK_PERMISSIONS,A0 as ION_SCIM_USER_EXTENSION_URN,z as ION_IAM_USERS_WRITE,Y as ION_IAM_READ,M as ION_IAM_GROUPS_WRITE,b as ION_ENDPOINT_PERMISSIONS,C as ION_CIAM_MAGIC_LINK_CREATE,K as ION_CAPABILITIEZ_READ,W as ION_AUTHZ_OAA_SYNC,I0 as ION_AUTHZ_GROUP_SCHEMA,Z0 as EcidFormatError,x0 as ECID_SCHEME,h as DEFAULT_TENANT_UI_NAMESPACE,p as DEFAULT_TENANT_API_NAMESPACE,j as ConfigSourceError};
|
package/dist/server.d.ts
CHANGED
|
@@ -1071,7 +1071,7 @@ type ModuleReadinessState = {
|
|
|
1071
1071
|
* Holistic, read-only readiness snapshot for an ionite instance. Returned by
|
|
1072
1072
|
* `ion.readiness()` and used by the built-in `${basePath}/readyz` endpoint. This is composition
|
|
1073
1073
|
* DATA, not a request gate: applications combine it (via `ion.requireReady([...])`) with their own
|
|
1074
|
-
* non-
|
|
1074
|
+
* non-ionite dependency checks to build their health endpoints.
|
|
1075
1075
|
*/
|
|
1076
1076
|
type ReadinessReport = {
|
|
1077
1077
|
/** True when config has been applied (`applied`) and every ACTIVE module is ready. */
|
|
@@ -1550,7 +1550,7 @@ type TrustedIdp = {
|
|
|
1550
1550
|
* Workload config with separate incoming (server) and outgoing (client) roles.
|
|
1551
1551
|
* - **incoming**: Server-only config for validating tokens presented to this app. Either a single
|
|
1552
1552
|
* `{ jwksUri, issuer }` config, or a list of {@link TrustedIdp} entries for multi-IdP trust.
|
|
1553
|
-
* - **outgoing**: Map of named clients for outbound calls; use getWorkloadToken(client, ion, scope?) from server (client is required and must be one of the outgoing names; pass the
|
|
1553
|
+
* - **outgoing**: Map of named clients for outbound calls; use getWorkloadToken(client, ion, scope?) from server (client is required and must be one of the outgoing names; pass the Ionite instance).
|
|
1554
1554
|
*/
|
|
1555
1555
|
type WorkloadIncomingOutgoing = {
|
|
1556
1556
|
incoming?: Partial<WorkloadConfig> | TrustedIdp[];
|
|
@@ -3075,7 +3075,7 @@ type AzureSecretsConfig = {
|
|
|
3075
3075
|
* - `path`: the tenant-specific secret path within that source.
|
|
3076
3076
|
* - `ttl` (optional): poll interval (ms) for the tenant config subscription.
|
|
3077
3077
|
*
|
|
3078
|
-
* This keeps credentials/connection wiring on the root
|
|
3078
|
+
* This keeps credentials/connection wiring on the root Ionite (ConfigSource-owned) and out of the tenant
|
|
3079
3079
|
* store, and forces apps to declare their secrets sources up front rather than spinning them up
|
|
3080
3080
|
* ad-hoc per tenant.
|
|
3081
3081
|
*/
|
|
@@ -3109,7 +3109,7 @@ type AuthzOaaConfig = {
|
|
|
3109
3109
|
};
|
|
3110
3110
|
};
|
|
3111
3111
|
/**
|
|
3112
|
-
* A config-declared workload client that is pre-authorized to hold specific `
|
|
3112
|
+
* A config-declared workload client that is pre-authorized to hold specific `ion:*` (or app) permissions
|
|
3113
3113
|
* WITHOUT a stored grant in the AccessAssignmentStore. This is a read-path overlay used for bootstrap
|
|
3114
3114
|
* and provisioning identities (e.g. the deployer, tenant provisioning, SCIM aggregators) so the SDK
|
|
3115
3115
|
* never has to write seed grants to a remote store at initialization (see
|
|
@@ -3560,7 +3560,7 @@ type CIAM<
|
|
|
3560
3560
|
ready?: (timeout?: number) => Promise<void>;
|
|
3561
3561
|
};
|
|
3562
3562
|
/**
|
|
3563
|
-
* CIAM config that code may provide; excludes vault-only secrets (`providers`) and
|
|
3563
|
+
* CIAM config that code may provide; excludes vault-only secrets (`providers`) and ionite-derived
|
|
3564
3564
|
* endpoint URLs (`customerLoginUrl`, `customerCallbackUrl`, `customerProvidersUrl`).
|
|
3565
3565
|
*/
|
|
3566
3566
|
type CIAMConfigFromCode<
|
|
@@ -3631,7 +3631,7 @@ type IoniteBase = {
|
|
|
3631
3631
|
/**
|
|
3632
3632
|
* Holistic, read-only readiness snapshot: per-module readiness plus config-application status.
|
|
3633
3633
|
* Composition data for building health endpoints; does not gate the request path. Combine with
|
|
3634
|
-
* `requireReady([...])` and your own non-
|
|
3634
|
+
* `requireReady([...])` and your own non-ionite service checks in your `/readyz` handler.
|
|
3635
3635
|
*/
|
|
3636
3636
|
readiness(): ReadinessReport;
|
|
3637
3637
|
/**
|
|
@@ -3682,8 +3682,8 @@ type BaseTenant = {
|
|
|
3682
3682
|
updatedAt: Date;
|
|
3683
3683
|
/**
|
|
3684
3684
|
* Serializable pointer used to materialize this tenant's ConfigSource. Resolves against the root
|
|
3685
|
-
*
|
|
3686
|
-
* Required: every tenant has config, so `
|
|
3685
|
+
* ionite secrets sources ({@link TenantConfigLocator}); carries no connection details or credentials.
|
|
3686
|
+
* Required: every tenant has config, so `createIon`/`tenantConfigSource` can rely on it without a
|
|
3687
3687
|
* runtime presence guard.
|
|
3688
3688
|
*/
|
|
3689
3689
|
configLocator: TenantConfigLocator;
|
|
@@ -3702,7 +3702,7 @@ type BaseTenant = {
|
|
|
3702
3702
|
* const ionCache = new LRUCache<string, Ionite>({
|
|
3703
3703
|
* max: 100,
|
|
3704
3704
|
* ttl: 1000 * 60 * 60,
|
|
3705
|
-
* dispose: (
|
|
3705
|
+
* dispose: (ion) => ion.close(), // full lifecycle: evicted/invalidated runtimes are closed
|
|
3706
3706
|
* fetchMethod: async (id) => {
|
|
3707
3707
|
* const tenant = await tenants.get(id); // `tenants` assigned below; resolved at call time
|
|
3708
3708
|
* return tenant ? createTenantIon(tenant) : undefined;
|
|
@@ -3773,7 +3773,7 @@ type BaseUser<TExtended = object> = BaseUserFields & {
|
|
|
3773
3773
|
* Optional Enterprise Controlled ID: a system-of-record-owned identity correlator formatted as
|
|
3774
3774
|
* `ecid:<realm>:<opaque>` (realm = the minting authority's id). Correlates this account to a
|
|
3775
3775
|
* single identity across systems. Minted by the enterprise SOR (via an ECI), never by the app;
|
|
3776
|
-
* received on the SCIM
|
|
3776
|
+
* received on the SCIM ionite extension or the `ecid` JWT claim. Never an authorization subject.
|
|
3777
3777
|
* See https://ionite.com/docs/llms-ecid.txt.
|
|
3778
3778
|
*/
|
|
3779
3779
|
ecid?: string;
|