@ionite/core 0.0.23 → 0.0.24-beta.20260907.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +555 -314
- package/dist/index.js +1 -1
- package/dist/server.d.ts +539 -331
- package/dist/server.js +1 -1
- package/dist/shared/core-ys2a23v0.js +4 -0
- package/package.json +1 -1
- package/dist/shared/core-fm0d5w83.js +0 -4
package/dist/server.d.ts
CHANGED
|
@@ -36,6 +36,12 @@ interface ListResult<T> {
|
|
|
36
36
|
interface ListFilter {
|
|
37
37
|
/** Restrict catalog entries to those whose `requestable` flag equals this value. */
|
|
38
38
|
requestable?: boolean;
|
|
39
|
+
/** Exact match on the principal's login/userName (or workload `clientId` projected as userName). */
|
|
40
|
+
userName?: string;
|
|
41
|
+
/** Exact match on the store `externalId`. */
|
|
42
|
+
externalId?: string;
|
|
43
|
+
/** Exclusive lower bound on `updatedAt` (SCIM `meta.lastModified gt`; ISO string or Date). */
|
|
44
|
+
updatedAfter?: Date | string;
|
|
39
45
|
}
|
|
40
46
|
/** Shared options for paginated list operations. */
|
|
41
47
|
interface ListOptions {
|
|
@@ -507,85 +513,6 @@ interface Logger {
|
|
|
507
513
|
}
|
|
508
514
|
import { StandardSchemaV1 as StandardSchemaV15 } from "@standard-schema/spec";
|
|
509
515
|
/**
|
|
510
|
-
* IAM delta egress mode (RemoteConfig/ECI intent). Selects how IAM-visible runtime changes that
|
|
511
|
-
* occur inside the application are surfaced to the enterprise's IAM/governance layer:
|
|
512
|
-
*
|
|
513
|
-
* - `'patch'`: outbound SCIM into the IAM tool (per-resource POST/PUT/PATCH/DELETE,
|
|
514
|
-
* correlated by the App-owned id carried as SCIM `externalId`). The IAM tool's view stays fresh as users, materialized entitlement
|
|
515
|
-
* definitions, and access change in the app. See the README "IAM delta egress" section.
|
|
516
|
-
*
|
|
517
|
-
* Origin/trust: every push is authenticated with the app's outgoing workload client (OAuth bearer);
|
|
518
|
-
* the receiver treats the authenticated workload identity as the verified origin. Audit
|
|
519
|
-
* accountability lives with the IdP that authenticated the workload and the IAM tool that granted
|
|
520
|
-
* it access. The SDK only surfaces the signal; it never dictates the enterprise's workflow or
|
|
521
|
-
* policy (flag, auto-revoke + notify, or simply audit).
|
|
522
|
-
*/
|
|
523
|
-
type IamDeltaMode = "patch";
|
|
524
|
-
/** SCIM resource types the delta patch adapter addresses. */
|
|
525
|
-
type IamDeltaResourceType = "user" | "group";
|
|
526
|
-
/** Destination-owned reference captured from a SCIM User/Group response. */
|
|
527
|
-
type DestinationReference = {
|
|
528
|
-
/** Service-provider-assigned SCIM resource id. */
|
|
529
|
-
providerId: string;
|
|
530
|
-
/** IAM-owned deep link where access to an entitlement can be requested, when supplied. */
|
|
531
|
-
requestUrl?: string;
|
|
532
|
-
};
|
|
533
|
-
/**
|
|
534
|
-
* Full IAM delta snapshot supplied by the app's maintenance/reconcile path. It mirrors the entities
|
|
535
|
-
* visible through IAM aggregation: users, durable entitlement definitions, and active access roots.
|
|
536
|
-
*/
|
|
537
|
-
type IamDeltaReconcileInput = {
|
|
538
|
-
users?: Iterable<BaseUser> | AsyncIterable<BaseUser>;
|
|
539
|
-
groups?: Iterable<Group> | AsyncIterable<Group>;
|
|
540
|
-
roles?: Iterable<Role> | AsyncIterable<Role>;
|
|
541
|
-
permissions?: Iterable<Permission> | AsyncIterable<Permission>;
|
|
542
|
-
access?: Iterable<AccessChange> | AsyncIterable<AccessChange>;
|
|
543
|
-
};
|
|
544
|
-
/** Result of an app-driven full reconcile (re-push of definitions, users, and active roots). */
|
|
545
|
-
type IamDeltaReconcileResult = {
|
|
546
|
-
pushed: number;
|
|
547
|
-
skipped: number;
|
|
548
|
-
errors: string[];
|
|
549
|
-
};
|
|
550
|
-
/**
|
|
551
|
-
* Projects observed runtime mutations to the configured IAM delta destination. The invariant is:
|
|
552
|
-
* every runtime mutation the SDK observes that would change what IAM full sync shows must also
|
|
553
|
-
* egress through this handle. That includes users, materialized entitlement definitions, and access
|
|
554
|
-
* roots. Code templates are not pushed during config apply.
|
|
555
|
-
*
|
|
556
|
-
* Request-triggered methods resolve when projection completes (or immediately when not ready). They
|
|
557
|
-
* are best-effort egress: the SCIM mutation path awaits them inside the request, but a rejection is
|
|
558
|
-
* caught and reported as degraded egress — it never turns a committed store mutation into a SCIM
|
|
559
|
-
* error. Reactive catalog/resource events use the same methods outside a request and warn on failure.
|
|
560
|
-
*
|
|
561
|
-
* Readiness follows the shared contract: `isReady()` is a synchronous check; `ready(timeout?)`
|
|
562
|
-
* resolves once the emitter first becomes usable.
|
|
563
|
-
*/
|
|
564
|
-
interface IamDeltaEmitter {
|
|
565
|
-
/** Upsert a full SCIM User representation at the destination. */
|
|
566
|
-
onUserUpsert(user: BaseUser): Promise<void>;
|
|
567
|
-
/** Delete a destination User identified strictly by externalId. */
|
|
568
|
-
onUserDelete(externalId: string): Promise<void>;
|
|
569
|
-
/** Upsert a full SCIM Group representation for a group, role, or permission definition. */
|
|
570
|
-
onEntitlementUpsert(entity: Entitlement, type: EntitlementType): Promise<void>;
|
|
571
|
-
/** Delete a destination entitlement Group identified by the App-owned catalog id. */
|
|
572
|
-
onEntitlementDelete(type: EntitlementType, id: string): Promise<void>;
|
|
573
|
-
/** Project a granted root; resolves on completion (or immediately when not ready), rejects on push failure. */
|
|
574
|
-
onGrant(change: AccessChange): Promise<void>;
|
|
575
|
-
/** Project a revoked root; resolves on completion (or immediately when not ready), rejects on push failure. */
|
|
576
|
-
onRevoke(change: AccessChange): Promise<void>;
|
|
577
|
-
/** Re-push the complete IAM-visible snapshot to the destination (app-driven full reconcile). */
|
|
578
|
-
reconcile(input: IamDeltaReconcileInput): Promise<IamDeltaReconcileResult>;
|
|
579
|
-
/**
|
|
580
|
-
* Read a previously captured destination reference without making a network request. Returns
|
|
581
|
-
* undefined until the resource has been resolved or pushed to the configured IAM destination.
|
|
582
|
-
* `correlationId` is a User's `externalId` or an entitlement's App-owned catalog `id`.
|
|
583
|
-
*/
|
|
584
|
-
getDestinationRef(resourceType: IamDeltaResourceType, correlationId: string): Promise<DestinationReference | undefined>;
|
|
585
|
-
isReady(): boolean;
|
|
586
|
-
ready(timeout?: number): Promise<void>;
|
|
587
|
-
}
|
|
588
|
-
/**
|
|
589
516
|
* SCIM 2.0 User Resource
|
|
590
517
|
* @see https://datatracker.ietf.org/doc/html/rfc7643#section-4.1
|
|
591
518
|
*/
|
|
@@ -717,7 +644,7 @@ interface Address {
|
|
|
717
644
|
/**
|
|
718
645
|
* SCIM Group reference (used within User resources)
|
|
719
646
|
*/
|
|
720
|
-
interface
|
|
647
|
+
interface Group {
|
|
721
648
|
/**
|
|
722
649
|
* The identifier of the User's group
|
|
723
650
|
*/
|
|
@@ -753,10 +680,10 @@ interface GroupMember {
|
|
|
753
680
|
display?: string;
|
|
754
681
|
/**
|
|
755
682
|
* The type of the member. `"Workload"` labels a service-account/workload principal (including
|
|
756
|
-
* config-declared trusted provisioning clients)
|
|
757
|
-
* `"User"` or a nested `"Group"`.
|
|
683
|
+
* config-declared trusted provisioning clients) and `"Customer"` a CIAM customer so SCIM consumers
|
|
684
|
+
* can distinguish them from a workforce `"User"` or a nested `"Group"`.
|
|
758
685
|
*/
|
|
759
|
-
type?: "User" | "Group" | "Workload";
|
|
686
|
+
type?: "User" | "Group" | "Workload" | "Customer";
|
|
760
687
|
}
|
|
761
688
|
/**
|
|
762
689
|
* SCIM 2.0 Group Resource
|
|
@@ -794,10 +721,49 @@ interface GroupResource {
|
|
|
794
721
|
*/
|
|
795
722
|
members?: GroupMember[];
|
|
796
723
|
}
|
|
724
|
+
/** SCIM Workload resource — machine/service principal, not a User. */
|
|
725
|
+
interface ScimWorkload {
|
|
726
|
+
schemas?: string[];
|
|
727
|
+
id?: string;
|
|
728
|
+
externalId?: string;
|
|
729
|
+
/** Login identifier; typically the OAuth `clientId`. */
|
|
730
|
+
userName?: string;
|
|
731
|
+
displayName?: string;
|
|
732
|
+
description?: string;
|
|
733
|
+
active?: boolean;
|
|
734
|
+
providerId?: string;
|
|
735
|
+
requestUrl?: string;
|
|
736
|
+
meta?: {
|
|
737
|
+
resourceType?: string;
|
|
738
|
+
created?: string;
|
|
739
|
+
lastModified?: string;
|
|
740
|
+
location?: string;
|
|
741
|
+
version?: string;
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
/** SCIM Customer resource — CIAM consumer principal, not a workforce User. */
|
|
745
|
+
interface ScimCustomer {
|
|
746
|
+
schemas?: string[];
|
|
747
|
+
id?: string;
|
|
748
|
+
externalId?: string;
|
|
749
|
+
userName?: string;
|
|
750
|
+
displayName?: string;
|
|
751
|
+
active?: boolean;
|
|
752
|
+
emails?: Email[];
|
|
753
|
+
providerId?: string;
|
|
754
|
+
requestUrl?: string;
|
|
755
|
+
meta?: {
|
|
756
|
+
resourceType?: string;
|
|
757
|
+
created?: string;
|
|
758
|
+
lastModified?: string;
|
|
759
|
+
location?: string;
|
|
760
|
+
version?: string;
|
|
761
|
+
};
|
|
762
|
+
}
|
|
797
763
|
/**
|
|
798
764
|
* SCIM Role
|
|
799
765
|
*/
|
|
800
|
-
interface
|
|
766
|
+
interface Role {
|
|
801
767
|
/**
|
|
802
768
|
* The value of the role
|
|
803
769
|
*/
|
|
@@ -993,7 +959,7 @@ interface User {
|
|
|
993
959
|
/**
|
|
994
960
|
* A list of groups to which the user belongs
|
|
995
961
|
*/
|
|
996
|
-
groups?:
|
|
962
|
+
groups?: Group[];
|
|
997
963
|
/**
|
|
998
964
|
* A list of entitlements for the User
|
|
999
965
|
*/
|
|
@@ -1006,7 +972,7 @@ interface User {
|
|
|
1006
972
|
/**
|
|
1007
973
|
* A list of roles for the User
|
|
1008
974
|
*/
|
|
1009
|
-
roles?:
|
|
975
|
+
roles?: Role[];
|
|
1010
976
|
/**
|
|
1011
977
|
* A list of certificates issued to the User
|
|
1012
978
|
*/
|
|
@@ -1016,13 +982,310 @@ interface User {
|
|
|
1016
982
|
*/
|
|
1017
983
|
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"?: EnterpriseExtension;
|
|
1018
984
|
/**
|
|
1019
|
-
* ionite User Extension (ECID + accountClass).
|
|
985
|
+
* ionite User Extension (ECID + accountClass).
|
|
986
|
+
*/
|
|
987
|
+
"urn:ionite:scim:schemas:extension:ion:2.0:User"?: IoniteUserExtension;
|
|
988
|
+
/**
|
|
989
|
+
* REQUIRED. The schemas attribute is an array of Strings which allows introspection of the supported schema version
|
|
990
|
+
*/
|
|
991
|
+
schemas?: string[];
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* Persisted CIAM customer record with identity fields and tracking metadata.
|
|
995
|
+
*
|
|
996
|
+
* Builds on the shared minimal identity fields with a lightweight set of
|
|
997
|
+
* consumer-oriented attributes and an optional CIAM (`ciam`) session envelope.
|
|
998
|
+
* This is the type returned by `CustomerStore`. Apps typically extend the
|
|
999
|
+
* `BaseCustomer` Zod/Valibot schema to add custom attributes.
|
|
1000
|
+
*
|
|
1001
|
+
* @template TExtended - Type-safe custom data that consumers can add to customers
|
|
1002
|
+
*/
|
|
1003
|
+
type BaseCustomer<TExtended = object> = BaseUserFields & {
|
|
1004
|
+
/**
|
|
1005
|
+
* Optional ionite tenant identifier for tenant-aware apps.
|
|
1006
|
+
*/
|
|
1007
|
+
tenantId?: string;
|
|
1008
|
+
/**
|
|
1009
|
+
* Optional external identifier from a provisioning client.
|
|
1010
|
+
*/
|
|
1011
|
+
externalId?: string;
|
|
1012
|
+
/**
|
|
1013
|
+
* Optional destination service-provider id captured after IAM materializes this customer.
|
|
1014
|
+
*/
|
|
1015
|
+
providerId?: string;
|
|
1016
|
+
/**
|
|
1017
|
+
* Optional IAM-owned deep link associated with this customer receipt.
|
|
1018
|
+
*/
|
|
1019
|
+
requestUrl?: string;
|
|
1020
|
+
/**
|
|
1021
|
+
* Optional display name distinct from the simple `name` field.
|
|
1022
|
+
*/
|
|
1023
|
+
displayName?: string;
|
|
1024
|
+
/**
|
|
1025
|
+
* Optional email collection.
|
|
1026
|
+
* The simple `email` field still stores the primary email for convenience.
|
|
1027
|
+
*/
|
|
1028
|
+
emails?: Email[];
|
|
1029
|
+
/**
|
|
1030
|
+
* Optional phone numbers.
|
|
1031
|
+
*/
|
|
1032
|
+
phoneNumbers?: PhoneNumber[];
|
|
1033
|
+
/**
|
|
1034
|
+
* Optional account state.
|
|
1035
|
+
*/
|
|
1036
|
+
active?: boolean;
|
|
1037
|
+
/**
|
|
1038
|
+
* Timestamp when the customer was first stored.
|
|
1039
|
+
*/
|
|
1040
|
+
createdAt?: Date;
|
|
1041
|
+
/**
|
|
1042
|
+
* Timestamp when the customer was last updated (e.g., on re-login).
|
|
1043
|
+
*/
|
|
1044
|
+
updatedAt?: Date;
|
|
1045
|
+
/**
|
|
1046
|
+
* Optional CIAM envelope for stores that persist customer session profile data.
|
|
1047
|
+
* Simple app stores MAY omit this field.
|
|
1048
|
+
*/
|
|
1049
|
+
ciam?: Customer["ciam"];
|
|
1050
|
+
} & TExtended;
|
|
1051
|
+
/**
|
|
1052
|
+
* Abstract interface for customer storage backends.
|
|
1053
|
+
*
|
|
1054
|
+
* Mirrors `UserStore` but for the CIAM customer domain. Consumers can
|
|
1055
|
+
* implement this for in-memory, Redis, or database-backed persistence.
|
|
1056
|
+
*
|
|
1057
|
+
* @template TExtended - Type-safe custom data that consumers can add to customers
|
|
1058
|
+
*/
|
|
1059
|
+
interface CustomerStore<TExtended = object> {
|
|
1060
|
+
/**
|
|
1061
|
+
* Retrieve a customer by their unique identifier.
|
|
1062
|
+
*
|
|
1063
|
+
* @param id - The customer's unique identifier as defined by the store implementation
|
|
1064
|
+
* @returns The customer if found, undefined otherwise
|
|
1065
|
+
*/
|
|
1066
|
+
get(id: string): Promise<BaseCustomer<TExtended> | undefined>;
|
|
1067
|
+
/**
|
|
1068
|
+
* Retrieve a customer based on their identity attributes or CIAM claims.
|
|
1069
|
+
*
|
|
1070
|
+
* @param customer - The customer to lookup
|
|
1071
|
+
* @returns The customer if found, undefined otherwise
|
|
1072
|
+
*/
|
|
1073
|
+
lookup(customer: BaseCustomer<TExtended>): Promise<BaseCustomer<TExtended> | undefined>;
|
|
1074
|
+
/**
|
|
1075
|
+
* Optional indexed lookup by `externalId`. When omitted, callers fall back to `lookup` or a list scan.
|
|
1076
|
+
*/
|
|
1077
|
+
getByExternalId?(externalId: string): Promise<BaseCustomer<TExtended> | undefined>;
|
|
1078
|
+
/**
|
|
1079
|
+
* Create or update a customer in the store.
|
|
1080
|
+
*
|
|
1081
|
+
* @param customer - The customer data to store
|
|
1082
|
+
*/
|
|
1083
|
+
upsert(customer: BaseCustomer<TExtended>): Promise<BaseCustomer<TExtended>>;
|
|
1084
|
+
/**
|
|
1085
|
+
* Delete a customer by their unique identifier.
|
|
1086
|
+
*
|
|
1087
|
+
* @param id - The customer's unique identifier as defined by the store implementation
|
|
1088
|
+
* @returns The number of customers deleted (0 or 1)
|
|
1089
|
+
*/
|
|
1090
|
+
delete(id: string): Promise<number>;
|
|
1091
|
+
/**
|
|
1092
|
+
* List customers in the store with optional pagination and sort.
|
|
1093
|
+
*
|
|
1094
|
+
* @param options - Optional start (0-based), limit (page size), and sort
|
|
1095
|
+
* @returns ListResult with total, count, items, size, page, pages
|
|
1096
|
+
*/
|
|
1097
|
+
list(options?: ListOptions): Promise<ListResult<BaseCustomer<TExtended>>>;
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Persisted workload principal record. Mirrors the registry/enrichment shape of `BaseUser`, scoped
|
|
1101
|
+
* to the small set of attributes meaningful for non-human identities.
|
|
1102
|
+
*
|
|
1103
|
+
* @template TExtended - Type-safe custom data that consumers can add to workload identities.
|
|
1104
|
+
*/
|
|
1105
|
+
type BaseWorkloadIdentity<TExtended = object> = {
|
|
1106
|
+
/**
|
|
1107
|
+
* Stable subject id for this workload. Used as the AccessIndex subject for
|
|
1108
|
+
* `subjectType: 'workload'` checks. Typically `clientId`, a workload id, or the token `sub`.
|
|
1109
|
+
*/
|
|
1110
|
+
id: string;
|
|
1111
|
+
/** OAuth client identifier, when the workload authenticates via client credentials. */
|
|
1112
|
+
clientId?: string;
|
|
1113
|
+
/** Human-friendly display name for the service account / machine identity. */
|
|
1114
|
+
displayName?: string;
|
|
1115
|
+
/** Free-form description of the workload's purpose. */
|
|
1116
|
+
description?: string;
|
|
1117
|
+
/** External identifier from the provisioning client (e.g. SCIM). */
|
|
1118
|
+
externalId?: string;
|
|
1119
|
+
/**
|
|
1120
|
+
* Optional destination service-provider id captured after IAM materializes this workload.
|
|
1121
|
+
*/
|
|
1122
|
+
providerId?: string;
|
|
1123
|
+
/**
|
|
1124
|
+
* Optional IAM-owned deep link associated with this workload receipt.
|
|
1125
|
+
*/
|
|
1126
|
+
requestUrl?: string;
|
|
1127
|
+
/**
|
|
1128
|
+
* Optional Enterprise Controlled ID for this workload: `ecid:<realm>:<opaque>`. A workload is its
|
|
1129
|
+
* own governance root, never folded into a human's ECID. See https://ionite.com/docs/llms-ecid.txt.
|
|
1130
|
+
*/
|
|
1131
|
+
ecid?: string;
|
|
1132
|
+
/** Whether the workload is active. Set `false` to disable it without deleting the record. */
|
|
1133
|
+
active?: boolean;
|
|
1134
|
+
/** Default OAuth scopes associated with this workload (space-delimited tokens, normalized list). */
|
|
1135
|
+
scopes?: string[];
|
|
1136
|
+
/** Timestamp when the workload identity was first stored. */
|
|
1137
|
+
createdAt?: Date;
|
|
1138
|
+
/** Timestamp when the workload identity was last updated. */
|
|
1139
|
+
updatedAt?: Date;
|
|
1140
|
+
/** Optional free-form metadata bag. */
|
|
1141
|
+
metadata?: Record<string, unknown>;
|
|
1142
|
+
} & TExtended;
|
|
1143
|
+
/**
|
|
1144
|
+
* Abstract interface for workload identity storage backends. Implement to back the registry with
|
|
1145
|
+
* in-memory, Redis, or a database. Mirrors {@link UserStore}.
|
|
1146
|
+
*
|
|
1147
|
+
* @template TExtended - Type-safe custom data that consumers can add to workload identities.
|
|
1148
|
+
*/
|
|
1149
|
+
interface WorkloadIdentityStore<TExtended = object> {
|
|
1150
|
+
/**
|
|
1151
|
+
* Retrieve a workload identity by its unique id.
|
|
1152
|
+
*
|
|
1153
|
+
* @param id - The workload's unique identifier.
|
|
1154
|
+
* @returns The workload identity if found, undefined otherwise.
|
|
1155
|
+
*/
|
|
1156
|
+
get(id: string): Promise<BaseWorkloadIdentity<TExtended> | undefined>;
|
|
1157
|
+
/**
|
|
1158
|
+
* Retrieve a workload identity by matching identifying attributes (e.g. `clientId`, `externalId`).
|
|
1159
|
+
*
|
|
1160
|
+
* @param identity - The workload identity to look up.
|
|
1161
|
+
* @returns The workload identity if found, undefined otherwise.
|
|
1162
|
+
*/
|
|
1163
|
+
lookup(identity: BaseWorkloadIdentity<TExtended>): Promise<BaseWorkloadIdentity<TExtended> | undefined>;
|
|
1164
|
+
/**
|
|
1165
|
+
* Optional indexed lookup by `externalId`. When omitted, callers fall back to `lookup` or a list scan.
|
|
1166
|
+
*/
|
|
1167
|
+
getByExternalId?(externalId: string): Promise<BaseWorkloadIdentity<TExtended> | undefined>;
|
|
1168
|
+
/**
|
|
1169
|
+
* Create or update a workload identity. If a record with the same `id` exists it is updated,
|
|
1170
|
+
* otherwise a new record is created.
|
|
1171
|
+
*
|
|
1172
|
+
* @param identity - The workload identity to store.
|
|
1173
|
+
*/
|
|
1174
|
+
upsert(identity: BaseWorkloadIdentity<TExtended>): Promise<BaseWorkloadIdentity<TExtended>>;
|
|
1175
|
+
/**
|
|
1176
|
+
* Delete a workload identity by id.
|
|
1177
|
+
*
|
|
1178
|
+
* @param id - The workload's unique identifier.
|
|
1179
|
+
* @returns The number of records deleted (0 or 1).
|
|
1180
|
+
*/
|
|
1181
|
+
delete(id: string): Promise<number>;
|
|
1182
|
+
/**
|
|
1183
|
+
* List workload identities with optional pagination and sort.
|
|
1184
|
+
*
|
|
1185
|
+
* @param options - Optional start (0-based), limit (page size), and sort.
|
|
1186
|
+
* @returns ListResult with total, count, items, size, page, pages.
|
|
1187
|
+
*/
|
|
1188
|
+
list(options?: ListOptions): Promise<ListResult<BaseWorkloadIdentity<TExtended>>>;
|
|
1189
|
+
}
|
|
1190
|
+
/**
|
|
1191
|
+
* IAM delta egress mode (RemoteConfig/ECI intent). Selects how IAM-visible runtime changes that
|
|
1192
|
+
* occur inside the application are surfaced to the enterprise's IAM/governance layer:
|
|
1193
|
+
*
|
|
1194
|
+
* - `'patch'`: outbound SCIM into the IAM tool (per-resource POST/PUT/PATCH/DELETE,
|
|
1195
|
+
* correlated by the App-owned id carried as SCIM `externalId`). The IAM tool's view stays fresh as users, materialized entitlement
|
|
1196
|
+
* definitions, and access change in the app. See the README "IAM delta egress" section.
|
|
1197
|
+
*
|
|
1198
|
+
* Origin/trust: every push is authenticated with the app's outgoing workload client (OAuth bearer);
|
|
1199
|
+
* the receiver treats the authenticated workload identity as the verified origin. Audit
|
|
1200
|
+
* accountability lives with the IdP that authenticated the workload and the IAM tool that granted
|
|
1201
|
+
* it access. The SDK only surfaces the signal; it never dictates the enterprise's workflow or
|
|
1202
|
+
* policy (flag, auto-revoke + notify, or simply audit).
|
|
1203
|
+
*/
|
|
1204
|
+
type IamDeltaMode = "patch";
|
|
1205
|
+
type AccessRequestCreate = {
|
|
1206
|
+
subject: string;
|
|
1207
|
+
subjectType: SubjectType;
|
|
1208
|
+
targetType: EntitlementType;
|
|
1209
|
+
target: string;
|
|
1210
|
+
justification?: string;
|
|
1211
|
+
};
|
|
1212
|
+
type AccessRequestResult = {
|
|
1213
|
+
id: string;
|
|
1214
|
+
status: "pending" | "approved" | "denied";
|
|
1215
|
+
trackingUrl: string;
|
|
1216
|
+
};
|
|
1217
|
+
/** SCIM resource types the delta patch adapter addresses. */
|
|
1218
|
+
type IamDeltaResourceType = "user" | "group" | "workload" | "customer";
|
|
1219
|
+
/** Destination-owned reference captured from a SCIM User/Group response. */
|
|
1220
|
+
type DestinationReference = {
|
|
1221
|
+
/** Service-provider-assigned SCIM resource id. */
|
|
1222
|
+
providerId: string;
|
|
1223
|
+
/** IAM-owned deep link where access to an entitlement can be requested, when supplied. */
|
|
1224
|
+
requestUrl?: string;
|
|
1225
|
+
};
|
|
1226
|
+
/**
|
|
1227
|
+
* Full IAM delta snapshot supplied by the app's maintenance/reconcile path. It mirrors the entities
|
|
1228
|
+
* visible through IAM aggregation: users, durable entitlement definitions, and active access roots.
|
|
1229
|
+
*/
|
|
1230
|
+
type IamDeltaReconcileInput = {
|
|
1231
|
+
users?: Iterable<BaseUser> | AsyncIterable<BaseUser>;
|
|
1232
|
+
workloads?: Iterable<BaseWorkloadIdentity> | AsyncIterable<BaseWorkloadIdentity>;
|
|
1233
|
+
customers?: Iterable<BaseCustomer> | AsyncIterable<BaseCustomer>;
|
|
1234
|
+
groups?: Iterable<Group2> | AsyncIterable<Group2>;
|
|
1235
|
+
roles?: Iterable<Role2> | AsyncIterable<Role2>;
|
|
1236
|
+
permissions?: Iterable<Permission> | AsyncIterable<Permission>;
|
|
1237
|
+
access?: Iterable<AccessChange> | AsyncIterable<AccessChange>;
|
|
1238
|
+
};
|
|
1239
|
+
/** Result of an app-driven full reconcile (re-push of definitions, users, and active roots). */
|
|
1240
|
+
type IamDeltaReconcileResult = {
|
|
1241
|
+
pushed: number;
|
|
1242
|
+
skipped: number;
|
|
1243
|
+
errors: string[];
|
|
1244
|
+
};
|
|
1245
|
+
/**
|
|
1246
|
+
* Projects observed runtime mutations to the configured IAM delta destination. The invariant is:
|
|
1247
|
+
* every runtime mutation the SDK observes that would change what IAM full sync shows must also
|
|
1248
|
+
* egress through this handle. That includes users, materialized entitlement definitions, and access
|
|
1249
|
+
* roots. Code templates are not pushed during config apply.
|
|
1250
|
+
*
|
|
1251
|
+
* Request-triggered methods resolve when projection completes (or immediately when not ready). They
|
|
1252
|
+
* are best-effort egress: the SCIM mutation path awaits them inside the request, but a rejection is
|
|
1253
|
+
* caught and reported as degraded egress — it never turns a committed store mutation into a SCIM
|
|
1254
|
+
* error. Reactive catalog/resource events use the same methods outside a request and warn on failure.
|
|
1255
|
+
*
|
|
1256
|
+
* Readiness follows the shared contract: `isReady()` is a synchronous check; `ready(timeout?)`
|
|
1257
|
+
* resolves once the emitter first becomes usable.
|
|
1258
|
+
*/
|
|
1259
|
+
interface IamDeltaEmitter {
|
|
1260
|
+
/** Upsert a full SCIM User representation at the destination. */
|
|
1261
|
+
onUserUpsert(user: BaseUser): Promise<void>;
|
|
1262
|
+
/** Delete a destination User identified strictly by externalId. */
|
|
1263
|
+
onUserDelete(externalId: string): Promise<void>;
|
|
1264
|
+
/** Upsert a full SCIM Group representation for a group, role, or permission definition. */
|
|
1265
|
+
onEntitlementUpsert(entity: Entitlement, type: EntitlementType): Promise<void>;
|
|
1266
|
+
/** Delete a destination entitlement Group identified by the App-owned catalog id. */
|
|
1267
|
+
onEntitlementDelete(type: EntitlementType, id: string): Promise<void>;
|
|
1268
|
+
/** Project a granted root; resolves on completion (or immediately when not ready), rejects on push failure. */
|
|
1269
|
+
onGrant(change: AccessChange): Promise<void>;
|
|
1270
|
+
/** Project a revoked root; resolves on completion (or immediately when not ready), rejects on push failure. */
|
|
1271
|
+
onRevoke(change: AccessChange): Promise<void>;
|
|
1272
|
+
/** Re-push the complete IAM-visible snapshot to the destination (app-driven full reconcile). */
|
|
1273
|
+
reconcile(input: IamDeltaReconcileInput): Promise<IamDeltaReconcileResult>;
|
|
1274
|
+
/**
|
|
1275
|
+
* Submit an on-behalf access request at `${iam.url}/AccessRequests`. Requires only the
|
|
1276
|
+
* destination channel (`url` plus the `deltaAudience` workload client) — not `isReady()`, which
|
|
1277
|
+
* additionally demands delta egress (a per-kind `'patch'` mode and its receipt stores). A tenant
|
|
1278
|
+
* whose IAM aggregates by pull alone may still submit requests.
|
|
1020
1279
|
*/
|
|
1021
|
-
|
|
1280
|
+
requestAccess(input: AccessRequestCreate): Promise<AccessRequestResult>;
|
|
1022
1281
|
/**
|
|
1023
|
-
*
|
|
1282
|
+
* Read a previously captured destination reference without making a network request. Returns
|
|
1283
|
+
* undefined until the resource has been resolved or pushed to the configured IAM destination.
|
|
1284
|
+
* `correlationId` is a User's `externalId` or an entitlement's App-owned catalog `id`.
|
|
1024
1285
|
*/
|
|
1025
|
-
|
|
1286
|
+
getDestinationRef(resourceType: IamDeltaResourceType, correlationId: string): Promise<DestinationReference | undefined>;
|
|
1287
|
+
isReady(): boolean;
|
|
1288
|
+
ready(timeout?: number): Promise<void>;
|
|
1026
1289
|
}
|
|
1027
1290
|
import { StandardSchemaV1 as StandardSchemaV14 } from "@standard-schema/spec";
|
|
1028
1291
|
type ChangeListener = () => void;
|
|
@@ -1103,85 +1366,6 @@ type RequireReadyResult = {
|
|
|
1103
1366
|
}>;
|
|
1104
1367
|
};
|
|
1105
1368
|
/**
|
|
1106
|
-
* Persisted workload principal record. Mirrors the registry/enrichment shape of `BaseUser`, scoped
|
|
1107
|
-
* to the small set of attributes meaningful for non-human identities.
|
|
1108
|
-
*
|
|
1109
|
-
* @template TExtended - Type-safe custom data that consumers can add to workload identities.
|
|
1110
|
-
*/
|
|
1111
|
-
type BaseWorkloadIdentity<TExtended = object> = {
|
|
1112
|
-
/**
|
|
1113
|
-
* Stable subject id for this workload. Used as the AccessIndex subject for
|
|
1114
|
-
* `subjectType: 'workload'` checks. Typically `clientId`, a workload id, or the token `sub`.
|
|
1115
|
-
*/
|
|
1116
|
-
id: string;
|
|
1117
|
-
/** OAuth client identifier, when the workload authenticates via client credentials. */
|
|
1118
|
-
clientId?: string;
|
|
1119
|
-
/** Human-friendly display name for the service account / machine identity. */
|
|
1120
|
-
displayName?: string;
|
|
1121
|
-
/** Free-form description of the workload's purpose. */
|
|
1122
|
-
description?: string;
|
|
1123
|
-
/** External identifier from the provisioning client (e.g. SCIM). */
|
|
1124
|
-
externalId?: string;
|
|
1125
|
-
/**
|
|
1126
|
-
* Optional Enterprise Controlled ID for this workload: `ecid:<realm>:<opaque>`. A workload is its
|
|
1127
|
-
* own governance root, never folded into a human's ECID. See https://ionite.com/docs/llms-ecid.txt.
|
|
1128
|
-
*/
|
|
1129
|
-
ecid?: string;
|
|
1130
|
-
/** Whether the workload is active. Set `false` to disable it without deleting the record. */
|
|
1131
|
-
active?: boolean;
|
|
1132
|
-
/** Default OAuth scopes associated with this workload (space-delimited tokens, normalized list). */
|
|
1133
|
-
scopes?: string[];
|
|
1134
|
-
/** Timestamp when the workload identity was first stored. */
|
|
1135
|
-
createdAt?: Date;
|
|
1136
|
-
/** Timestamp when the workload identity was last updated. */
|
|
1137
|
-
updatedAt?: Date;
|
|
1138
|
-
/** Optional free-form metadata bag. */
|
|
1139
|
-
metadata?: Record<string, unknown>;
|
|
1140
|
-
} & TExtended;
|
|
1141
|
-
/**
|
|
1142
|
-
* Abstract interface for workload identity storage backends. Implement to back the registry with
|
|
1143
|
-
* in-memory, Redis, or a database. Mirrors {@link UserStore}.
|
|
1144
|
-
*
|
|
1145
|
-
* @template TExtended - Type-safe custom data that consumers can add to workload identities.
|
|
1146
|
-
*/
|
|
1147
|
-
interface WorkloadIdentityStore<TExtended = object> {
|
|
1148
|
-
/**
|
|
1149
|
-
* Retrieve a workload identity by its unique id.
|
|
1150
|
-
*
|
|
1151
|
-
* @param id - The workload's unique identifier.
|
|
1152
|
-
* @returns The workload identity if found, undefined otherwise.
|
|
1153
|
-
*/
|
|
1154
|
-
get(id: string): Promise<BaseWorkloadIdentity<TExtended> | undefined>;
|
|
1155
|
-
/**
|
|
1156
|
-
* Retrieve a workload identity by matching identifying attributes (e.g. `clientId`, `externalId`).
|
|
1157
|
-
*
|
|
1158
|
-
* @param identity - The workload identity to look up.
|
|
1159
|
-
* @returns The workload identity if found, undefined otherwise.
|
|
1160
|
-
*/
|
|
1161
|
-
lookup(identity: BaseWorkloadIdentity<TExtended>): Promise<BaseWorkloadIdentity<TExtended> | undefined>;
|
|
1162
|
-
/**
|
|
1163
|
-
* Create or update a workload identity. If a record with the same `id` exists it is updated,
|
|
1164
|
-
* otherwise a new record is created.
|
|
1165
|
-
*
|
|
1166
|
-
* @param identity - The workload identity to store.
|
|
1167
|
-
*/
|
|
1168
|
-
upsert(identity: BaseWorkloadIdentity<TExtended>): Promise<BaseWorkloadIdentity<TExtended>>;
|
|
1169
|
-
/**
|
|
1170
|
-
* Delete a workload identity by id.
|
|
1171
|
-
*
|
|
1172
|
-
* @param id - The workload's unique identifier.
|
|
1173
|
-
* @returns The number of records deleted (0 or 1).
|
|
1174
|
-
*/
|
|
1175
|
-
delete(id: string): Promise<number>;
|
|
1176
|
-
/**
|
|
1177
|
-
* List workload identities with optional pagination and sort.
|
|
1178
|
-
*
|
|
1179
|
-
* @param options - Optional start (0-based), limit (page size), and sort.
|
|
1180
|
-
* @returns ListResult with total, count, items, size, page, pages.
|
|
1181
|
-
*/
|
|
1182
|
-
list(options?: ListOptions): Promise<ListResult<BaseWorkloadIdentity<TExtended>>>;
|
|
1183
|
-
}
|
|
1184
|
-
/**
|
|
1185
1369
|
* Token caching for workload identity authentication.
|
|
1186
1370
|
*
|
|
1187
1371
|
* Token stores are optional but recommended for performance - they enable:
|
|
@@ -1637,6 +1821,14 @@ interface IAMHandlerConfig {
|
|
|
1637
1821
|
*/
|
|
1638
1822
|
groupsUrl?: string;
|
|
1639
1823
|
/**
|
|
1824
|
+
* Base path for the SCIM Workloads endpoints (e.g., '/api/iam/Workloads')
|
|
1825
|
+
*/
|
|
1826
|
+
workloadsUrl?: string;
|
|
1827
|
+
/**
|
|
1828
|
+
* Base path for the SCIM Customers endpoints (e.g., '/api/iam/Customers')
|
|
1829
|
+
*/
|
|
1830
|
+
customersUrl?: string;
|
|
1831
|
+
/**
|
|
1640
1832
|
* Handler overrides for SCIM discovery endpoints (e.g., '/api/iam/ServiceProviderConfig')
|
|
1641
1833
|
*/
|
|
1642
1834
|
discovery?: IAMDiscoveryHandlerConfig;
|
|
@@ -1660,6 +1852,19 @@ type IAMConfig = {
|
|
|
1660
1852
|
*/
|
|
1661
1853
|
userStore?: UserStore;
|
|
1662
1854
|
/**
|
|
1855
|
+
* Store for inbound workload provisioning. When configured, `/Workloads` is served.
|
|
1856
|
+
*/
|
|
1857
|
+
workloadIdentityStore?: WorkloadIdentityStore;
|
|
1858
|
+
/**
|
|
1859
|
+
* Store for inbound customer provisioning. When configured, `/Customers` is served.
|
|
1860
|
+
*/
|
|
1861
|
+
customerStore?: CustomerStore;
|
|
1862
|
+
/**
|
|
1863
|
+
* Destination-only hook for `POST /AccessRequests`. Apps that are not IAM destinations omit this
|
|
1864
|
+
* and the endpoint returns 404.
|
|
1865
|
+
*/
|
|
1866
|
+
accessRequests?: IAMAccessRequestsConfig;
|
|
1867
|
+
/**
|
|
1663
1868
|
* Optional inbound user mapping hooks for SCIM provisioning.
|
|
1664
1869
|
* Use these when the default BaseUser <-> SCIM mapping is not a direct fit
|
|
1665
1870
|
* for your application's database model.
|
|
@@ -1676,13 +1881,28 @@ type IAMConfig = {
|
|
|
1676
1881
|
*/
|
|
1677
1882
|
usersUrl?: string;
|
|
1678
1883
|
groupsUrl?: string;
|
|
1884
|
+
workloadsUrl?: string;
|
|
1885
|
+
customersUrl?: string;
|
|
1679
1886
|
discovery?: IAMDiscoveryConfig;
|
|
1680
1887
|
/**
|
|
1681
|
-
* RemoteConfig intent
|
|
1682
|
-
*
|
|
1683
|
-
* IAM module is present.
|
|
1888
|
+
* RemoteConfig intent for workforce principals. Set by Ops/ECI via the ConfigSource; not
|
|
1889
|
+
* configurable from application code. `enabled` gates the inbound SCIM Users endpoint (default
|
|
1890
|
+
* on when the IAM module is present). `assignment` is the Ops-owned in-app grant policy
|
|
1891
|
+
* (default `'app'`). Effective Users availability also requires a `userStore` capability.
|
|
1892
|
+
*/
|
|
1893
|
+
users?: IamPrincipalKindFlag;
|
|
1894
|
+
/**
|
|
1895
|
+
* RemoteConfig intent for workload principals. Set by Ops/ECI via the ConfigSource; not
|
|
1896
|
+
* configurable from application code. `enabled` gates `/Workloads` (default on). `assignment` is
|
|
1897
|
+
* consumed by {@link Authz.grant}. `delta` is the Ops-owned per-kind egress mode.
|
|
1898
|
+
*/
|
|
1899
|
+
workloads?: IamPrincipalKindFlag;
|
|
1900
|
+
/**
|
|
1901
|
+
* RemoteConfig intent for CIAM customer principals. Set by Ops/ECI via the ConfigSource; not
|
|
1902
|
+
* configurable from application code. `enabled` gates `/Customers` (default on). `assignment` is
|
|
1903
|
+
* consumed by {@link Authz.grant}. `delta` is the Ops-owned per-kind egress mode.
|
|
1684
1904
|
*/
|
|
1685
|
-
|
|
1905
|
+
customers?: IamPrincipalKindFlag;
|
|
1686
1906
|
/**
|
|
1687
1907
|
* RemoteConfig intent flag for the inbound SCIM Groups endpoint. Set by Ops/ECI via the
|
|
1688
1908
|
* ConfigSource; not configurable from application code. Effective availability also requires an
|
|
@@ -1690,21 +1910,9 @@ type IAMConfig = {
|
|
|
1690
1910
|
*/
|
|
1691
1911
|
groups?: IAMEndpointFlag;
|
|
1692
1912
|
/**
|
|
1693
|
-
* RemoteConfig/ECI intent:
|
|
1694
|
-
*
|
|
1695
|
-
*
|
|
1696
|
-
* `'patch'`: outbound SCIM into the IAM tool keyed by the App-owned catalog id carried as SCIM
|
|
1697
|
-
* `externalId` (uses `url` as the destination base and `deltaAudience` for the outgoing workload client). Every observed runtime
|
|
1698
|
-
* mutation that changes the IAM full-sync view egresses: user and entitlement upsert/delete, and
|
|
1699
|
-
* access grant/revoke. See the README "IAM delta egress" section.
|
|
1700
|
-
*
|
|
1701
|
-
* When omitted, delta egress is disabled. The SDK only emits the signal; the enterprise's IAM
|
|
1702
|
-
* tooling owns the response (flag, auto-revoke + notify, or audit). See `IamDeltaMode`.
|
|
1703
|
-
*/
|
|
1704
|
-
delta?: IamDeltaMode;
|
|
1705
|
-
/**
|
|
1706
|
-
* RemoteConfig/ECI intent: name of the outgoing workload client used to authenticate `delta:'patch'`
|
|
1707
|
-
* pushes to the destination (`url`). When omitted, the default workload server token is used.
|
|
1913
|
+
* RemoteConfig/ECI intent: name of the outgoing workload client used to authenticate per-kind
|
|
1914
|
+
* `delta:'patch'` pushes to the destination (`url`). When omitted, the default workload server
|
|
1915
|
+
* token is used. Module-wide; per-kind enablement lives on `users`/`workloads`/`customers`.
|
|
1708
1916
|
*/
|
|
1709
1917
|
deltaAudience?: string;
|
|
1710
1918
|
};
|
|
@@ -1714,6 +1922,32 @@ type IAMConfig = {
|
|
|
1714
1922
|
type IAMEndpointFlag = {
|
|
1715
1923
|
enabled?: boolean;
|
|
1716
1924
|
};
|
|
1925
|
+
/**
|
|
1926
|
+
* RemoteConfig intent for one principal kind: endpoint enablement plus the Ops-owned assignment
|
|
1927
|
+
* policy. `assignment` defaults to `'app'` (today's notify-via-delta semantics).
|
|
1928
|
+
*/
|
|
1929
|
+
type IamPrincipalKindFlag = {
|
|
1930
|
+
enabled?: boolean;
|
|
1931
|
+
assignment?: IamAssignmentPolicy;
|
|
1932
|
+
/** Per-kind IAM delta egress. `'patch'` enables outbound SCIM for this principal kind. */
|
|
1933
|
+
delta?: IamDeltaMode;
|
|
1934
|
+
};
|
|
1935
|
+
/** Normalized, always-present principal-kind intent exposed on `ion.iam`. */
|
|
1936
|
+
type IamPrincipalKind = {
|
|
1937
|
+
enabled: boolean;
|
|
1938
|
+
assignment: IamAssignmentPolicy;
|
|
1939
|
+
delta?: IamDeltaMode;
|
|
1940
|
+
};
|
|
1941
|
+
type IAMAccessRequestsConfig = {
|
|
1942
|
+
create: (request: AccessRequestCreate) => Promise<AccessRequestResult>;
|
|
1943
|
+
};
|
|
1944
|
+
type AccessRequestSubmit = {
|
|
1945
|
+
subject: AccessChange["subject"];
|
|
1946
|
+
subjectType: SubjectType;
|
|
1947
|
+
targetType: EntitlementType;
|
|
1948
|
+
target: AccessChange["target"];
|
|
1949
|
+
justification?: string;
|
|
1950
|
+
};
|
|
1717
1951
|
type IAMEntitlementRequestUrlContext = {
|
|
1718
1952
|
request: Request;
|
|
1719
1953
|
tenantId?: string;
|
|
@@ -1721,6 +1955,8 @@ type IAMEntitlementRequestUrlContext = {
|
|
|
1721
1955
|
type IAMValidators = {
|
|
1722
1956
|
user: StandardSchemaV15<unknown, User>;
|
|
1723
1957
|
group: StandardSchemaV15<unknown, GroupResource>;
|
|
1958
|
+
workload?: StandardSchemaV15<unknown, ScimWorkload>;
|
|
1959
|
+
customer?: StandardSchemaV15<unknown, ScimCustomer>;
|
|
1724
1960
|
};
|
|
1725
1961
|
interface IAMInboundUserContext {
|
|
1726
1962
|
/**
|
|
@@ -1828,8 +2064,12 @@ interface IAMDiscoveryContext {
|
|
|
1828
2064
|
basePath: string;
|
|
1829
2065
|
usersUrl: string;
|
|
1830
2066
|
groupsUrl: string;
|
|
2067
|
+
workloadsUrl: string;
|
|
2068
|
+
customersUrl: string;
|
|
1831
2069
|
supportsUsers: boolean;
|
|
1832
2070
|
supportsGroups: boolean;
|
|
2071
|
+
supportsWorkloads: boolean;
|
|
2072
|
+
supportsCustomers: boolean;
|
|
1833
2073
|
}
|
|
1834
2074
|
interface IAMDiscoveryConfig {
|
|
1835
2075
|
/**
|
|
@@ -1894,6 +2134,12 @@ interface UsersInboundHandlerConfig {
|
|
|
1894
2134
|
*/
|
|
1895
2135
|
basePath?: string;
|
|
1896
2136
|
}
|
|
2137
|
+
interface PrincipalInboundHandlerConfig {
|
|
2138
|
+
basePath?: string;
|
|
2139
|
+
}
|
|
2140
|
+
type IAMPrincipalsInbound = {
|
|
2141
|
+
handler: (request: Request, config?: PrincipalInboundHandlerConfig) => Promise<Response>;
|
|
2142
|
+
};
|
|
1897
2143
|
interface IAMDiscoveryHandlerConfig {
|
|
1898
2144
|
/**
|
|
1899
2145
|
* Base path for the IAM discovery endpoints (e.g., '/api/iam')
|
|
@@ -1943,7 +2189,13 @@ type IAMUsersInbound = {
|
|
|
1943
2189
|
* - `groups_inbound` is available when a `catalogStore` is configured
|
|
1944
2190
|
* - `users_inbound` is available when `userStore` is configured
|
|
1945
2191
|
*/
|
|
1946
|
-
type IAM = IAMConfig & {
|
|
2192
|
+
type IAM = Omit<IAMConfig, "users" | "workloads" | "customers" | "groups"> & {
|
|
2193
|
+
users: IamPrincipalKind;
|
|
2194
|
+
workloads: IamPrincipalKind;
|
|
2195
|
+
customers: IamPrincipalKind;
|
|
2196
|
+
groups: {
|
|
2197
|
+
enabled: boolean;
|
|
2198
|
+
};
|
|
1947
2199
|
/**
|
|
1948
2200
|
* Create a new user/account in the external IAM provider
|
|
1949
2201
|
* Only available when `url` is configured.
|
|
@@ -1968,9 +2220,11 @@ type IAM = IAMConfig & {
|
|
|
1968
2220
|
* Available when `userStore` is configured in IAMConfig.
|
|
1969
2221
|
*/
|
|
1970
2222
|
users_inbound?: IAMUsersInbound;
|
|
2223
|
+
workloads_inbound?: IAMPrincipalsInbound;
|
|
2224
|
+
customers_inbound?: IAMPrincipalsInbound;
|
|
1971
2225
|
/**
|
|
1972
2226
|
* Framework-agnostic request handler for the IAM module.
|
|
1973
|
-
* Routes to discovery, users_inbound, or
|
|
2227
|
+
* Routes to discovery, users_inbound, groups_inbound, or principal-kind inbound based on path.
|
|
1974
2228
|
*/
|
|
1975
2229
|
handler: (request: Request, config?: IAMHandlerConfig) => Promise<Response>;
|
|
1976
2230
|
/** Synchronous readiness: true once this IAM handle is configured and usable. */
|
|
@@ -1985,6 +2239,15 @@ type IAM = IAMConfig & {
|
|
|
1985
2239
|
delta?: IamDeltaEmitter;
|
|
1986
2240
|
};
|
|
1987
2241
|
/**
|
|
2242
|
+
* Enforce subject-type scoping at grant time (fail closed). Rejects a grant whose effective
|
|
2243
|
+
* `subjectType` is outside the platform ceiling or outside the target's required
|
|
2244
|
+
* `assignableSubjectTypes`. Code ids resolve through the materialized row with code-owned subject
|
|
2245
|
+
* scoping. A no-op when no definition source is wired or the target entity is not found (the grant
|
|
2246
|
+
* proceeds as before). Shared by SCIM ingress and `ion.authz.grant` so both chokepoints enforce
|
|
2247
|
+
* one contract.
|
|
2248
|
+
*/
|
|
2249
|
+
declare function assertSubjectTypeAssignable(catalogStore: AccessCatalogStore | undefined, codeCatalog: CodeCatalog | undefined, change: AccessChange, cache?: CatalogAdjacencyCache): Promise<void>;
|
|
2250
|
+
/**
|
|
1988
2251
|
* Creates an IAM service instance.
|
|
1989
2252
|
*
|
|
1990
2253
|
* - If `url` is configured, enables outbound SCIM operations to external IAM
|
|
@@ -2732,100 +2995,6 @@ declare function resolveUser(request: Request, ion: Ionite): Promise<IdentityRes
|
|
|
2732
2995
|
declare function initiateLogin(request: Request, ion: Ionite): Promise<Response>;
|
|
2733
2996
|
declare function callback(request: Request, ion: Ionite): Promise<Response>;
|
|
2734
2997
|
/**
|
|
2735
|
-
* Persisted CIAM customer record with identity fields and tracking metadata.
|
|
2736
|
-
*
|
|
2737
|
-
* Builds on the shared minimal identity fields with a lightweight set of
|
|
2738
|
-
* consumer-oriented attributes and an optional CIAM (`ciam`) session envelope.
|
|
2739
|
-
* This is the type returned by `CustomerStore`. Apps typically extend the
|
|
2740
|
-
* `BaseCustomer` Zod/Valibot schema to add custom attributes.
|
|
2741
|
-
*
|
|
2742
|
-
* @template TExtended - Type-safe custom data that consumers can add to customers
|
|
2743
|
-
*/
|
|
2744
|
-
type BaseCustomer<TExtended = object> = BaseUserFields & {
|
|
2745
|
-
/**
|
|
2746
|
-
* Optional ionite tenant identifier for tenant-aware apps.
|
|
2747
|
-
*/
|
|
2748
|
-
tenantId?: string;
|
|
2749
|
-
/**
|
|
2750
|
-
* Optional external identifier from a provisioning client.
|
|
2751
|
-
*/
|
|
2752
|
-
externalId?: string;
|
|
2753
|
-
/**
|
|
2754
|
-
* Optional display name distinct from the simple `name` field.
|
|
2755
|
-
*/
|
|
2756
|
-
displayName?: string;
|
|
2757
|
-
/**
|
|
2758
|
-
* Optional email collection.
|
|
2759
|
-
* The simple `email` field still stores the primary email for convenience.
|
|
2760
|
-
*/
|
|
2761
|
-
emails?: Email[];
|
|
2762
|
-
/**
|
|
2763
|
-
* Optional phone numbers.
|
|
2764
|
-
*/
|
|
2765
|
-
phoneNumbers?: PhoneNumber[];
|
|
2766
|
-
/**
|
|
2767
|
-
* Optional account state.
|
|
2768
|
-
*/
|
|
2769
|
-
active?: boolean;
|
|
2770
|
-
/**
|
|
2771
|
-
* Timestamp when the customer was first stored.
|
|
2772
|
-
*/
|
|
2773
|
-
createdAt?: Date;
|
|
2774
|
-
/**
|
|
2775
|
-
* Timestamp when the customer was last updated (e.g., on re-login).
|
|
2776
|
-
*/
|
|
2777
|
-
updatedAt?: Date;
|
|
2778
|
-
/**
|
|
2779
|
-
* Optional CIAM envelope for stores that persist customer session profile data.
|
|
2780
|
-
* Simple app stores MAY omit this field.
|
|
2781
|
-
*/
|
|
2782
|
-
ciam?: Customer["ciam"];
|
|
2783
|
-
} & TExtended;
|
|
2784
|
-
/**
|
|
2785
|
-
* Abstract interface for customer storage backends.
|
|
2786
|
-
*
|
|
2787
|
-
* Mirrors `UserStore` but for the CIAM customer domain. Consumers can
|
|
2788
|
-
* implement this for in-memory, Redis, or database-backed persistence.
|
|
2789
|
-
*
|
|
2790
|
-
* @template TExtended - Type-safe custom data that consumers can add to customers
|
|
2791
|
-
*/
|
|
2792
|
-
interface CustomerStore<TExtended = object> {
|
|
2793
|
-
/**
|
|
2794
|
-
* Retrieve a customer by their unique identifier.
|
|
2795
|
-
*
|
|
2796
|
-
* @param id - The customer's unique identifier as defined by the store implementation
|
|
2797
|
-
* @returns The customer if found, undefined otherwise
|
|
2798
|
-
*/
|
|
2799
|
-
get(id: string): Promise<BaseCustomer<TExtended> | undefined>;
|
|
2800
|
-
/**
|
|
2801
|
-
* Retrieve a customer based on their identity attributes or CIAM claims.
|
|
2802
|
-
*
|
|
2803
|
-
* @param customer - The customer to lookup
|
|
2804
|
-
* @returns The customer if found, undefined otherwise
|
|
2805
|
-
*/
|
|
2806
|
-
lookup(customer: BaseCustomer<TExtended>): Promise<BaseCustomer<TExtended> | undefined>;
|
|
2807
|
-
/**
|
|
2808
|
-
* Create or update a customer in the store.
|
|
2809
|
-
*
|
|
2810
|
-
* @param customer - The customer data to store
|
|
2811
|
-
*/
|
|
2812
|
-
upsert(customer: BaseCustomer<TExtended>): Promise<BaseCustomer<TExtended>>;
|
|
2813
|
-
/**
|
|
2814
|
-
* Delete a customer by their unique identifier.
|
|
2815
|
-
*
|
|
2816
|
-
* @param id - The customer's unique identifier as defined by the store implementation
|
|
2817
|
-
* @returns The number of customers deleted (0 or 1)
|
|
2818
|
-
*/
|
|
2819
|
-
delete(id: string): Promise<number>;
|
|
2820
|
-
/**
|
|
2821
|
-
* List customers in the store with optional pagination and sort.
|
|
2822
|
-
*
|
|
2823
|
-
* @param options - Optional start (0-based), limit (page size), and sort
|
|
2824
|
-
* @returns ListResult with total, count, items, size, page, pages
|
|
2825
|
-
*/
|
|
2826
|
-
list(options?: ListOptions): Promise<ListResult<BaseCustomer<TExtended>>>;
|
|
2827
|
-
}
|
|
2828
|
-
/**
|
|
2829
2998
|
* Magic link data stored in the store.
|
|
2830
2999
|
*
|
|
2831
3000
|
* @template TExtended - Type-safe custom data that consumers can add to magic links
|
|
@@ -3483,9 +3652,9 @@ type AuthzConfig = {
|
|
|
3483
3652
|
* Opt-in transform applied to a group before OAA projection (e.g. computed `custom_properties`,
|
|
3484
3653
|
* redaction). Applied identically on incremental push and full sync. Undefined => identity.
|
|
3485
3654
|
*/
|
|
3486
|
-
mapGroup?: (group:
|
|
3655
|
+
mapGroup?: (group: Group2) => Group2;
|
|
3487
3656
|
/** Opt-in transform applied to a role before OAA projection. Undefined => identity. */
|
|
3488
|
-
mapRole?: (role:
|
|
3657
|
+
mapRole?: (role: Role2) => Role2;
|
|
3489
3658
|
/** Opt-in transform applied to a resource before OAA projection. Undefined => identity. */
|
|
3490
3659
|
mapResource?: (resource: Resource) => Resource;
|
|
3491
3660
|
/**
|
|
@@ -4167,12 +4336,12 @@ type BaseUser<TExtended = object> = BaseUserFields & {
|
|
|
4167
4336
|
* Optional SCIM roles.
|
|
4168
4337
|
* Commonly set by IAM inbound SCIM provisioning flows.
|
|
4169
4338
|
*/
|
|
4170
|
-
roles?:
|
|
4339
|
+
roles?: Role[];
|
|
4171
4340
|
/**
|
|
4172
4341
|
* Optional SCIM groups.
|
|
4173
4342
|
* Commonly set by IAM inbound SCIM provisioning flows.
|
|
4174
4343
|
*/
|
|
4175
|
-
groups?:
|
|
4344
|
+
groups?: Group[];
|
|
4176
4345
|
/**
|
|
4177
4346
|
* Optional SCIM entitlements.
|
|
4178
4347
|
* Commonly set by IAM inbound SCIM provisioning flows.
|
|
@@ -4307,19 +4476,19 @@ type Resource = AuthzEntityBase & {
|
|
|
4307
4476
|
/**
|
|
4308
4477
|
* AppDev-owned subject-type scoping shared by every catalog entitlement (group/role/permission).
|
|
4309
4478
|
*
|
|
4310
|
-
* - `assignableSubjectTypes` is the AppDev **veto**: the hard ceiling of
|
|
4311
|
-
* ever hold this entitlement. It is authored in application code and is
|
|
4312
|
-
* tool (projected through SCIM as a `readOnly` attribute).
|
|
4313
|
-
*
|
|
4314
|
-
*
|
|
4479
|
+
* - `assignableSubjectTypes` is the AppDev **veto**: the hard, required, non-empty ceiling of
|
|
4480
|
+
* principal kinds that may ever hold this entitlement. It is authored in application code and is
|
|
4481
|
+
* **read-only** to the IAM tool (projected through SCIM as a `readOnly` attribute). There is no
|
|
4482
|
+
* default-to-workforce and no unset-means-unrestricted: every entitlement declares its audience
|
|
4483
|
+
* explicitly. A grant whose `subjectType` is outside this set is rejected.
|
|
4315
4484
|
* - `recommendedSubjectTypes` is the AppDev **advisory default**: a (non-binding) subset of
|
|
4316
4485
|
* `assignableSubjectTypes` the IAM tool should default to. It is also read-only to IAM; the IAM
|
|
4317
4486
|
* tool is responsible for tracking changes to it over time. It MUST be a subset of
|
|
4318
4487
|
* `assignableSubjectTypes` (validated when the entitlement is authored).
|
|
4319
4488
|
*/
|
|
4320
4489
|
type SubjectTypeScoping = {
|
|
4321
|
-
/** AppDev veto:
|
|
4322
|
-
assignableSubjectTypes
|
|
4490
|
+
/** AppDev veto: required non-empty ceiling of principal kinds that may hold this entitlement (read-only to IAM). */
|
|
4491
|
+
assignableSubjectTypes: SubjectType[];
|
|
4323
4492
|
/** AppDev advisory default principal kinds; must be a subset of `assignableSubjectTypes` (read-only to IAM). */
|
|
4324
4493
|
recommendedSubjectTypes?: SubjectType[];
|
|
4325
4494
|
};
|
|
@@ -4336,7 +4505,7 @@ type Permission = AuthzEntityBase & SubjectTypeScoping & {
|
|
|
4336
4505
|
/** When true, the permission also applies to a resource's sub-resources (maps to OAA `apply_to_sub_resources`). */
|
|
4337
4506
|
applyToSubResources?: boolean;
|
|
4338
4507
|
};
|
|
4339
|
-
type
|
|
4508
|
+
type Role2 = AuthzEntityBase & SubjectTypeScoping & {
|
|
4340
4509
|
/** True when this catalog entry should be exposed as requestable access in IAM tooling. */
|
|
4341
4510
|
requestable?: boolean;
|
|
4342
4511
|
/** IAM-owned deep link where a principal can request this entitlement, when the destination provides one. */
|
|
@@ -4344,15 +4513,15 @@ type Role = AuthzEntityBase & SubjectTypeScoping & {
|
|
|
4344
4513
|
/** Permissions this role confers (definitional). Roles are flat bundles — OAA has no nested-role edge. */
|
|
4345
4514
|
permissions?: Array<string | Permission>;
|
|
4346
4515
|
};
|
|
4347
|
-
type
|
|
4516
|
+
type Group2 = AuthzEntityBase & SubjectTypeScoping & {
|
|
4348
4517
|
/** True when this catalog entry should be exposed as requestable access in IAM tooling. */
|
|
4349
4518
|
requestable?: boolean;
|
|
4350
4519
|
/** IAM-owned deep link where a principal can request this entitlement, when the destination provides one. */
|
|
4351
4520
|
requestUrl?: string;
|
|
4352
4521
|
/** Nested child groups composed into this group (definitional). */
|
|
4353
|
-
groups?: Array<string |
|
|
4522
|
+
groups?: Array<string | Group2>;
|
|
4354
4523
|
/** Roles this group confers (group is the principal). Projected as OAA `local_group` role assignments. */
|
|
4355
|
-
roles?: Array<string |
|
|
4524
|
+
roles?: Array<string | Role2>;
|
|
4356
4525
|
/** Permissions this group confers (group is the principal). Projected as OAA `local_group` application permissions. */
|
|
4357
4526
|
permissions?: Array<string | Permission>;
|
|
4358
4527
|
/**
|
|
@@ -4375,7 +4544,7 @@ type OaaAccessTargetType = "group" | "role" | "permission";
|
|
|
4375
4544
|
*/
|
|
4376
4545
|
type EntitlementType = OaaAccessTargetType;
|
|
4377
4546
|
/** A catalog Entitlement: a group, role, or permission (see {@link EntitlementType}). */
|
|
4378
|
-
type Entitlement =
|
|
4547
|
+
type Entitlement = Group2 | Role2 | Permission;
|
|
4379
4548
|
type AccessRef<T> = string | T;
|
|
4380
4549
|
/**
|
|
4381
4550
|
* A catalog entry returned synchronously by {@link EntityStore.set}. It is the entity itself,
|
|
@@ -4422,18 +4591,18 @@ type CatalogChangeKind = OaaAccessTargetType;
|
|
|
4422
4591
|
type CatalogChange = {
|
|
4423
4592
|
op: "set";
|
|
4424
4593
|
kind: CatalogChangeKind;
|
|
4425
|
-
entity:
|
|
4426
|
-
previous:
|
|
4594
|
+
entity: Group2 | Role2 | Permission;
|
|
4595
|
+
previous: Group2 | Role2 | Permission | undefined;
|
|
4427
4596
|
} | {
|
|
4428
4597
|
op: "delete";
|
|
4429
4598
|
kind: CatalogChangeKind;
|
|
4430
|
-
entity:
|
|
4599
|
+
entity: Group2 | Role2 | Permission;
|
|
4431
4600
|
};
|
|
4432
4601
|
/** Listener invoked with a {@link CatalogChange} after a durable catalog write lands. */
|
|
4433
4602
|
type CatalogChangeListener = (change: CatalogChange) => void;
|
|
4434
4603
|
type AccessCatalogStore = {
|
|
4435
|
-
groups: EntityStore<
|
|
4436
|
-
roles: EntityStore<
|
|
4604
|
+
groups: EntityStore<Group2>;
|
|
4605
|
+
roles: EntityStore<Role2>;
|
|
4437
4606
|
permissions: EntityStore<Permission>;
|
|
4438
4607
|
/**
|
|
4439
4608
|
* Reactive change subscription (the catalog analog of {@link ReactiveHandle}). When implemented,
|
|
@@ -4524,8 +4693,8 @@ type SubjectScope = SubjectType | SubjectType[] | "any";
|
|
|
4524
4693
|
*/
|
|
4525
4694
|
type AccessChange<
|
|
4526
4695
|
TUser = BaseUser,
|
|
4527
|
-
TGroup =
|
|
4528
|
-
TRole =
|
|
4696
|
+
TGroup = Group2,
|
|
4697
|
+
TRole = Role2,
|
|
4529
4698
|
TPermission = Permission
|
|
4530
4699
|
> = {
|
|
4531
4700
|
/** Deterministic id derived from `subjectType:subject:targetType:target[:scope]`; assigned by stores/orchestration. */
|
|
@@ -4592,7 +4761,7 @@ type SubjectRef = {
|
|
|
4592
4761
|
subjectType: SubjectType;
|
|
4593
4762
|
};
|
|
4594
4763
|
/** A single check target, optionally scoped to a resource. */
|
|
4595
|
-
type AccessCheckTarget<TTarget =
|
|
4764
|
+
type AccessCheckTarget<TTarget = Group2 | Role2 | Permission> = {
|
|
4596
4765
|
targetType: OaaAccessTargetType;
|
|
4597
4766
|
target: AccessRef<TTarget>;
|
|
4598
4767
|
resource?: AccessRef<Resource>;
|
|
@@ -4621,9 +4790,9 @@ type EffectiveEdge = {
|
|
|
4621
4790
|
* Revoking one role removes only its rows — overlapping permissions from the other role remain.
|
|
4622
4791
|
*/
|
|
4623
4792
|
interface AccessIndex {
|
|
4624
|
-
has(subject: AccessRef<BaseUser>, targetType: OaaAccessTargetType, target: AccessRef<
|
|
4625
|
-
hasGroup(subject: AccessRef<BaseUser>, group: AccessRef<
|
|
4626
|
-
hasRole(subject: AccessRef<BaseUser>, role: AccessRef<
|
|
4793
|
+
has(subject: AccessRef<BaseUser>, targetType: OaaAccessTargetType, target: AccessRef<Group2 | Role2 | Permission>, resource: AccessRef<Resource> | undefined, subjectType: SubjectType): Promise<AuthzDecision>;
|
|
4794
|
+
hasGroup(subject: AccessRef<BaseUser>, group: AccessRef<Group2>, resource: AccessRef<Resource> | undefined, subjectType: SubjectType): Promise<AuthzDecision>;
|
|
4795
|
+
hasRole(subject: AccessRef<BaseUser>, role: AccessRef<Role2>, resource: AccessRef<Resource> | undefined, subjectType: SubjectType): Promise<AuthzDecision>;
|
|
4627
4796
|
hasPermission(subject: AccessRef<BaseUser>, permission: AccessRef<Permission>, resource: AccessRef<Resource> | undefined, subjectType: SubjectType): Promise<AuthzDecision>;
|
|
4628
4797
|
hasAny(subject: AccessRef<BaseUser>, targets: AccessCheckTarget[], subjectType: SubjectType): Promise<AuthzDecision>;
|
|
4629
4798
|
hasAll(subject: AccessRef<BaseUser>, targets: AccessCheckTarget[], subjectType: SubjectType): Promise<AuthzDecision>;
|
|
@@ -4682,8 +4851,8 @@ type OaaSyncInput<
|
|
|
4682
4851
|
TResource
|
|
4683
4852
|
> = {
|
|
4684
4853
|
users?: Iterable<TUser> | AsyncIterable<TUser>;
|
|
4685
|
-
groups?: Iterable<TGroup |
|
|
4686
|
-
roles?: Iterable<
|
|
4854
|
+
groups?: Iterable<TGroup | Group2> | AsyncIterable<TGroup | Group2>;
|
|
4855
|
+
roles?: Iterable<Role2> | AsyncIterable<Role2>;
|
|
4687
4856
|
permissions?: Iterable<Permission> | AsyncIterable<Permission>;
|
|
4688
4857
|
resources?: Iterable<TResource> | AsyncIterable<TResource>;
|
|
4689
4858
|
access?: Iterable<AccessChange> | AsyncIterable<AccessChange>;
|
|
@@ -4695,13 +4864,13 @@ type OaaAccessChangeBatchItem = {
|
|
|
4695
4864
|
};
|
|
4696
4865
|
interface OaaClient<
|
|
4697
4866
|
TUser = BaseUser,
|
|
4698
|
-
TGroup =
|
|
4699
|
-
TRole =
|
|
4867
|
+
TGroup = Group2,
|
|
4868
|
+
TRole = Role2,
|
|
4700
4869
|
TPermission = Permission,
|
|
4701
4870
|
TResource = Resource
|
|
4702
4871
|
> {
|
|
4703
4872
|
pushUser(user: TUser): Promise<void>;
|
|
4704
|
-
pushGroup(group: TGroup |
|
|
4873
|
+
pushGroup(group: TGroup | Group2): Promise<void>;
|
|
4705
4874
|
pushRole(role: TRole): Promise<void>;
|
|
4706
4875
|
pushPermission(permission: TPermission): Promise<void>;
|
|
4707
4876
|
pushResource(resource: TResource): Promise<void>;
|
|
@@ -4816,9 +4985,9 @@ type Authz = {
|
|
|
4816
4985
|
};
|
|
4817
4986
|
/** The wired closure index powering `has*`, when the app provided one via stores. */
|
|
4818
4987
|
accessIndex?: AccessIndex;
|
|
4819
|
-
has(subject: AccessRef<BaseUser>, targetType: OaaAccessTargetType, target: AccessRef<
|
|
4820
|
-
hasGroup(subject: AccessRef<BaseUser>, group: AccessRef<
|
|
4821
|
-
hasRole(subject: AccessRef<BaseUser>, role: AccessRef<
|
|
4988
|
+
has(subject: AccessRef<BaseUser>, targetType: OaaAccessTargetType, target: AccessRef<Group2 | Role2 | Permission>, resource: AccessRef<Resource> | undefined, subjectType: SubjectType): Promise<AuthzDecision>;
|
|
4989
|
+
hasGroup(subject: AccessRef<BaseUser>, group: AccessRef<Group2>, resource: AccessRef<Resource> | undefined, subjectType: SubjectType): Promise<AuthzDecision>;
|
|
4990
|
+
hasRole(subject: AccessRef<BaseUser>, role: AccessRef<Role2>, resource: AccessRef<Resource> | undefined, subjectType: SubjectType): Promise<AuthzDecision>;
|
|
4822
4991
|
hasPermission(subject: AccessRef<BaseUser>, permission: AccessRef<Permission>, resource: AccessRef<Resource> | undefined, subjectType: SubjectType): Promise<AuthzDecision>;
|
|
4823
4992
|
hasAny(subject: AccessRef<BaseUser>, targets: AccessCheckTarget[], subjectType: SubjectType): Promise<AuthzDecision>;
|
|
4824
4993
|
hasAll(subject: AccessRef<BaseUser>, targets: AccessCheckTarget[], subjectType: SubjectType): Promise<AuthzDecision>;
|
|
@@ -4849,7 +5018,42 @@ type Authz = {
|
|
|
4849
5018
|
* is wired. Always run it off the request path.
|
|
4850
5019
|
*/
|
|
4851
5020
|
reconcile(): Promise<ReconcileReport>;
|
|
5021
|
+
/**
|
|
5022
|
+
* App-facing grant: audience + assignment-policy checks, then write the root and materialize the
|
|
5023
|
+
* index. IAM SCIM ingress does **not** use this path (it stays policy-exempt). Throws
|
|
5024
|
+
* {@link AssignmentPolicyError} when Ops forbids in-app assignment for the principal kind.
|
|
5025
|
+
*/
|
|
5026
|
+
grant(change: AccessChange): Promise<AccessChange>;
|
|
5027
|
+
/**
|
|
5028
|
+
* Submit an access request on a principal's behalf. Allowed only when that kind's assignment
|
|
5029
|
+
* policy is `'iam-request'`. Authenticated with the module-wide `deltaAudience` workload client.
|
|
5030
|
+
*/
|
|
5031
|
+
requestAccess(change: {
|
|
5032
|
+
subject: AccessChange["subject"];
|
|
5033
|
+
subjectType: SubjectType;
|
|
5034
|
+
targetType: EntitlementType;
|
|
5035
|
+
target: AccessChange["target"];
|
|
5036
|
+
justification?: string;
|
|
5037
|
+
}): Promise<{
|
|
5038
|
+
id: string;
|
|
5039
|
+
status: "pending" | "approved" | "denied";
|
|
5040
|
+
trackingUrl: string;
|
|
5041
|
+
}>;
|
|
5042
|
+
/**
|
|
5043
|
+
* App-facing revoke of a granted root. Does not re-check assignment policy (removing access is
|
|
5044
|
+
* always allowed from the app once the root exists).
|
|
5045
|
+
*/
|
|
5046
|
+
revoke(change: AccessChange): Promise<void>;
|
|
4852
5047
|
};
|
|
5048
|
+
/**
|
|
5049
|
+
* Ops-owned assignment policy for one principal kind (`RemoteConfig.iam.{users,workloads,customers}.assignment`).
|
|
5050
|
+
*
|
|
5051
|
+
* - `'app'` — the application may assign access; delta notifies IAM.
|
|
5052
|
+
* - `'iam'` — never assign in-app; show a request link (or a read-only entitlement table).
|
|
5053
|
+
* - `'iam-request'` — never assign in-app; the app submits a request on the principal's behalf via
|
|
5054
|
+
* {@link Authz.requestAccess}.
|
|
5055
|
+
*/
|
|
5056
|
+
type IamAssignmentPolicy = "app" | "iam" | "iam-request";
|
|
4853
5057
|
/** Why an {@link AccessCheckResult} resolved the way it did. */
|
|
4854
5058
|
type AccessCheckReason = "ok" | "unauthenticated" | "forbidden" | "not_configured";
|
|
4855
5059
|
/**
|
|
@@ -4887,14 +5091,14 @@ type CodeCatalogNamespace<TEntity> = {
|
|
|
4887
5091
|
* deep-frozen and id-indexed.
|
|
4888
5092
|
*/
|
|
4889
5093
|
type CodeCatalog = {
|
|
4890
|
-
groups: CodeCatalogNamespace<
|
|
4891
|
-
roles: CodeCatalogNamespace<
|
|
5094
|
+
groups: CodeCatalogNamespace<Group2>;
|
|
5095
|
+
roles: CodeCatalogNamespace<Role2>;
|
|
4892
5096
|
permissions: CodeCatalogNamespace<Permission>;
|
|
4893
5097
|
};
|
|
4894
5098
|
/** Declarative input for {@link defineCatalog} (plain arrays authored in app code). */
|
|
4895
5099
|
type CodeCatalogInput = {
|
|
4896
|
-
groups?: readonly
|
|
4897
|
-
roles?: readonly
|
|
5100
|
+
groups?: readonly Group2[];
|
|
5101
|
+
roles?: readonly Role2[];
|
|
4898
5102
|
permissions?: readonly Permission[];
|
|
4899
5103
|
};
|
|
4900
5104
|
/**
|
|
@@ -4936,7 +5140,7 @@ declare class CatalogAdjacencyCache {
|
|
|
4936
5140
|
private readonly subResources;
|
|
4937
5141
|
private readonly children;
|
|
4938
5142
|
constructor(catalog: AccessCatalogStore | undefined, resources?: ResourceProvider | undefined, code?: CodeCatalog | undefined);
|
|
4939
|
-
getNode(kind: "group" | "role" | "permission" | "resource", id: string): Promise<
|
|
5143
|
+
getNode(kind: "group" | "role" | "permission" | "resource", id: string): Promise<Group2 | Role2 | Permission | Resource | undefined>;
|
|
4940
5144
|
/** Memoized direct children of a resource (provider `children()`, else `Resource.resources` refs). */
|
|
4941
5145
|
resourceChildren(id: string): Promise<Resource[]>;
|
|
4942
5146
|
resourceAndSubResourceIds(resourceId: string): Promise<string[]>;
|
|
@@ -4993,8 +5197,8 @@ declare function reconcileSubjectAccess(subject: string, subjectType: SubjectTyp
|
|
|
4993
5197
|
* the downstream projection never carries a dangling reference.
|
|
4994
5198
|
*/
|
|
4995
5199
|
type ReferencedDefinitions = {
|
|
4996
|
-
groups:
|
|
4997
|
-
roles:
|
|
5200
|
+
groups: Group2[];
|
|
5201
|
+
roles: Role2[];
|
|
4998
5202
|
permissions: Permission[];
|
|
4999
5203
|
resources: Resource[];
|
|
5000
5204
|
};
|
|
@@ -5006,7 +5210,7 @@ type ReferencedDefinitions = {
|
|
|
5006
5210
|
* inline object references are used directly. Unresolvable string ids are skipped (a later full sync
|
|
5007
5211
|
* reconciles). Cycle-safe via a per-call visited set.
|
|
5008
5212
|
*/
|
|
5009
|
-
declare function collectReferencedDefinitions(root:
|
|
5213
|
+
declare function collectReferencedDefinitions(root: Group2 | Role2, rootKind: "group" | "role", view: CatalogView): Promise<ReferencedDefinitions>;
|
|
5010
5214
|
/**
|
|
5011
5215
|
* Request-level entitlement check helper (the value-returning "helper mode" layer). Resolves the
|
|
5012
5216
|
* authenticated principal(s) from `request` per `subjectType` (default `'any'`: resolve every
|
|
@@ -5017,13 +5221,13 @@ declare function collectReferencedDefinitions(root: Group | Role, rootKind: "gro
|
|
|
5017
5221
|
* Pure APIs/SPAs: `if (!result.allow) return result.response();`. SSR/RPC apps should ignore
|
|
5018
5222
|
* `response()` and branch on `result.allow`/`result.reason` from their own `require*` helpers.
|
|
5019
5223
|
*/
|
|
5020
|
-
declare function has(request: Request, ion: Ionite, targetType: OaaAccessTargetType, target: AccessRef<
|
|
5224
|
+
declare function has(request: Request, ion: Ionite, targetType: OaaAccessTargetType, target: AccessRef<Group2 | Role2 | Permission>, resource?: AccessRef<Resource>, subjectType?: SubjectScope): Promise<AccessCheckResult>;
|
|
5021
5225
|
/** Request-level check that a resolved principal holds a permission. See {@link has}. */
|
|
5022
5226
|
declare function hasPermission2(request: Request, ion: Ionite, permission: AccessRef<Permission>, resource?: AccessRef<Resource>, subjectType?: SubjectScope): Promise<AccessCheckResult>;
|
|
5023
5227
|
/** Request-level check that a resolved principal holds a role. See {@link has}. */
|
|
5024
|
-
declare function hasRole2(request: Request, ion: Ionite, role: AccessRef<
|
|
5228
|
+
declare function hasRole2(request: Request, ion: Ionite, role: AccessRef<Role2>, resource?: AccessRef<Resource>, subjectType?: SubjectScope): Promise<AccessCheckResult>;
|
|
5025
5229
|
/** Request-level check that a resolved principal is a member of a group. See {@link has}. */
|
|
5026
|
-
declare function hasGroup2(request: Request, ion: Ionite, group: AccessRef<
|
|
5230
|
+
declare function hasGroup2(request: Request, ion: Ionite, group: AccessRef<Group2>, resource?: AccessRef<Resource>, subjectType?: SubjectScope): Promise<AccessCheckResult>;
|
|
5027
5231
|
/** Request-level check that a resolved principal holds ANY of the given targets. See {@link has}. */
|
|
5028
5232
|
declare function hasAny2(request: Request, ion: Ionite, targets: AccessCheckTarget[], subjectType?: SubjectScope): Promise<AccessCheckResult>;
|
|
5029
5233
|
/** Request-level check that a resolved principal holds ALL of the given targets. See {@link has}. */
|
|
@@ -5320,6 +5524,10 @@ declare function generateAppleClientSecret(options: AppleClientSecretOptions): P
|
|
|
5320
5524
|
declare function entitlementToScimGroup(entity: Entitlement, type: EntitlementType, members?: GroupMember[]): GroupResource;
|
|
5321
5525
|
/** Project a stored user through the default full SCIM User shape used by IAM aggregation. */
|
|
5322
5526
|
declare function baseUserToScimUser(storedUser: BaseUser): User;
|
|
5527
|
+
/** Project a stored workload through the native SCIM Workload shape. */
|
|
5528
|
+
declare function baseWorkloadToScim(stored: BaseWorkloadIdentity): ScimWorkload;
|
|
5529
|
+
/** Project a stored customer through the native SCIM Customer shape. */
|
|
5530
|
+
declare function baseCustomerToScim(stored: BaseCustomer): ScimCustomer;
|
|
5323
5531
|
type SessionResponse = {
|
|
5324
5532
|
sid: string;
|
|
5325
5533
|
authType: "sso" | "ciam";
|
|
@@ -5364,4 +5572,4 @@ type VerifyUserOptions = {
|
|
|
5364
5572
|
* does not match, or the token is expired.
|
|
5365
5573
|
*/
|
|
5366
5574
|
declare function verifyUser(jwt: string, options: VerifyUserOptions): Promise<WorkforceUser>;
|
|
5367
|
-
export { withSetCookies, verifyUser, verifyLogoutToken, verifyLfvSignature, verifyIdToken, stringifyLfvJwks, sso, signLfvPayload, setJwksRetry, setJwksClock, setDiscoveryClock, sendTenantWebhook, sameOriginRedirectRules, resolveUser, resolveSessionCacheConfig, resolveRedirect, resolveProviderBranding, resolveJwksCacheConfig, resolveJwkForKid, resolveCustomer, resolveCiamProvider, resolveCapturedRedirect, resolveCacheConfig, resolveAfterRedirect, reconcileSubjectAccess, pkceChallengeFromVerifier, parseLfvJwks, orderedEnabledProviders, normalizeOidcIssuer, listSsoClientIdsFromCookies, isRedirectAllowed, initiateLogin, iam, hasScope, hasRole2 as hasRole, hasPermission2 as hasPermission, hasGroup2 as hasGroup, hasAnyScope, hasAny2 as hasAny, hasAllScope, hasAll2 as hasAll, has, getVerificationKeyForKid, getUser, getPublicKeyFromJwks, getPublicKeyForKid, getProviderPreset, getJwks, getDiscoveredSessionUsers, getCustomer, getCachedVerificationKey, generateLfvEd25519KeyPair, generateAppleClientSecret, fetchUserInfo, expandRoot, exchangeAuthorizationCode, entitlementToScimGroup, discoverSessions, discoverSessionRecords, discoverOidcEndpoints, defaultRedirectPolicies, configureJwksCache, collectReferencedDefinitions, clearJwksCache, clearDiscoveryCache, ciam, captureRedirect, callback, buildLfvSigningInput, buildAuthorizationUrl, blockDangerousUrls, baseUserToScimUser, assertTrustedIdTokenClaims, allowSameOrigin, allowRelativePaths, allowOrigins, allowHosts, VerifyUserOptions, VerifyLogoutTokenOptions, VerifyIdTokenOptions, UsersInboundHandlerConfig, StateCookie, SessionResponse, SessionDiscoveryOptions, ScimServiceProviderConfig, ScimSchemaDefinition, ScimSchemaAttributeDefinition, ScimResult, ScimResourceTypeSchemaExtension, ScimResourceType, ScimListResponse, ScimError, ScimAuthenticationScheme, SSOValidators, SSOHandlerConfig, SSOConfig, SSO, ResolvedSessionReadCacheConfig, ResolvedSessionCacheConfig, ResolvedJwksCacheConfig, ResolvedCacheConfig, ReferencedDefinitions, RedirectVerdict, RedirectRuleContext, RedirectRule, RedirectResult, RedirectPolicy, RedirectContext, ReconcileStores, JWKS, InMemoryTenantStore, IAMValidators, IAMUsersInbound, IAMInboundUsersConfig, IAMInboundUserContext, IAMHandlerConfig, IAMGroupsOutbound, IAMGroupsInbound, IAMDiscoveryHandlerConfig, IAMDiscoveryContext, IAMDiscoveryConfig, IAMConfig, IAM, GroupsInboundHandlerConfig, CreateUserOptions, CreateGroupOptions, CatalogView, CatalogAdjacencyCache, CIAM_PROVIDER_PRESETS, CIAMValidators, CIAMProviderType, CIAMProviderDescriptor, CIAMProviderConfig, CIAMProviderColors, CIAMProviderBranding, CIAMConfigFromCode, CIAMConfig, CIAM, CACHE_BOUNDS, BeforeLogoutHook, BeforeLogoutContext, BeforeLoginHook, BeforeLoginContext, AssertTrustedIdTokenClaimsOptions, AfterLogoutHook, AfterLogoutContext, AfterLoginHook, AfterLoginContext };
|
|
5575
|
+
export { withSetCookies, verifyUser, verifyLogoutToken, verifyLfvSignature, verifyIdToken, stringifyLfvJwks, sso, signLfvPayload, setJwksRetry, setJwksClock, setDiscoveryClock, sendTenantWebhook, sameOriginRedirectRules, resolveUser, resolveSessionCacheConfig, resolveRedirect, resolveProviderBranding, resolveJwksCacheConfig, resolveJwkForKid, resolveCustomer, resolveCiamProvider, resolveCapturedRedirect, resolveCacheConfig, resolveAfterRedirect, reconcileSubjectAccess, pkceChallengeFromVerifier, parseLfvJwks, orderedEnabledProviders, normalizeOidcIssuer, listSsoClientIdsFromCookies, isRedirectAllowed, initiateLogin, iam, hasScope, hasRole2 as hasRole, hasPermission2 as hasPermission, hasGroup2 as hasGroup, hasAnyScope, hasAny2 as hasAny, hasAllScope, hasAll2 as hasAll, has, getVerificationKeyForKid, getUser, getPublicKeyFromJwks, getPublicKeyForKid, getProviderPreset, getJwks, getDiscoveredSessionUsers, getCustomer, getCachedVerificationKey, generateLfvEd25519KeyPair, generateAppleClientSecret, fetchUserInfo, expandRoot, exchangeAuthorizationCode, entitlementToScimGroup, discoverSessions, discoverSessionRecords, discoverOidcEndpoints, defaultRedirectPolicies, configureJwksCache, collectReferencedDefinitions, clearJwksCache, clearDiscoveryCache, ciam, captureRedirect, callback, buildLfvSigningInput, buildAuthorizationUrl, blockDangerousUrls, baseWorkloadToScim, baseUserToScimUser, baseCustomerToScim, assertTrustedIdTokenClaims, assertSubjectTypeAssignable, allowSameOrigin, allowRelativePaths, allowOrigins, allowHosts, VerifyUserOptions, VerifyLogoutTokenOptions, VerifyIdTokenOptions, UsersInboundHandlerConfig, StateCookie, SessionResponse, SessionDiscoveryOptions, ScimServiceProviderConfig, ScimSchemaDefinition, ScimSchemaAttributeDefinition, ScimResult, ScimResourceTypeSchemaExtension, ScimResourceType, ScimListResponse, ScimError, ScimAuthenticationScheme, SSOValidators, SSOHandlerConfig, SSOConfig, SSO, ResolvedSessionReadCacheConfig, ResolvedSessionCacheConfig, ResolvedJwksCacheConfig, ResolvedCacheConfig, ReferencedDefinitions, RedirectVerdict, RedirectRuleContext, RedirectRule, RedirectResult, RedirectPolicy, RedirectContext, ReconcileStores, JWKS, InMemoryTenantStore, IAMValidators, IAMUsersInbound, IAMInboundUsersConfig, IAMInboundUserContext, IAMHandlerConfig, IAMGroupsOutbound, IAMGroupsInbound, IAMDiscoveryHandlerConfig, IAMDiscoveryContext, IAMDiscoveryConfig, IAMConfig, IAMAccessRequestsConfig, IAM, GroupsInboundHandlerConfig, CreateUserOptions, CreateGroupOptions, CatalogView, CatalogAdjacencyCache, CIAM_PROVIDER_PRESETS, CIAMValidators, CIAMProviderType, CIAMProviderDescriptor, CIAMProviderConfig, CIAMProviderColors, CIAMProviderBranding, CIAMConfigFromCode, CIAMConfig, CIAM, CACHE_BOUNDS, BeforeLogoutHook, BeforeLogoutContext, BeforeLoginHook, BeforeLoginContext, AssertTrustedIdTokenClaimsOptions, AfterLogoutHook, AfterLogoutContext, AfterLoginHook, AfterLoginContext, AccessRequestSubmit, AccessRequestResult, AccessRequestCreate };
|