@owlmeans/iam 0.1.18-rc.46 → 0.1.18-rc.48
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/README.md +2 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/iam/SKILL.md +15 -41
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ Provider-agnostic IAM abstraction for the OwlMeans framework — `IamService` in
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
bun add @owlmeans/iam@^0.1.18-rc.
|
|
18
|
+
bun add @owlmeans/iam@^0.1.18-rc.48
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
## Usage
|
|
@@ -38,7 +38,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
38
38
|
your project's skill store (`.agents/skills/`):
|
|
39
39
|
|
|
40
40
|
```sh
|
|
41
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
41
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.47
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
The embedded files are version-matched to this package release. Do not edit them
|
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-10-
|
|
4
|
+
"version": "0.1.18-rc.48",
|
|
5
|
+
"generatedAt": "2026-10-03T20:05:07.591Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ metadata:
|
|
|
8
8
|
|
|
9
9
|
# Using `@owlmeans/iam`
|
|
10
10
|
|
|
11
|
-
**Install:** `"@owlmeans/iam": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/iam": "^0.1.18-rc.48"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
Provider-agnostic IAM abstraction: the `IamService` interface, the permission and grant shapes, the
|
|
14
14
|
gate-param grammar, `hasPermission`, and the declarations of the provider's runtime IAM API. It
|
|
@@ -16,41 +16,13 @@ contains no implementation and talks to no provider —
|
|
|
16
16
|
concrete backends (a Keycloak proxy, an integrated backend built on the OwlMeans OIDC provider) are
|
|
17
17
|
separate packages, and every consumer depends on this interface rather than on one of them.
|
|
18
18
|
|
|
19
|
-
##
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|--------|-------------|
|
|
27
|
-
| `appendIam(context, opts?)` | Wires the OIDC guard onto a web context **and** installs the consent-before-sign-in precondition |
|
|
28
|
-
| `withIamGuard(protocolTree, coguards?)` | Returns a decorated immutable protocol tree with IAM's OIDC guard applied |
|
|
29
|
-
| `iamEntrypoints(dispatcherProps?)` | Browser-local OIDC bindings and dispatcher-screen binding |
|
|
30
|
-
| `requireConsentForLogin(ctx, opts?)` | That precondition on its own, for a context wired some other way |
|
|
31
|
-
| `CONSENT_LOGIN_PRECONDITION` / `CLIENT_IAM_SERVICE` | The precondition alias and the service alias |
|
|
32
|
-
| `useLogin` / `useLogout`, `LoginOutcome` / `LoginIntent`, `LoginPlugin` / `LoginService` / … | Re-exported sign-in surface, so an app has one IAM import rather than three |
|
|
33
|
-
| `listOrganizations(ctx)` | The signed-in subject's organizations (`OidcOrganizationItem[]`, the acting one marked `acting`) over `oidcProtocols.organizations` |
|
|
34
|
-
| `switchOrganization(ctx, entitySlug)` | Moves the session into another of its organizations over `oidcProtocols.organization` and adopts the re-signed token with `adoptToken` |
|
|
35
|
-
| `ORGANIZATION_REFUSAL` / `ORGANIZATION_OWNER_REFUSAL` | Re-exported from `@owlmeans/oidc`: the `AuthForbidden` reasons a screen phrases (not a member; not the owner) |
|
|
36
|
-
| Everything from `@owlmeans/iam` | The types above, plus `hasPermission` |
|
|
37
|
-
|
|
38
|
-
The protocol tree is immutable. Decorate it once with `withIamGuard(protocols)` before binding local
|
|
39
|
-
screens and API callers, then spread `iamEntrypoints()` once into that browser binding list. The
|
|
40
|
-
helper deliberately does not add declarations to a flattened entrypoint array.
|
|
41
|
-
|
|
42
|
-
And the consent precondition sits on `LoginService.begin` rather than on a hook, a screen or a login
|
|
43
|
-
plugin, because `begin` is the single funnel every sign-in mechanic passes through and the one place
|
|
44
|
-
the user's gesture is still live — a refusal resolves as `LoginOutcome.Gesture` and opens the consent dialog in
|
|
45
|
-
the same gesture. An application that genuinely sets no cookie passes `{ consent: { disabled: true } }`.
|
|
46
|
-
|
|
47
|
-
Both organization calls need the bindings `iamEntrypoints()` spreads, and both are answered by the
|
|
48
|
-
application's own server from the session it holds — there is no per-request organization selector,
|
|
49
|
-
so a screen that offers "act in another organization" calls `switchOrganization` and re-reads `auth`.
|
|
50
|
-
|
|
51
|
-
The server half of the same story is `@owlmeans/server-iam` — the IAM gate that asserts the grants
|
|
52
|
-
this package's screens hand out, and the runtime IAM client. Permission decisions are made there,
|
|
53
|
-
never in the browser.
|
|
19
|
+
## Where the halves live
|
|
20
|
+
|
|
21
|
+
This package is contracts only. The browser half — `appendIam`, the session's organizations and the
|
|
22
|
+
switch, `hasPermission` re-exported — is `@owlmeans/client-iam` (`client-iam` skill); the server half
|
|
23
|
+
— the IAM gate, the session's organizations on the server and the runtime IAM client — is
|
|
24
|
+
`@owlmeans/server-iam` (`server-iam` skill). Permission decisions are made on the server, never in
|
|
25
|
+
the browser.
|
|
54
26
|
|
|
55
27
|
## Public API surface
|
|
56
28
|
|
|
@@ -220,7 +192,8 @@ interface IamService extends InitializedService {
|
|
|
220
192
|
// A rename and a merge — never a delete, never an invention.
|
|
221
193
|
normalizePermissions: (entityId: string, clientId: string, args?: IamNormalizeArgs) => Promise<IamNormalizationReport>
|
|
222
194
|
|
|
223
|
-
// Provision a resource and assign it to the tenant's owner role
|
|
195
|
+
// Provision a resource and assign it to the tenant's owner role (keycloak). A no-op on the
|
|
196
|
+
// integrated backend, which has no owner role to assign to.
|
|
224
197
|
ensureResourceOwnership: (entityId: string, clientId: string, resource: IamResourceSpec) => Promise<void>
|
|
225
198
|
|
|
226
199
|
// --- Authorization (permission definitions & grants) ---
|
|
@@ -298,7 +271,7 @@ promise would hand it the wrong type — an awaited call rejects either way.
|
|
|
298
271
|
past the membership cap), `updateMember`, `removeMember`. The last owner cannot be demoted or
|
|
299
272
|
removed (`IamOrganizationError`).
|
|
300
273
|
- **`groups`** — a group is (organization, client, key), kept inside the organization record; one
|
|
301
|
-
client never reads or writes another's. `ensure`, `remove`, `members`, `addMembers`,
|
|
274
|
+
client never reads or writes another's. `list`, `ensure`, `remove`, `members`, `addMembers`,
|
|
302
275
|
`removeMembers`, `grant` / `revoke` (bound to the group's organization), `grants`, and
|
|
303
276
|
`setBundles` — a bundle (`{ filter?, permissions? }`) grants every definition it selects to the
|
|
304
277
|
group's members at claim time. `IAM_MEMBERS_GROUP` is the managed group `syncStaff` keeps in the
|
|
@@ -359,8 +332,8 @@ cannot namespace it on a consumer's behalf. Uniqueness has to be *in the id*.
|
|
|
359
332
|
|
|
360
333
|
## `IamClient.realm` field
|
|
361
334
|
|
|
362
|
-
`realm`
|
|
363
|
-
reach into an adapter's own internals (`(client as any)._realm`) for the same value.
|
|
335
|
+
Every implementation sets `realm` to the entity id, so read `client.realm ?? fallbackEntityId` and
|
|
336
|
+
never reach into an adapter's own internals (`(client as any)._realm`) for the same value.
|
|
364
337
|
|
|
365
338
|
## Issuer & redirect URIs
|
|
366
339
|
|
|
@@ -429,7 +402,6 @@ the same options — otherwise they disagree about the issuer, and only one of t
|
|
|
429
402
|
- Do not expose `getCredentialsPair` to request handlers — it returns a raw admin token.
|
|
430
403
|
- `IamClientError` means the provisioned client was invalid (missing secret, null token). The adapter
|
|
431
404
|
already throws it; callers handle it rather than re-throwing a wrapped error.
|
|
432
|
-
- `IamClient.realm` is set by every concrete implementation.
|
|
433
405
|
- An operation a backend cannot support throws `IamUnsupported('<what>')`; a whole facet it cannot
|
|
434
406
|
support is `unsupportedFacet(what)`. Callers turn that into a fallback — an "external console"
|
|
435
407
|
link, a disabled control — rather than an error screen.
|
|
@@ -440,6 +412,8 @@ the same options — otherwise they disagree about the issuer, and only one of t
|
|
|
440
412
|
|
|
441
413
|
- `@owlmeans/server-iam` — the IAM gate that asserts every permission kind, the gate-param grammar,
|
|
442
414
|
the session's organizations and the runtime IAM client; see the `server-iam` skill
|
|
415
|
+
- `@owlmeans/client-iam` — browser wiring, the organization switch and `hasPermission`; see the
|
|
416
|
+
`client-iam` skill
|
|
443
417
|
- `@owlmeans/oidc` — provider descriptors and the `iamMode` config seam; see the `oidc` skill
|
|
444
418
|
- The concrete adapters (a Keycloak proxy, and the integrated backend built on
|
|
445
419
|
`@owlmeans/server-oidc-provider` plus `@owlmeans/server-auth-identity`) ship separately and are
|
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.48",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
25
|
+
"@owlmeans/auth": "^0.1.18-rc.38",
|
|
26
26
|
"@owlmeans/context": "^0.1.18-rc.32",
|
|
27
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
27
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.39",
|
|
28
28
|
"@owlmeans/error": "^0.1.18-rc.36",
|
|
29
|
-
"@owlmeans/oidc": "^0.1.18-rc.
|
|
29
|
+
"@owlmeans/oidc": "^0.1.18-rc.53",
|
|
30
30
|
"@owlmeans/route": "^0.1.18-rc.33"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|