@owlmeans/iam 0.1.18-rc.6 → 0.1.18-rc.8
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/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/iam/SKILL.md +50 -0
- package/build/types.d.ts +29 -2
- package/build/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/types.ts +32 -2
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/iam",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-08-
|
|
4
|
+
"version": "0.1.18-rc.8",
|
|
5
|
+
"generatedAt": "2026-08-24T21:14:00.118Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -23,6 +23,9 @@ Provider-agnostic IAM abstraction. Defines `IamService` interface and related ty
|
|
|
23
23
|
| `IamPermissionDefinition` | type | Declared permission `{ name, resource, action?, resourceScoped?, title? }` |
|
|
24
24
|
| `IamGrantArgs` | type | `{ resources?: string[] }` — present = resource-scoped grant form |
|
|
25
25
|
| `IamGrant` | type | `{ profileId, clientId, permission, resources? }` |
|
|
26
|
+
| `IamUser` | type | End-user of an entity `{ profileId, email?, name?, role, disabled?, grantCount? }` |
|
|
27
|
+
| `IamUserInvite` | type | `{ email, name?, role? }` — find-or-create args |
|
|
28
|
+
| `IamUserUpdate` | type | `{ name?, role?, disabled? }` |
|
|
26
29
|
| `hasPermission` | fn | `(auth, permission, { scope?, resourceId? }?)` — checks `Authorization.permissions` PermissionSet[]; an unscoped set satisfies a resourceId check |
|
|
27
30
|
| `DEFAULT_ALIAS` | const | Default service alias `'iam-service'` |
|
|
28
31
|
| `IAM_MODE_KEYCLOAK` | const | `'keycloak'` |
|
|
@@ -62,8 +65,15 @@ interface IamService extends InitializedService {
|
|
|
62
65
|
|
|
63
66
|
// Provision an OIDC client for a tenant and return its credentials.
|
|
64
67
|
// options.redirectUris hardens the client; always pass them (see "Issuer & redirect URIs").
|
|
68
|
+
// MUST refuse an existing record owned by another entity — see "A client id is a global name".
|
|
65
69
|
ensureClient: (entityId: string, clientId: string, options?: IamClientOptions) => Promise<IamClient>
|
|
66
70
|
|
|
71
|
+
// Reserve a free client id without provisioning it; false when anyone else holds it.
|
|
72
|
+
claimClient: (entityId: string, clientId: string) => Promise<boolean>
|
|
73
|
+
|
|
74
|
+
// Release a client id and everything keyed by it (called when a project/slot is deleted).
|
|
75
|
+
deleteClient: (entityId: string, clientId: string) => Promise<void>
|
|
76
|
+
|
|
67
77
|
// Provision a named permission on a client resource; returns the resource name
|
|
68
78
|
ensurePermission: (entityId: string, clientId: string, resource?: string, args?: IamPermissionArgs) => Promise<string>
|
|
69
79
|
|
|
@@ -83,9 +93,49 @@ interface IamService extends InitializedService {
|
|
|
83
93
|
|
|
84
94
|
// List grants for the client, optionally for one subject
|
|
85
95
|
listGrants: (entityId: string, clientId: string, profileId?: string) => Promise<IamGrant[]>
|
|
96
|
+
|
|
97
|
+
// --- End-user management (customer-wide users, shared per entityId) ---
|
|
98
|
+
|
|
99
|
+
// Every end-user of the entity. clientId scopes the reported grantCount — it does NOT filter.
|
|
100
|
+
listUsers: (entityId: string, clientId?: string) => Promise<IamUser[]>
|
|
101
|
+
getUser: (entityId: string, profileId: string) => Promise<IamUser | null>
|
|
102
|
+
// Find-or-create by email — the one way an end-user record comes into existence.
|
|
103
|
+
inviteUser: (entityId: string, invite: IamUserInvite) => Promise<IamUser>
|
|
104
|
+
updateUser: (entityId: string, profileId: string, update: IamUserUpdate) => Promise<IamUser>
|
|
105
|
+
removeUser: (entityId: string, profileId: string) => Promise<void>
|
|
86
106
|
}
|
|
87
107
|
```
|
|
88
108
|
|
|
109
|
+
## End-users are customer-wide
|
|
110
|
+
|
|
111
|
+
An end-user belongs to the **entity**, not to a project: one customer's users are shared across every
|
|
112
|
+
project they own. `listUsers` therefore returns the entity's whole set and `clientId` only scopes the
|
|
113
|
+
reported `grantCount` to one project's client. Do not reintroduce a per-client filter — a person who
|
|
114
|
+
has authenticated against a project but holds no grant there is still that project's user, and the
|
|
115
|
+
screen that hands out grants is exactly where they have to be visible.
|
|
116
|
+
|
|
117
|
+
`inviteUser` is idempotent by email, which is what lets an invitation and a first sign-in converge on
|
|
118
|
+
one record instead of accumulating twins. Backends that have no user store of their own (keycloak,
|
|
119
|
+
where the customer manages realm users in its console) throw `IamUnsupported('user-management')` from
|
|
120
|
+
all five methods; callers turn that into an "external console" fallback rather than an error.
|
|
121
|
+
|
|
122
|
+
## A client id is a global name
|
|
123
|
+
|
|
124
|
+
A provider resolves a client from the bare `client_id` a relying party sends — the adapter gets no
|
|
125
|
+
tenant context — so the id is unique across the whole deployment, not per entity, and the store
|
|
126
|
+
cannot namespace it on a consumer's behalf. Uniqueness has to be *in the id*.
|
|
127
|
+
|
|
128
|
+
- Compose it with the owning entity in it. A name derived from a project's own name alone lets two
|
|
129
|
+
organizations share one registration: one secret, one redirect-URI list, one permission-definition
|
|
130
|
+
set, and one grant namespace, because `PermissionSet.scope` is that same string.
|
|
131
|
+
- `ensureClient` refuses a record belonging to another entity rather than returning it. The failure
|
|
132
|
+
is deliberate — a loud provisioning error is the only alternative to a silent cross-tenant handover.
|
|
133
|
+
- Assign an id **once** and reserve it with `claimClient`. Whatever a consumer derives ids from
|
|
134
|
+
(a project alias, a slug) may later be released and re-used by a sibling, so only the registry can
|
|
135
|
+
say whether an id is free. `deleteClient` gives it back, or a deleted project's name is burned.
|
|
136
|
+
- Backends whose clients are already per-tenant (keycloak realms) satisfy this by construction:
|
|
137
|
+
`claimClient` returns true and `deleteClient` may be `IamUnsupported`.
|
|
138
|
+
|
|
89
139
|
## `IamClient.realm` field
|
|
90
140
|
|
|
91
141
|
`realm` is set by the provider to the entity ID. Use it instead of accessing internal properties:
|
package/build/types.d.ts
CHANGED
|
@@ -104,7 +104,31 @@ export interface IamService extends InitializedService {
|
|
|
104
104
|
* misconfiguration is loud instead of yielding a silently wrong issuer.
|
|
105
105
|
*/
|
|
106
106
|
getIssuerUrl: (entityId: string) => Promise<string>;
|
|
107
|
+
/**
|
|
108
|
+
* Find-or-create the entity's OIDC client.
|
|
109
|
+
*
|
|
110
|
+
* A client id is globally unique — a provider resolves it from the bare `client_id` a relying
|
|
111
|
+
* party sends, with no tenant context — so an implementation MUST refuse an existing record
|
|
112
|
+
* that belongs to a different entity (`IamClientError('client:entity-mismatch')`) rather than
|
|
113
|
+
* returning it. Silently adopting one hands the caller another tenant's secret and overwrites
|
|
114
|
+
* that tenant's redirect URIs.
|
|
115
|
+
*/
|
|
107
116
|
ensureClient: (entityId: string, clientId: string, options?: IamClientOptions) => Promise<IamClient>;
|
|
117
|
+
/**
|
|
118
|
+
* Reserve a client id for the entity without provisioning it, so a caller can find a free name
|
|
119
|
+
* before committing to it. Returns false when the id is already taken — by this entity or any
|
|
120
|
+
* other — and true when the reservation is now held.
|
|
121
|
+
*
|
|
122
|
+
* This exists because the id is minted from a name that may later be released (a project alias
|
|
123
|
+
* moves when its hostname is refused), so the naming index cannot answer whether an id is free.
|
|
124
|
+
* The registry is the only authority.
|
|
125
|
+
*/
|
|
126
|
+
claimClient: (entityId: string, clientId: string) => Promise<boolean>;
|
|
127
|
+
/**
|
|
128
|
+
* Release a client id and everything keyed by it. Called when a project or slot is deleted —
|
|
129
|
+
* without it a recreated project can inherit a stale registration.
|
|
130
|
+
*/
|
|
131
|
+
deleteClient: (entityId: string, clientId: string) => Promise<void>;
|
|
108
132
|
/**
|
|
109
133
|
* Ensures a permission/resource exists in the entity's client.
|
|
110
134
|
* Returns the canonical resource name (e.g. "res--action" or "res").
|
|
@@ -130,8 +154,11 @@ export interface IamService extends InitializedService {
|
|
|
130
154
|
/** Lists grants for the entity's client, optionally for a single subject. */
|
|
131
155
|
listGrants: (entityId: string, clientId: string, profileId?: string) => Promise<IamGrant[]>;
|
|
132
156
|
/**
|
|
133
|
-
* Lists the entity's end-users.
|
|
134
|
-
*
|
|
157
|
+
* Lists the entity's end-users. End-users are customer-wide — shared across every project of
|
|
158
|
+
* the entity — so `clientId` scopes the reported `grantCount` to one project's client and does
|
|
159
|
+
* **not** filter the set: a user who has authenticated against a project but holds no grant
|
|
160
|
+
* there is still that project's user, and the screen that manages grants is exactly where they
|
|
161
|
+
* must be visible.
|
|
135
162
|
*/
|
|
136
163
|
listUsers: (entityId: string, clientId?: string) => Promise<IamUser[]>;
|
|
137
164
|
/** Loads a single end-user by subject id, or null when absent. */
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExD,MAAM,WAAW,SAAS;IACxB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qFAAqF;IACrF,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,8DAA8D;AAC9D,MAAM,WAAW,uBAAuB;IACtC,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,kGAAkG;IAClG,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAED,yEAAyE;AACzE,MAAM,WAAW,QAAQ;IACvB,kGAAkG;IAClG,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAED,sFAAsF;AACtF,MAAM,WAAW,OAAO;IACtB,kGAAkG;IAClG,SAAS,EAAE,MAAM,CAAA;IACjB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,iGAAiG;IACjG,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,yGAAyG;AACzG,MAAM,WAAW,UAAW,SAAQ,kBAAkB;IAEpD,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACvE,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAErE;;;;;;;;;;;OAWG;IACH,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/iam",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@owlmeans/auth": "^0.1.18-rc.6",
|
|
26
26
|
"@owlmeans/context": "^0.1.18-rc.6",
|
|
27
27
|
"@owlmeans/error": "^0.1.18-rc.6",
|
|
28
|
-
"@owlmeans/oidc": "^0.1.18-rc.
|
|
28
|
+
"@owlmeans/oidc": "^0.1.18-rc.7"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@owlmeans/dep-config": "workspace:*",
|
package/src/types.ts
CHANGED
|
@@ -120,8 +120,35 @@ export interface IamService extends InitializedService {
|
|
|
120
120
|
getIssuerUrl: (entityId: string) => Promise<string>
|
|
121
121
|
|
|
122
122
|
// --- Provisioning (agent → story development) ---
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Find-or-create the entity's OIDC client.
|
|
126
|
+
*
|
|
127
|
+
* A client id is globally unique — a provider resolves it from the bare `client_id` a relying
|
|
128
|
+
* party sends, with no tenant context — so an implementation MUST refuse an existing record
|
|
129
|
+
* that belongs to a different entity (`IamClientError('client:entity-mismatch')`) rather than
|
|
130
|
+
* returning it. Silently adopting one hands the caller another tenant's secret and overwrites
|
|
131
|
+
* that tenant's redirect URIs.
|
|
132
|
+
*/
|
|
123
133
|
ensureClient: (entityId: string, clientId: string, options?: IamClientOptions) => Promise<IamClient>
|
|
124
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Reserve a client id for the entity without provisioning it, so a caller can find a free name
|
|
137
|
+
* before committing to it. Returns false when the id is already taken — by this entity or any
|
|
138
|
+
* other — and true when the reservation is now held.
|
|
139
|
+
*
|
|
140
|
+
* This exists because the id is minted from a name that may later be released (a project alias
|
|
141
|
+
* moves when its hostname is refused), so the naming index cannot answer whether an id is free.
|
|
142
|
+
* The registry is the only authority.
|
|
143
|
+
*/
|
|
144
|
+
claimClient: (entityId: string, clientId: string) => Promise<boolean>
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Release a client id and everything keyed by it. Called when a project or slot is deleted —
|
|
148
|
+
* without it a recreated project can inherit a stale registration.
|
|
149
|
+
*/
|
|
150
|
+
deleteClient: (entityId: string, clientId: string) => Promise<void>
|
|
151
|
+
|
|
125
152
|
/**
|
|
126
153
|
* Ensures a permission/resource exists in the entity's client.
|
|
127
154
|
* Returns the canonical resource name (e.g. "res--action" or "res").
|
|
@@ -178,8 +205,11 @@ export interface IamService extends InitializedService {
|
|
|
178
205
|
// --- End-user management (customer-wide users, shared per entityId) ---
|
|
179
206
|
|
|
180
207
|
/**
|
|
181
|
-
* Lists the entity's end-users.
|
|
182
|
-
*
|
|
208
|
+
* Lists the entity's end-users. End-users are customer-wide — shared across every project of
|
|
209
|
+
* the entity — so `clientId` scopes the reported `grantCount` to one project's client and does
|
|
210
|
+
* **not** filter the set: a user who has authenticated against a project but holds no grant
|
|
211
|
+
* there is still that project's user, and the screen that manages grants is exactly where they
|
|
212
|
+
* must be visible.
|
|
183
213
|
*/
|
|
184
214
|
listUsers: (entityId: string, clientId?: string) => Promise<IamUser[]>
|
|
185
215
|
|