@vantageos/cloud-identity 0.13.0 → 0.16.0
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/CHANGELOG.md +129 -0
- package/README.md +186 -1
- package/dist/identity-refusal.d.ts +1 -1
- package/dist/identity-refusal.d.ts.map +1 -1
- package/dist/identity-refusal.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/org-by-id.d.ts +170 -0
- package/dist/org-by-id.d.ts.map +1 -0
- package/dist/org-by-id.js +232 -0
- package/dist/org-by-id.js.map +1 -0
- package/dist/principal-by-id.d.ts +138 -0
- package/dist/principal-by-id.d.ts.map +1 -1
- package/dist/principal-by-id.js +173 -0
- package/dist/principal-by-id.js.map +1 -1
- package/dist/resource-server.d.ts +108 -0
- package/dist/resource-server.d.ts.map +1 -0
- package/dist/resource-server.js +171 -0
- package/dist/resource-server.js.map +1 -0
- package/dist/scope-filter.d.ts +12 -9
- package/dist/scope-filter.d.ts.map +1 -1
- package/dist/scope-filter.js +12 -9
- package/dist/scope-filter.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,135 @@
|
|
|
3
3
|
All notable changes to `@vantageos/cloud-identity` are documented here.
|
|
4
4
|
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
5
5
|
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- `verifyMcpAccessToken` now validates `audience` as an absolute URL with no
|
|
11
|
+
fragment (RFC 8707 section 2), with the same validator as the `resource` of
|
|
12
|
+
`buildProtectedResourceMetadata`. A whitespace-only, non-URL or
|
|
13
|
+
fragment-bearing audience throws the config error instead of being accepted.
|
|
14
|
+
|
|
15
|
+
## [0.16.0]
|
|
16
|
+
|
|
17
|
+
**Additive: an organisation is its permanent ID (`./org-by-id`).** A consumer
|
|
18
|
+
used to keep its own copy of "which org is this credential", "are these two
|
|
19
|
+
rows one org", "which org is the operator" and "what is this slug's org ID".
|
|
20
|
+
Those decisions are now the package's, keyed on IDs, refusing by default. No
|
|
21
|
+
existing function changes behaviour for an existing input.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- `resolveOrgFromClaim(claims, lookups, { door? })`: a verified
|
|
26
|
+
credential's `org_id` claim to the org's mapping row (roster, scopes, kind).
|
|
27
|
+
- `sameOrg`, `isFleetStamp`, `sameTenantStamp`: comparisons over `OrgRef`
|
|
28
|
+
(`{ id?, label? }`). Unstamped is never a match.
|
|
29
|
+
- `findOperatorOrg(lookups, { cap? })`: `one | none | many | overCap | unreadable`.
|
|
30
|
+
- `resolveOrgIdForLabelBackfillOnly(label, lookups)`: label to permanent ID,
|
|
31
|
+
or a typed `ORG_ID_ABSENT` absence. For the one-off backfill only; it must
|
|
32
|
+
never be called on a request path, and the name says so. (Developed as
|
|
33
|
+
`resolveOrgIdForLabel`; that name was never published.)
|
|
34
|
+
- `orgMappingRowSchema` and the types `OrgRef`, `OrgMappingRow`,
|
|
35
|
+
`OrgMappingLookups`, `ResolvedOrg`, `ResolveOrgFromClaimOptions`,
|
|
36
|
+
`ResolveOrgFromClaimResult`, `OrgIdAbsence`, `OrgIdAbsenceReason`,
|
|
37
|
+
`OrgIdResolution`, `OperatorOrgLookups`, `FindOperatorOrgOptions`,
|
|
38
|
+
`OperatorOrgResult`.
|
|
39
|
+
- New `IdentityRefusalReason` values: `org-mapping-lookup-failed`,
|
|
40
|
+
`org-mapping-not-found`, `org-mapping-record-invalid`.
|
|
41
|
+
|
|
42
|
+
### No label resolution
|
|
43
|
+
|
|
44
|
+
An organisation is never resolved from its label on a request path, and no
|
|
45
|
+
option turns that on. A transitional `labelFallback` option was developed and
|
|
46
|
+
removed before publication: `sameOrg`, `isFleetStamp`, `sameTenantStamp` and
|
|
47
|
+
`resolveOrgFromClaim` compare and select by org ID only, a label-only input
|
|
48
|
+
refuses, and the `org-id-contradicts-label` reason and the `source` field of
|
|
49
|
+
`ResolvedOrg` went with it. The label adapter is read only by
|
|
50
|
+
`resolveOrgIdForLabelBackfillOnly`.
|
|
51
|
+
|
|
52
|
+
## [0.15.0]
|
|
53
|
+
|
|
54
|
+
**Additive: resource-server primitives (`./resource-server`).** No existing
|
|
55
|
+
function changes behaviour for an existing input. This is the identity layer an
|
|
56
|
+
MCP server needs as an OAuth 2.1 protected resource, so a separate
|
|
57
|
+
resource-server package is no longer needed.
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
|
|
61
|
+
- `buildProtectedResourceMetadata(config)`: the RFC 9728 document served at
|
|
62
|
+
`/.well-known/oauth-protected-resource` (`resource`, `authorization_servers`,
|
|
63
|
+
`bearer_methods_supported`, optional `scopes_supported`, `resource_name`,
|
|
64
|
+
`resource_documentation`). Throws on a relative or fragment-bearing resource,
|
|
65
|
+
an empty or relative authorization server list, or empty bearer methods.
|
|
66
|
+
- `unauthorizedChallenge(config)`: the `401` status and a `WWW-Authenticate:
|
|
67
|
+
Bearer` value that always carries `resource_metadata` (RFC 9728 section 5.1),
|
|
68
|
+
with optional `error`, `error_description` and `scope` (RFC 6750). Values are
|
|
69
|
+
quoted and escaped; a line break throws.
|
|
70
|
+
- `deriveClerkDiscoveryUrls(issuer)`: the OIDC discovery and JWKS URLs of an
|
|
71
|
+
`https` issuer.
|
|
72
|
+
- `verifyMcpAccessToken(authorization, config, nowMs?)`: reads the `Authorization`
|
|
73
|
+
header and verifies the token for this resource by delegating to
|
|
74
|
+
`verifyClerkSessionToken` (RS256 only; signature, `iss`, `aud`, `exp`, `nbf`),
|
|
75
|
+
with the audience mandatory. Returns the verified session, or a typed
|
|
76
|
+
`CREDENTIAL_REFUSED` refusal with the `401` envelope (`bearer-missing` and
|
|
77
|
+
`bearer-malformed` answer `invalid_request`; `token-invalid` answers
|
|
78
|
+
`invalid_token`), or `503` with no challenge when the key set is unreachable
|
|
79
|
+
(`jwks-unavailable`). A missing issuer or audience throws.
|
|
80
|
+
- Types `ProtectedResourceMetadataConfig`, `ProtectedResourceMetadata`,
|
|
81
|
+
`UnauthorizedChallengeConfig`, `UnauthorizedChallenge`, `ClerkDiscoveryUrls`,
|
|
82
|
+
`McpResourceServerConfig`, `VerifyMcpAccessTokenResult`.
|
|
83
|
+
- `IdentityRefusalReason` gains `bearer-missing`, `bearer-malformed`,
|
|
84
|
+
`token-invalid`, `jwks-unavailable`.
|
|
85
|
+
|
|
86
|
+
## [0.14.0]
|
|
87
|
+
|
|
88
|
+
**Additive: who may address whom, which rows a caller may see, and a caller's
|
|
89
|
+
standing, decided by agent ID only (`./principal-by-id`).** No existing function changes behaviour for an existing
|
|
90
|
+
input.
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
|
|
94
|
+
- `assertRecipientAddressable(sender, recipient, lookups, { door? })` (CI-2):
|
|
95
|
+
decides, by agent ID only, whether a sender may address a recipient,
|
|
96
|
+
across organisations included. Admits same organisation; client to operator
|
|
97
|
+
when the recipient's ID is on the sender organisation's roster; operator to
|
|
98
|
+
client when the sender's ID is on the recipient organisation's roster.
|
|
99
|
+
`lookups` is `{ orgKindOf, rosterOf }`. Everything else refuses with a typed
|
|
100
|
+
`RBAC_DENIED` naming the door: client to client, a missing sender or
|
|
101
|
+
recipient, a sender that is not an agent, an unresolvable roster. The roster
|
|
102
|
+
check reuses `assertPrincipalListed`. Types `RecipientIds`,
|
|
103
|
+
`RecipientLookups`, `AssertRecipientAddressableOptions`,
|
|
104
|
+
`AssertRecipientAddressableResult`.
|
|
105
|
+
- `resolveCallerStanding(credential, lookups, { adminRoles, door? })` (CI-4):
|
|
106
|
+
names a caller's standing as `anonymous` (with the typed refusal), `pre-org`
|
|
107
|
+
(a verified session with no organisation, via the new
|
|
108
|
+
`{ kind: "person-no-org", personId }` credential), `member`, `admin` or
|
|
109
|
+
`fleet`. Built on `resolveActingPrincipal` and `assertOrgAdmin`; the only
|
|
110
|
+
case the existing primitives could not say was `pre-org`, which they refuse
|
|
111
|
+
like a garbled credential. Types `CallerCredential`,
|
|
112
|
+
`AssertCallerStandingOptions`, `CallerStanding`.
|
|
113
|
+
- `filterTargetsBelongingTo(principal, rows, lookups, opts?)` (CI-3): the
|
|
114
|
+
ID-keyed row filter that replaces the name-keyed `scopeFilterList`. Async;
|
|
115
|
+
returns `{ ok: true, rows }` or `{ ok: false, refusal }`. Each row is kept
|
|
116
|
+
exactly when `assertTargetBelongsTo` admits it (same `lookups` and options,
|
|
117
|
+
including `door`, `ownerOnly`, `fleetCrossOrg`); that function is reused, not
|
|
118
|
+
re-derived. The principal is proved first: an absent or unresolved principal
|
|
119
|
+
is a refusal naming the door, even for an empty list, never an empty
|
|
120
|
+
success. A resolved principal whose rows all belong elsewhere gets
|
|
121
|
+
`{ ok: true, rows: [] }`. Rows of other organisations, unstamped rows and a
|
|
122
|
+
same-NAME row of another organisation are dropped. A lookup failure on any
|
|
123
|
+
row refuses the whole call, never a silent drop. `fleetCrossOrg: true` from a
|
|
124
|
+
principal that is not `kind: "fleet"` is refused `reserved-fleet-scope` for
|
|
125
|
+
any list. Input order is kept. Type
|
|
126
|
+
`FilterTargetsResult`.
|
|
127
|
+
|
|
128
|
+
### Deprecated
|
|
129
|
+
|
|
130
|
+
- `scopeFilterList`, `scopeFilterGet`, `passesScopeFilter` and the name-keyed
|
|
131
|
+
`OAuthCtx.fromAllowList` field now point to `filterTargetsBelongingTo` in
|
|
132
|
+
their TSDoc. Behaviour is unchanged; they are removed when the consumer
|
|
133
|
+
migrates.
|
|
134
|
+
|
|
6
135
|
## [0.13.0]
|
|
7
136
|
|
|
8
137
|
**Additive: admission by membership of a stored list, by agent ID only
|
package/README.md
CHANGED
|
@@ -183,7 +183,7 @@ await resolveTenant({ session: null }); // throws Error("Unauthenticated: no ses
|
|
|
183
183
|
unrestricted access. Useful for skipping filtering you know is pointless;
|
|
184
184
|
never as a substitute for it.
|
|
185
185
|
|
|
186
|
-
**Deprecated since 0.11.0: `passesScopeFilter`, `scopeFilterGet` and
|
|
186
|
+
**Deprecated since 0.11.0 (pointing to `filterTargetsBelongingTo` since 0.14.0): `passesScopeFilter`, `scopeFilterGet` and
|
|
187
187
|
`scopeFilterList`.** All three (the last two through the first) admit a row
|
|
188
188
|
when its `createdBy` NAME appears in the caller's `fromAllowList`, so a name
|
|
189
189
|
selects the row, which backend standard R-53 clause 1 forbids. For a target
|
|
@@ -720,6 +720,52 @@ const listed = assertPrincipalListed(who.principal, { orgId: row.orgId, principa
|
|
|
720
720
|
if (!listed.ok) throw toHttpError(listed.refusal);
|
|
721
721
|
```
|
|
722
722
|
|
|
723
|
+
**`assertRecipientAddressable(sender, recipient, lookups, opts)`** (`./principal-by-id`, 0.14.0)
|
|
724
|
+
|
|
725
|
+
Async. Returns `{ ok: true }` or `{ ok: false, refusal }`. `recipient` is
|
|
726
|
+
`{ agentId, orgId }`; `lookups` is `{ orgKindOf, rosterOf }` where
|
|
727
|
+
`rosterOf(orgId)` returns the stored `{ orgId, principalIds }` roster of that
|
|
728
|
+
client organisation; `opts` is `{ door? }`. Decided by agent ID only:
|
|
729
|
+
|
|
730
|
+
- same organisation: admitted;
|
|
731
|
+
- client sender to operator recipient: the recipient's ID must be on the
|
|
732
|
+
SENDER organisation's roster;
|
|
733
|
+
- operator sender to client recipient: the sender's ID must be on the
|
|
734
|
+
RECIPIENT organisation's roster;
|
|
735
|
+
- client to client across organisations, a missing sender or recipient, a
|
|
736
|
+
sender that is not an agent, an unknown organisation kind and an
|
|
737
|
+
unresolvable roster all refuse. A name never matches. Types: `RecipientIds`,
|
|
738
|
+
`RecipientLookups`, `AssertRecipientAddressableOptions`,
|
|
739
|
+
`AssertRecipientAddressableResult`.
|
|
740
|
+
|
|
741
|
+
```js
|
|
742
|
+
const may = await assertRecipientAddressable(who.principal, { agentId: to.id, orgId: to.orgId }, {
|
|
743
|
+
orgKindOf, rosterOf,
|
|
744
|
+
}, { door: "send_message" });
|
|
745
|
+
if (!may.ok) throw toHttpError(may.refusal);
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
**`filterTargetsBelongingTo(principal, rows, lookups, opts)`** (`./principal-by-id`, 0.14.0)
|
|
749
|
+
|
|
750
|
+
Async. The ID-keyed replacement for `scopeFilterList`. Returns
|
|
751
|
+
`{ ok: true, rows }` (the rows `assertTargetBelongsTo` admits, in input order)
|
|
752
|
+
or `{ ok: false, refusal }`. `lookups` and `opts` are those of
|
|
753
|
+
`assertTargetBelongsTo`. Type: `FilterTargetsResult`.
|
|
754
|
+
|
|
755
|
+
- an absent or unresolved principal is a refusal naming the door, even for an
|
|
756
|
+
empty list; it is never `{ ok: true, rows: [] }`;
|
|
757
|
+
- a resolved principal whose rows all belong elsewhere gets
|
|
758
|
+
`{ ok: true, rows: [] }`, so a refusal is distinguishable from an absence;
|
|
759
|
+
- rows of other organisations, unstamped rows and a same-NAME row of another
|
|
760
|
+
organisation are dropped; a name never decides;
|
|
761
|
+
- a lookup failure is a refusal of the whole call, never a silent drop.
|
|
762
|
+
|
|
763
|
+
```js
|
|
764
|
+
const out = await filterTargetsBelongingTo(who.principal, rows, { orgKindOf }, { door: "tasks:list" });
|
|
765
|
+
if (!out.ok) throw toHttpError(out.refusal);
|
|
766
|
+
return out.rows;
|
|
767
|
+
```
|
|
768
|
+
|
|
723
769
|
**The fleet is the operator organisation.** The fleet is not a reserved ID: it
|
|
724
770
|
is the organisation your `orgKindOf` adapter reports as `"operator"` (for
|
|
725
771
|
example the organisation whose mapping row carries `orgKind: "operator"`),
|
|
@@ -768,6 +814,145 @@ left in the tables the door reads, then switch the door.
|
|
|
768
814
|
takes a name as an identity input, and a test reads the exported signatures to
|
|
769
815
|
keep it that way.
|
|
770
816
|
|
|
817
|
+
### A caller's standing (0.14.0)
|
|
818
|
+
|
|
819
|
+
`resolveCallerStanding(credential, lookups, { adminRoles, door? })` names which
|
|
820
|
+
of the four callers is asking. It is built on `resolveActingPrincipal` and
|
|
821
|
+
`assertOrgAdmin`; it is not a second path.
|
|
822
|
+
|
|
823
|
+
| Credential (verified by you) | Standing |
|
|
824
|
+
|---|---|
|
|
825
|
+
| none, garbled, unknown or inactive principal | `anonymous`, with the typed `refusal` |
|
|
826
|
+
| `{ kind: "person-no-org", personId }` | `pre-org` (signed in, no organisation) |
|
|
827
|
+
| person or agent, or a non-operator service account, without the admin role | `member`, with `principal` |
|
|
828
|
+
| person whose `verifiedOrgRole` is in `adminRoles` | `admin`, with `principal` |
|
|
829
|
+
| service account of the operator organisation (`orgKindOf` is `"operator"`) | `fleet`, with `principal` |
|
|
830
|
+
|
|
831
|
+
Types: `CallerCredential`, `AssertCallerStandingOptions`, `CallerStanding`.
|
|
832
|
+
|
|
833
|
+
- A master token reaches `fleet` by your mapping it to the operator service
|
|
834
|
+
account: `validateMasterBearer` proves the secret, then you pass
|
|
835
|
+
`{ kind: "service", serviceAccountId }`. The package never mints a fleet
|
|
836
|
+
credential from a bearer.
|
|
837
|
+
- A Clerk session reaches the function through `verifyClerkSessionToken`: with
|
|
838
|
+
an `org_id` claim, pass a `person` credential carrying `verifiedOrgId` and
|
|
839
|
+
`verifiedOrgRole`; without one, pass `person-no-org`. A person credential
|
|
840
|
+
that merely lacks `verifiedOrgId` is garbled and is `anonymous`, never `pre-org`.
|
|
841
|
+
- Branch on `standing`, never on the absence of a field. `pre-org` is not
|
|
842
|
+
`anonymous`: refuse it where an organisation is needed, but answer it as a
|
|
843
|
+
signed-in caller (see the refusal rules of your read doors).
|
|
844
|
+
|
|
845
|
+
## Protecting an MCP server as an OAuth resource (`/resource-server`)
|
|
846
|
+
|
|
847
|
+
An MCP server that requires a bearer token is an OAuth 2.1 protected resource.
|
|
848
|
+
These primitives are the whole resource side; they fetch nothing and call no
|
|
849
|
+
network.
|
|
850
|
+
|
|
851
|
+
```ts
|
|
852
|
+
import {
|
|
853
|
+
buildProtectedResourceMetadata,
|
|
854
|
+
unauthorizedChallenge,
|
|
855
|
+
deriveClerkDiscoveryUrls,
|
|
856
|
+
verifyMcpAccessToken,
|
|
857
|
+
} from "@vantageos/cloud-identity/resource-server";
|
|
858
|
+
|
|
859
|
+
// GET /.well-known/oauth-protected-resource (RFC 9728)
|
|
860
|
+
const metadata = buildProtectedResourceMetadata({
|
|
861
|
+
resource: "https://mcp.example.com/mcp",
|
|
862
|
+
authorizationServers: ["https://clerk.example.com"],
|
|
863
|
+
scopesSupported: ["mcp:read", "mcp:write"],
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
// On every MCP request
|
|
867
|
+
const r = await verifyMcpAccessToken(req.headers.authorization, {
|
|
868
|
+
realm: "mcp",
|
|
869
|
+
resourceMetadataUrl: "https://mcp.example.com/.well-known/oauth-protected-resource",
|
|
870
|
+
issuer: "https://clerk.example.com",
|
|
871
|
+
audience: "https://mcp.example.com/mcp", // this resource: required
|
|
872
|
+
jwks: () => fetchJwks(deriveClerkDiscoveryUrls("https://clerk.example.com").jwksUrl),
|
|
873
|
+
});
|
|
874
|
+
if (!r.ok) return respond(r.status, "headers" in r ? r.headers : {});
|
|
875
|
+
// r.session.userId, r.session.claims
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
- `buildProtectedResourceMetadata` returns the RFC 9728 document
|
|
879
|
+
(`ProtectedResourceMetadataConfig` in, `ProtectedResourceMetadata` out).
|
|
880
|
+
- `unauthorizedChallenge` returns `{ status: 401, headers }` whose
|
|
881
|
+
`WWW-Authenticate` always carries `resource_metadata`, plus `error`,
|
|
882
|
+
`error_description` and `scope` when given (`UnauthorizedChallengeConfig`,
|
|
883
|
+
`UnauthorizedChallenge`). Values are escaped; a line break throws.
|
|
884
|
+
- `deriveClerkDiscoveryUrls` returns `ClerkDiscoveryUrls`
|
|
885
|
+
(`discoveryUrl`, `jwksUrl`) for an `https` issuer.
|
|
886
|
+
- `verifyMcpAccessToken` reuses `verifyClerkSessionToken` (RS256 only) and
|
|
887
|
+
requires the token's `aud` to contain `audience`. It returns the verified
|
|
888
|
+
session, or a `CREDENTIAL_REFUSED` refusal with the `401` envelope
|
|
889
|
+
(`McpResourceServerConfig`, `VerifyMcpAccessTokenResult`):
|
|
890
|
+
`bearer-missing` and `bearer-malformed` answer `invalid_request`,
|
|
891
|
+
`token-invalid` answers `invalid_token` (wrong signature, issuer, audience,
|
|
892
|
+
expiry or not-before are one answer), and an unreachable key set is `503`
|
|
893
|
+
with no challenge (`jwks-unavailable`). A missing issuer or audience throws.
|
|
894
|
+
- Limits, stated: the token needs a `sub` and a `kid` (the Clerk session shape);
|
|
895
|
+
the consumer fetches and caches the key set; no scope check is made on the
|
|
896
|
+
token (read `r.session.claims`).
|
|
897
|
+
|
|
898
|
+
## An organisation is its permanent ID (0.16.0)
|
|
899
|
+
|
|
900
|
+
A label (the slug an org can be renamed to) is display text. These functions
|
|
901
|
+
decide "which organisation" from the permanent org ID, with the store supplied
|
|
902
|
+
as adapters, and refuse by default. All are in `./org-by-id` and the root.
|
|
903
|
+
|
|
904
|
+
**`resolveOrgFromClaim(claims, lookups, opts)`** takes the claim record of a
|
|
905
|
+
VERIFIED credential (never a request field) and returns
|
|
906
|
+
`{ ok: true, org: { id, label, allowedOrchestrators, scopes, orgKind } }`
|
|
907
|
+
or a typed `RBAC_DENIED` refusal. The `org_id` claim (also read from
|
|
908
|
+
`organizationId` and `orgId`, only when shaped like a Clerk org ID) selects the
|
|
909
|
+
mapping row through `lookups.orgById`; a stale label in the token is ignored,
|
|
910
|
+
so a rename never changes who the caller is. Refused: no claim, an ID no
|
|
911
|
+
mapping holds, an inactive org, a row that does not repeat the ID asked for, a
|
|
912
|
+
malformed row, a missing or throwing adapter.
|
|
913
|
+
|
|
914
|
+
```ts
|
|
915
|
+
const r = await resolveOrgFromClaim(identity, {
|
|
916
|
+
orgById: (id) => db.mappingByClerkOrgId(id),
|
|
917
|
+
}, { door: "tasks:list" });
|
|
918
|
+
if (!r.ok) throw new IdentityRefusalError(r.refusal);
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
**`sameOrg(a, b, opts)`**, **`isFleetStamp(stamp, operator, opts)`** and
|
|
922
|
+
**`sameTenantStamp(a, b, operator, opts)`** compare `OrgRef` values
|
|
923
|
+
(`{ id?, label? }`). Two IDs are equal or they are not; unstamped is never
|
|
924
|
+
a match; `isFleetStamp` is true for an unstamped stamp or the operator's, and
|
|
925
|
+
`sameTenantStamp` is true for the same org or when both are the fleet's.
|
|
926
|
+
|
|
927
|
+
**`findOperatorOrg(lookups, opts)`** finds the operator organisation from
|
|
928
|
+
`lookups.activeOrganisations(limit)`: `one`, `none`, `many`, `overCap`
|
|
929
|
+
(`cap` defaults to 1000, the read is `cap + 1`) or `unreadable`. Only `one` is
|
|
930
|
+
an operator; pass `undefined` as `operator` otherwise and only unstamped rows
|
|
931
|
+
are the fleet's.
|
|
932
|
+
|
|
933
|
+
**`resolveOrgIdForLabelBackfillOnly(label, lookups)`** derives the permanent
|
|
934
|
+
ID of the org a label names, for a ONE-OFF BACKFILL that stamps rows written
|
|
935
|
+
before IDs existed. It must never be called on a request path: a request
|
|
936
|
+
decides its organisation from the verified `org_id` claim
|
|
937
|
+
(`resolveOrgFromClaim`), and a miss there is a refusal, never a retry by label.
|
|
938
|
+
It returns `{ present: true, orgId }` or a typed `ORG_ID_ABSENT` absence
|
|
939
|
+
(`no-label`, `lookup-failed`, `not-mapped`, `record-invalid`, `id-not-filled`).
|
|
940
|
+
It never invents an ID.
|
|
941
|
+
|
|
942
|
+
**`orgMappingRowSchema`** is the Zod shape of a mapping row an adapter returns
|
|
943
|
+
(`id`, `label`, `active`, `allowedOrchestrators`, `scopes`, `orgKind`).
|
|
944
|
+
|
|
945
|
+
Types: `OrgRef`, `OrgMappingRow`, `OrgMappingLookups`,
|
|
946
|
+
`ResolvedOrg`, `ResolveOrgFromClaimOptions`, `ResolveOrgFromClaimResult`,
|
|
947
|
+
`OrgIdAbsence`, `OrgIdAbsenceReason`, `OrgIdResolution`, `OperatorOrgLookups`,
|
|
948
|
+
`FindOperatorOrgOptions`, `OperatorOrgResult`.
|
|
949
|
+
|
|
950
|
+
**No label resolution.** No function above compares or selects by label, and
|
|
951
|
+
no option turns that on: a reference or credential without an org ID names no
|
|
952
|
+
organisation and is refused. A store that has not filled every ID is filled
|
|
953
|
+
once, with `resolveOrgIdForLabelBackfillOnly`, before the consumer relies on
|
|
954
|
+
these functions.
|
|
955
|
+
|
|
771
956
|
## What this package does not do
|
|
772
957
|
|
|
773
958
|
Worth reading before you rely on it.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* closed vocabulary for the person path.
|
|
14
14
|
*/
|
|
15
15
|
export type IdentityRefusalCode = "RBAC_DENIED" | "CREDENTIAL_REFUSED";
|
|
16
|
-
export type IdentityRefusalReason = "unknown-role" | "unknown-minimum-role" | "invalid-role-order" | "role-below-minimum" | "role-claim-absent" | "role-claim-unmapped" | "invalid-role-mapping" | "membership-invalid-input" | "membership-lookup-failed" | "membership-not-found" | "membership-record-invalid" | "membership-inactive" | "other-organisation" | "no-verified-organisation" | "role-not-admin" | "namespace-invalid" | "no-write-prefixes" | "namespace-write-denied" | "secret-not-configured" | "secret-mismatch" | "credential-invalid" | "principal-lookup-failed" | "principal-not-found" | "principal-record-invalid" | "principal-inactive" | "organisation-not-active" | "reserved-fleet-scope" | "acting-agent-other-organisation" | "target-unstamped" | "target-other-organisation" | "target-owner-mismatch" | "principal-not-a-person" | "list-absent" | "list-empty" | "principal-not-an-agent" | "principal-not-listed";
|
|
16
|
+
export type IdentityRefusalReason = "unknown-role" | "unknown-minimum-role" | "invalid-role-order" | "role-below-minimum" | "role-claim-absent" | "role-claim-unmapped" | "invalid-role-mapping" | "membership-invalid-input" | "membership-lookup-failed" | "membership-not-found" | "membership-record-invalid" | "membership-inactive" | "other-organisation" | "no-verified-organisation" | "role-not-admin" | "namespace-invalid" | "no-write-prefixes" | "namespace-write-denied" | "secret-not-configured" | "secret-mismatch" | "credential-invalid" | "principal-lookup-failed" | "principal-not-found" | "principal-record-invalid" | "principal-inactive" | "organisation-not-active" | "reserved-fleet-scope" | "acting-agent-other-organisation" | "target-unstamped" | "target-other-organisation" | "target-owner-mismatch" | "principal-not-a-person" | "list-absent" | "list-empty" | "principal-not-an-agent" | "principal-not-listed" | "bearer-missing" | "bearer-malformed" | "token-invalid" | "jwks-unavailable" | "org-mapping-lookup-failed" | "org-mapping-not-found" | "org-mapping-record-invalid";
|
|
17
17
|
export type IdentityRefusal = {
|
|
18
18
|
code: IdentityRefusalCode;
|
|
19
19
|
reason: IdentityRefusalReason;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-refusal.d.ts","sourceRoot":"","sources":["../src/identity-refusal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG,oBAAoB,CAAC;AAEvE,MAAM,MAAM,qBAAqB,GAE7B,cAAc,GACd,sBAAsB,GACtB,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,GACnB,qBAAqB,GACrB,sBAAsB,GAEtB,0BAA0B,GAC1B,0BAA0B,GAC1B,sBAAsB,GACtB,2BAA2B,GAC3B,qBAAqB,GACrB,oBAAoB,GAEpB,0BAA0B,GAC1B,gBAAgB,GAEhB,mBAAmB,GACnB,mBAAmB,GACnB,wBAAwB,GAExB,uBAAuB,GACvB,iBAAiB,GAEjB,oBAAoB,GACpB,yBAAyB,GACzB,qBAAqB,GACrB,0BAA0B,GAC1B,oBAAoB,GACpB,yBAAyB,GACzB,sBAAsB,GACtB,iCAAiC,GACjC,kBAAkB,GAClB,2BAA2B,GAC3B,uBAAuB,GAEvB,wBAAwB,GAExB,aAAa,GACb,YAAY,GACZ,wBAAwB,GACxB,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"identity-refusal.d.ts","sourceRoot":"","sources":["../src/identity-refusal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG,oBAAoB,CAAC;AAEvE,MAAM,MAAM,qBAAqB,GAE7B,cAAc,GACd,sBAAsB,GACtB,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,GACnB,qBAAqB,GACrB,sBAAsB,GAEtB,0BAA0B,GAC1B,0BAA0B,GAC1B,sBAAsB,GACtB,2BAA2B,GAC3B,qBAAqB,GACrB,oBAAoB,GAEpB,0BAA0B,GAC1B,gBAAgB,GAEhB,mBAAmB,GACnB,mBAAmB,GACnB,wBAAwB,GAExB,uBAAuB,GACvB,iBAAiB,GAEjB,oBAAoB,GACpB,yBAAyB,GACzB,qBAAqB,GACrB,0BAA0B,GAC1B,oBAAoB,GACpB,yBAAyB,GACzB,sBAAsB,GACtB,iCAAiC,GACjC,kBAAkB,GAClB,2BAA2B,GAC3B,uBAAuB,GAEvB,wBAAwB,GAExB,aAAa,GACb,YAAY,GACZ,wBAAwB,GACxB,sBAAsB,GAEtB,gBAAgB,GAChB,kBAAkB,GAClB,eAAe,GACf,kBAAkB,GAElB,2BAA2B,GAC3B,uBAAuB,GACvB,4BAA4B,CAAC;AAEjC,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,MAAM,EAAE,qBAAqB,CAAC;IAC9B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,0EAA0E;AAC1E,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;gBACtB,OAAO,EAAE,eAAe;CAKrC;AAED,gEAAgE;AAChE,wBAAgB,OAAO,CACrB,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,qBAAqB,EAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,eAAe,CAEjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-refusal.js","sourceRoot":"","sources":["../src/identity-refusal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"identity-refusal.js","sourceRoot":"","sources":["../src/identity-refusal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAoEH,0EAA0E;AAC1E,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,OAAO,CAAkB;IAClC,YAAY,OAAwB;QAClC,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;QACjF,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED,gEAAgE;AAChE,MAAM,UAAU,OAAO,CACrB,IAAyB,EACzB,MAA6B,EAC7B,IAAY,EACZ,MAAc;IAEd,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACxC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -37,6 +37,10 @@ export { isRowInTenant, resolveMembership, requireOrgAdmin, membershipRecordSche
|
|
|
37
37
|
export type { MembershipRecord, ResolvedMembership, ResolveMembershipInput, ResolveMembershipResult, RequireOrgAdminInput, } from "./tenant-membership.js";
|
|
38
38
|
export { assertNamespaceWrite } from "./namespace-write.js";
|
|
39
39
|
export { timingSafeEqualSync, assertSecretSync } from "./secret-compare-sync.js";
|
|
40
|
-
export { actingCredentialSchema, principalRowSchema, organisationRowSchema, resolveActingPrincipal, assertTargetBelongsTo, assertOrgAdmin, assertPrincipalListed, } from "./principal-by-id.js";
|
|
41
|
-
export type { ActingCredential, PrincipalRow, OrganisationRow, PrincipalLookups, OrgKind, OrgKindLookups, ActingPrincipalKind, ActingPrincipal, ResolveActingPrincipalResult, TargetIds, AssertTargetOptions, AssertTargetResult, AssertOrgAdminOptions, AssertOrgAdminResult, PrincipalIdList, AssertPrincipalListedOptions, AssertPrincipalListedResult, } from "./principal-by-id.js";
|
|
40
|
+
export { actingCredentialSchema, principalRowSchema, organisationRowSchema, resolveActingPrincipal, assertTargetBelongsTo, filterTargetsBelongingTo, assertOrgAdmin, assertPrincipalListed, assertRecipientAddressable, resolveCallerStanding, } from "./principal-by-id.js";
|
|
41
|
+
export type { ActingCredential, PrincipalRow, OrganisationRow, PrincipalLookups, OrgKind, OrgKindLookups, ActingPrincipalKind, ActingPrincipal, ResolveActingPrincipalResult, TargetIds, AssertTargetOptions, AssertTargetResult, FilterTargetsResult, AssertOrgAdminOptions, AssertOrgAdminResult, PrincipalIdList, AssertPrincipalListedOptions, AssertPrincipalListedResult, RecipientIds, RecipientLookups, AssertRecipientAddressableOptions, AssertRecipientAddressableResult, CallerCredential, AssertCallerStandingOptions, CallerStanding, } from "./principal-by-id.js";
|
|
42
|
+
export { buildProtectedResourceMetadata, unauthorizedChallenge, deriveClerkDiscoveryUrls, verifyMcpAccessToken, } from "./resource-server.js";
|
|
43
|
+
export type { ProtectedResourceMetadataConfig, ProtectedResourceMetadata, UnauthorizedChallengeConfig, UnauthorizedChallenge, ClerkDiscoveryUrls, McpResourceServerConfig, VerifyMcpAccessTokenResult, } from "./resource-server.js";
|
|
44
|
+
export { sameOrg, isFleetStamp, sameTenantStamp, resolveOrgFromClaim, resolveOrgIdForLabelBackfillOnly, findOperatorOrg, orgMappingRowSchema, } from "./org-by-id.js";
|
|
45
|
+
export type { OrgRef, OrgMappingRow, OrgMappingLookups, ResolvedOrg, ResolveOrgFromClaimOptions, ResolveOrgFromClaimResult, OrgIdAbsence, OrgIdAbsenceReason, OrgIdResolution, OperatorOrgLookups, FindOperatorOrgOptions, OperatorOrgResult, } from "./org-by-id.js";
|
|
42
46
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -38,5 +38,16 @@ export { timingSafeEqualSync, assertSecretSync } from "./secret-compare-sync.js"
|
|
|
38
38
|
// 0.11.0 — The acting principal by ID and the target checked by ID. A name is
|
|
39
39
|
// a display label: it never selects a row and never authorises one.
|
|
40
40
|
// 0.12.0 — assertOrgAdmin: the org-admin proof on a principal resolved by ID.
|
|
41
|
-
export { actingCredentialSchema, principalRowSchema, organisationRowSchema, resolveActingPrincipal, assertTargetBelongsTo, assertOrgAdmin, assertPrincipalListed, } from "./principal-by-id.js";
|
|
41
|
+
export { actingCredentialSchema, principalRowSchema, organisationRowSchema, resolveActingPrincipal, assertTargetBelongsTo, filterTargetsBelongingTo, assertOrgAdmin, assertPrincipalListed, assertRecipientAddressable, resolveCallerStanding, } from "./principal-by-id.js";
|
|
42
|
+
// 0.15.0 — Resource-server primitives: RFC 9728 protected resource metadata,
|
|
43
|
+
// the RFC 6750 401 challenge, issuer discovery URLs and MCP access-token
|
|
44
|
+
// verification bound to this resource. Replaces the standalone resource-server
|
|
45
|
+
// package; one identity layer.
|
|
46
|
+
export { buildProtectedResourceMetadata, unauthorizedChallenge, deriveClerkDiscoveryUrls, verifyMcpAccessToken, } from "./resource-server.js";
|
|
47
|
+
// 0.16.0 — An organisation is its permanent ID: the credential's org_id claim to
|
|
48
|
+
// the org's mapping row, the ID comparisons and the operator org. Labels
|
|
49
|
+
// (slugs) never select or prove an org; no option turns that on. The
|
|
50
|
+
// label-to-ID derivation is exported only as
|
|
51
|
+
// `resolveOrgIdForLabelBackfillOnly`, for a one-off backfill.
|
|
52
|
+
export { sameOrg, isFleetStamp, sameTenantStamp, resolveOrgFromClaim, resolveOrgIdForLabelBackfillOnly, findOperatorOrg, orgMappingRowSchema, } from "./org-by-id.js";
|
|
42
53
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,mBAAmB,GAEpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAS9D,0CAA0C;AAC1C,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAU7B,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAU1E,kFAAkF;AAClF,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,gBAAgB,EAChB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAWzB,sEAAsE;AACtE,yEAAyE;AACzE,mEAAmE;AACnE,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAY/B,+EAA+E;AAC/E,mEAAmE;AACnE,OAAO,EACL,cAAc,EACd,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAa7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAOhE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAQ7D,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AASlE,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAMjF,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAc/B,+EAA+E;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAM7D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAO/E,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAQhC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjF,8EAA8E;AAC9E,oEAAoE;AACpE,8EAA8E;AAC9E,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,cAAc,EACd,qBAAqB,GACtB,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,mBAAmB,GAEpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAS9D,0CAA0C;AAC1C,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAU7B,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAU1E,kFAAkF;AAClF,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,gBAAgB,EAChB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AAWzB,sEAAsE;AACtE,yEAAyE;AACzE,mEAAmE;AACnE,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAY/B,+EAA+E;AAC/E,mEAAmE;AACnE,OAAO,EACL,cAAc,EACd,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAa7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAOhE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAQ7D,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AASlE,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAMjF,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAc/B,+EAA+E;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAM7D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAO/E,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAQhC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjF,8EAA8E;AAC9E,oEAAoE;AACpE,8EAA8E;AAC9E,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,cAAc,EACd,qBAAqB,EACrB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AA6B9B,6EAA6E;AAC7E,yEAAyE;AACzE,+EAA+E;AAC/E,+BAA+B;AAC/B,OAAO,EACL,8BAA8B,EAC9B,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAW9B,iFAAiF;AACjF,yEAAyE;AACzE,qEAAqE;AACrE,6CAA6C;AAC7C,8DAA8D;AAC9D,OAAO,EACL,OAAO,EACP,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,gCAAgC,EAChC,eAAe,EACf,mBAAmB,GACpB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vantageos/cloud-identity — an organisation is its permanent ID.
|
|
3
|
+
*
|
|
4
|
+
* Everything here decides "which organisation" from the permanent org ID a
|
|
5
|
+
* verified credential or a stored row carries. A label (the slug an org can be
|
|
6
|
+
* renamed to) is display text: it never selects an org and never proves two
|
|
7
|
+
* references are one org.
|
|
8
|
+
*
|
|
9
|
+
* Refusal, always. There is no option that compares or resolves by label: a
|
|
10
|
+
* reference or credential without an org ID names no organisation, and a
|
|
11
|
+
* mapping is reached only by an ID.
|
|
12
|
+
*
|
|
13
|
+
* The store is the consumer's: every read is an adapter it supplies, called
|
|
14
|
+
* with the key as presented, byte for byte. A missing, throwing or malformed
|
|
15
|
+
* adapter refuses. An adapter's error text is never surfaced.
|
|
16
|
+
*/
|
|
17
|
+
import { z } from "zod";
|
|
18
|
+
import { type IdentityRefusal } from "./identity-refusal.js";
|
|
19
|
+
import type { OrgKind } from "./principal-by-id.js";
|
|
20
|
+
/**
|
|
21
|
+
* An organisation as a row or a caller names it: the permanent ID and the
|
|
22
|
+
* label. Either may be absent. Both absent is "unstamped", which names no
|
|
23
|
+
* organisation.
|
|
24
|
+
*/
|
|
25
|
+
export type OrgRef = {
|
|
26
|
+
/** The permanent org ID. */
|
|
27
|
+
id?: string | null;
|
|
28
|
+
/** The renamable label (slug). Display text; never compared. */
|
|
29
|
+
label?: string | null;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Do two references name the same organisation? Only by ID, when both carry
|
|
33
|
+
* one. A label never matches, and absence is not a match: two unstamped
|
|
34
|
+
* references are NOT the same organisation here.
|
|
35
|
+
*/
|
|
36
|
+
export declare function sameOrg(a: OrgRef | null | undefined, b: OrgRef | null | undefined): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Is a stamp the fleet's: unstamped, or the operator organisation's? The
|
|
39
|
+
* operator is read from stored data by the caller (see `findOperatorOrg`);
|
|
40
|
+
* pass `undefined` when there is not exactly one, and only an unstamped stamp
|
|
41
|
+
* is the fleet's. An empty-string stamp is neither unstamped nor the operator.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isFleetStamp(stamp: OrgRef | null | undefined, operator: OrgRef | null | undefined): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Do two stamps name the same tenant: the same organisation, or both the
|
|
46
|
+
* fleet's? Two IDs that differ are two tenants even under one label.
|
|
47
|
+
*/
|
|
48
|
+
export declare function sameTenantStamp(a: OrgRef | null | undefined, b: OrgRef | null | undefined, operator: OrgRef | null | undefined): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* The consumer's organisation mapping row, as an adapter returns it. `id` is
|
|
51
|
+
* the permanent org ID and may be absent while the store is being filled;
|
|
52
|
+
* `label` is the slug. Extra fields are allowed and ignored.
|
|
53
|
+
*/
|
|
54
|
+
export declare const orgMappingRowSchema: z.ZodObject<{
|
|
55
|
+
id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
56
|
+
label: z.ZodString;
|
|
57
|
+
active: z.ZodBoolean;
|
|
58
|
+
allowedOrchestrators: z.ZodArray<z.ZodString>;
|
|
59
|
+
scopes: z.ZodArray<z.ZodString>;
|
|
60
|
+
orgKind: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
export type OrgMappingRow = z.input<typeof orgMappingRowSchema>;
|
|
63
|
+
type Lookup<A extends unknown[], R> = (...args: A) => Promise<R | null | undefined> | R | null | undefined;
|
|
64
|
+
/** Indexed reads of the mapping store. Only the lookups of the path taken are called. */
|
|
65
|
+
export type OrgMappingLookups = {
|
|
66
|
+
/** The mapping row whose permanent ID is exactly the one asked for. */
|
|
67
|
+
orgById?: Lookup<[orgId: string], OrgMappingRow>;
|
|
68
|
+
/** The mapping row whose label is exactly the one asked for. Read only by `resolveOrgIdForLabelBackfillOnly`. */
|
|
69
|
+
orgByLabel?: Lookup<[label: string], OrgMappingRow>;
|
|
70
|
+
};
|
|
71
|
+
/** The org a credential resolves to, with the roster and scopes of its mapping row. */
|
|
72
|
+
export type ResolvedOrg = {
|
|
73
|
+
/** The permanent org ID: the one the credential carried and the mapping holds. */
|
|
74
|
+
id: string;
|
|
75
|
+
/** The org's CURRENT label. Display text. */
|
|
76
|
+
label: string;
|
|
77
|
+
allowedOrchestrators: string[];
|
|
78
|
+
scopes: string[];
|
|
79
|
+
orgKind: OrgKind | null;
|
|
80
|
+
};
|
|
81
|
+
export type ResolveOrgFromClaimOptions = {
|
|
82
|
+
/** The consumer's name for the door; carried on every refusal. */
|
|
83
|
+
door?: string;
|
|
84
|
+
};
|
|
85
|
+
export type ResolveOrgFromClaimResult = {
|
|
86
|
+
ok: true;
|
|
87
|
+
org: ResolvedOrg;
|
|
88
|
+
} | {
|
|
89
|
+
ok: false;
|
|
90
|
+
refusal: IdentityRefusal;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Resolves a VERIFIED credential's claims to the stored mapping row of its
|
|
94
|
+
* organisation, or refuses. The claim's org ID selects the row; nothing the
|
|
95
|
+
* request supplies does.
|
|
96
|
+
*
|
|
97
|
+
* A credential carrying no usable org ID is refused
|
|
98
|
+
* (`no-verified-organisation`) and an ID no mapping holds is refused
|
|
99
|
+
* (`org-mapping-not-found`). A label claim (a slug) is never read: it neither
|
|
100
|
+
* selects a mapping nor rescues a missing ID.
|
|
101
|
+
*
|
|
102
|
+
* `claims` is the verified identity's own claim record, never a request field.
|
|
103
|
+
*/
|
|
104
|
+
export declare function resolveOrgFromClaim(claims: Record<string, unknown> | null | undefined, lookups: OrgMappingLookups | null | undefined, options?: ResolveOrgFromClaimOptions): Promise<ResolveOrgFromClaimResult>;
|
|
105
|
+
export type OrgIdAbsenceReason = "no-label" | "lookup-failed" | "not-mapped" | "record-invalid" | "id-not-filled";
|
|
106
|
+
/** The typed absence of an ID. A non-empty object: never mistaken for an ID or for nothing. */
|
|
107
|
+
export type OrgIdAbsence = {
|
|
108
|
+
code: "ORG_ID_ABSENT";
|
|
109
|
+
reason: OrgIdAbsenceReason;
|
|
110
|
+
};
|
|
111
|
+
export type OrgIdResolution = {
|
|
112
|
+
present: true;
|
|
113
|
+
orgId: string;
|
|
114
|
+
} | {
|
|
115
|
+
present: false;
|
|
116
|
+
absence: OrgIdAbsence;
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* BACKFILL ONLY. Derives the permanent org ID of the organisation a label
|
|
120
|
+
* names, from the consumer's stored mapping, so a one-off migration can stamp
|
|
121
|
+
* rows written before IDs existed.
|
|
122
|
+
*
|
|
123
|
+
* MUST NEVER be called on a request path. A request decides its organisation
|
|
124
|
+
* from the verified credential's `org_id` claim (`resolveOrgFromClaim`); a miss
|
|
125
|
+
* there is a refusal, never a retry by label. A label is renamable display
|
|
126
|
+
* text: resolving an org from it on a request is the name-to-ID defect this
|
|
127
|
+
* module exists to close, and the export name carries that restriction so a
|
|
128
|
+
* reviewer sees it at every call site.
|
|
129
|
+
*
|
|
130
|
+
* A derivation and not an authorization: it answers for an inactive mapping
|
|
131
|
+
* too. It never invents an ID: a mapping with none filled is `id-not-filled`.
|
|
132
|
+
*/
|
|
133
|
+
export declare function resolveOrgIdForLabelBackfillOnly(label: string | null | undefined, lookups: OrgMappingLookups | null | undefined): Promise<OrgIdResolution>;
|
|
134
|
+
export type OperatorOrgLookups = {
|
|
135
|
+
/**
|
|
136
|
+
* The ACTIVE organisation mapping rows, at most `limit` of them. Called with
|
|
137
|
+
* `cap + 1` so a filled read is recognisable as over the cap.
|
|
138
|
+
*/
|
|
139
|
+
activeOrganisations?: (limit: number) => unknown;
|
|
140
|
+
};
|
|
141
|
+
export type FindOperatorOrgOptions = {
|
|
142
|
+
/** Read bound. Default 1000. A read over the cap is never decided from. */
|
|
143
|
+
cap?: number;
|
|
144
|
+
};
|
|
145
|
+
export type OperatorOrgResult = {
|
|
146
|
+
kind: "one";
|
|
147
|
+
org: {
|
|
148
|
+
id: string | undefined;
|
|
149
|
+
label: string;
|
|
150
|
+
};
|
|
151
|
+
} | {
|
|
152
|
+
kind: "none";
|
|
153
|
+
} | {
|
|
154
|
+
kind: "many";
|
|
155
|
+
count: number;
|
|
156
|
+
} | {
|
|
157
|
+
kind: "overCap";
|
|
158
|
+
} | {
|
|
159
|
+
kind: "unreadable";
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Finds the operator organisation (the fleet) from stored mapping rows: the
|
|
163
|
+
* single ACTIVE row whose kind is exactly `"operator"`. None, several, an
|
|
164
|
+
* over-cap read, an unreadable store and a malformed row are each a typed
|
|
165
|
+
* non-answer, so the caller can only treat the fleet as "no single operator"
|
|
166
|
+
* (fail closed) and never widen from a guess.
|
|
167
|
+
*/
|
|
168
|
+
export declare function findOperatorOrg(lookups: OperatorOrgLookups | null | undefined, options?: FindOperatorOrgOptions): Promise<OperatorOrgResult>;
|
|
169
|
+
export {};
|
|
170
|
+
//# sourceMappingURL=org-by-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-by-id.d.ts","sourceRoot":"","sources":["../src/org-by-id.ts"],"names":[],"mappings":"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"}
|