Interface: IdentityProvider
Defined in: packages/identity/src/port.ts:605
The identity provider behind the platform, as the setup engine and the identity
module see it: one port, a Keycloak adapter and a WSO2 Identity Server adapter, and
one contract suite that passes against both (chapter 07, vendor adapters).
Rules every method keeps
- Realms are named logically (
oktoid-staff,oktoid-holders). The adapter maps a name to its own thing: a Keycloak realm, a WSO2 tenant domain. - No vendor type crosses the port. Views carry no provider id, no representation, no secret. A client's secret is write-only.
ensure*converges. It reads, writes only what differs, and says what it wrote (Ensured). A second call with the same input changes nothing.- The engine owns what it marked. An object created here carries the managed
marker (
marker.ts). An object without it is never modified, except that IdentityProvider.assertNoDirectGrants switches off the direct grant on every client, because a built-in one is a risk we did not create. - Nothing deletes. A deleted client's secret and the
azpof tokens it issued cannot be recovered for an audit. IdentityProvider.disableClient is the strongest action. The setup engine calls it on a managed client the answer file no longer declares (PO-QA1) and, in abundleddeployment, on an undeclared one (PO-QA2); never on a provider's built-in client (BUILT_IN_CLIENTS). - Nothing re-enables. A disabled client was disabled by someone, on purpose or by the engine on a removal; IdentityProvider.ensureClient converges the rest of it and leaves it disabled. Enabling it again is an administrator's act at the provider. The one way round it: a disabled client that somebody deletes at the provider, while the answer file still declares it, is created again on the next run, and a created client is enabled. Disabling, not deleting, is how a client is kept off.
- Errors name what to do. See IdentityProviderErrorCode; an unreachable
provider is
indeterminate, never a refusal.
Order
ensureRealm, then ensureScope, then ensureAudienceMapper, then ensureClient,
then ensureSessionSettings, then assertNoDirectGrants.
Properties
kind
readonlykind:"keycloak"|"wso2"
Defined in: packages/identity/src/port.ts:607
Which vendor this is.
Methods
assertNoDirectGrants()
assertNoDirectGrants(
realm):Promise<Ensured<{checked:number; }>>
Defined in: packages/identity/src/port.ts:790
Turns the direct access grant off on every client of the realm that has it on, ours and the provider's built-ins, then reads the realm again and refuses to return while any client still allows it. Run on every converge.
Parameters
realm
string
Returns
Promise<Ensured<{ checked: number; }>>
changed when it had to switch any off; the value counts clients checked.
Throws
direct_grants_remain, naming the clients.
disableClient()
disableClient(
realm,clientId,options?):Promise<Ensured<ClientView>>
Defined in: packages/identity/src/port.ts:681
Disables a client so it can obtain no tokens. Does not delete it and does not revoke
tokens already issued, which expire with their own lifetime. Idempotent: a disabled
client gives changed: false.
By default only a managed client (PO-QA1: one the answer file no longer declares).
With options.undeclared, also one without the marker (PO-QA2: a client nobody
declared, in a realm the platform owns). Never a provider's built-in client
(BUILT_IN_CLIENTS), whatever the options say.
Disabling is what keeps a client off. A disabled client that is then deleted at the provider is created again, enabled, by IdentityProvider.ensureClient on the next run if the answer file still declares it.
Parameters
realm
string
clientId
string
options?
Returns
Promise<Ensured<ClientView>>
Throws
not_managed for a built-in client, and for a client
without the marker unless options.undeclared; not_found when there is none.
ensureAudienceMapper()
ensureAudienceMapper(
realm,spec):Promise<Ensured<MapperView>>
Defined in: packages/identity/src/port.ts:697
Makes tokens obtained with spec.scope carry spec.audience. On Keycloak that is a
mapper on the client scope; on WSO2 it is a registry the adapter keeps and applies
to each client when the client is ensured.
Parameters
realm
string
spec
Returns
Promise<Ensured<MapperView>>
Throws
not_found when the scope does not exist.
ensureClient()
ensureClient(
realm,spec):Promise<Ensured<ClientView>>
Defined in: packages/identity/src/port.ts:659
Creates or converges one client and marks it managed. Direct access grants are always off. See ClientSpec for what each kind must be.
A client that exists and is disabled stays disabled (value.enabled is false):
the call converges everything else about it and never enables it. A machine client's
secret is then neither tested nor set, because a disabled client obtains no token to
test it with; on WSO2 that also means a disabled application is never deleted and
created again for a new secret. The caller reports the client; the secret converges
on the first run after an administrator enables it.
A client that does not exist is created, enabled. That includes one the engine or an administrator disabled and somebody then deleted at the provider: if the answer file still declares it, the next run brings it back, enabled.
Parameters
realm
string
spec
Returns
Promise<Ensured<ClientView>>
Throws
conflict when a client of that id exists and is
not managed; not_found when a named scope does not exist.
ensureRealm()
Defined in: packages/identity/src/port.ts:639
Creates the realm if absent, then converges the settings in spec.
Parameters
realm
string
The logical realm name.
spec
What it should be. Absent fields are left alone.
Returns
Throws
forbidden when the credential may not create realms.
ensureScope()
Defined in: packages/identity/src/port.ts:688
Creates or converges a scope.
Parameters
realm
string
spec
Returns
ensureSessionSettings()
ensureSessionSettings(
realm,settings):Promise<Ensured<SessionView>>
Defined in: packages/identity/src/port.ts:777
Converges the session and token settings in settings (absent fields are left
alone). Settings the provider keeps per client are applied to every managed client.
Fields it cannot set are in unsupported.
Parameters
realm
string
settings
Partial<SessionSettings>
Returns
Promise<Ensured<SessionView>>
ensureUser()
ensureUser(
realm,spec):Promise<EnsuredUser>
Defined in: packages/identity/src/port.ts:712
Creates a user if absent and returns its provider subject. A user that exists is
not modified (the person may already have completed the actions) and no mail
is sent. For a new user with invite, sends the required-action mail through the
realm's SMTP; a mail failure is reported in invitationFailure and does not undo
the user.
Parameters
realm
string
spec
Returns
Promise<EnsuredUser>
listClients()
listClients(
realm):Promise<readonlyClientView[]>
Defined in: packages/identity/src/port.ts:662
Every client of the realm, ours and the provider's own, with managed set.
Parameters
realm
string
Returns
Promise<readonly ClientView[]>
listMappers()
listMappers(
realm,scope?):Promise<readonlyMapperView[]>
Defined in: packages/identity/src/port.ts:703
The audience mappers of the realm, optionally of one scope.
Parameters
realm
string
scope?
string
Returns
Promise<readonly MapperView[]>
probe()
probe(
realm?):Promise<ProbeResult>
Defined in: packages/identity/src/port.ts:620
Reads the server's version and tries each management capability: first a read, then
a create-and-delete of an object named oktoid-probe-<uuid>. Whatever it creates it
deletes, including on failure. It never writes outside the probe's own objects.
Parameters
realm?
string
The realm to probe the realm-scoped capabilities in. When it does not
exist those capabilities are indeterminate; probe again after ensureRealm.
Returns
Promise<ProbeResult>
Every capability, once. Use probeOutcome for D1.14's three outcomes.
Throws
credential_refused when the credential is not
accepted at all; every other failure becomes a capability state.
readInvitationAcceptance()
readInvitationAcceptance(
realm,subject):Promise<InvitationAcceptance>
Defined in: packages/identity/src/port.ts:753
Reads whether an invited user has taken up their account. A read: it changes nothing and sends no mail. It exists for the setup wizard's last step, which waits for the root account's holder and has no other way to see them arrive.
What each adapter reads:
- Keycloak: the user's outstanding required actions and whether a password
credential exists. Keycloak clears an action when the person completes it, so
none outstanding and a password present is
accepted; anything else ispending. It never answersunknown. - WSO2: the account state WSO2 keeps for its ask-password and forced-reset
flows. A
PENDING_*state ispendingandUNLOCKEDisaccepted. It says the password was set and nothing about the second factor, which a WSO2 user enrols at their first sign-in with no per-user record the management API returns. A user without the claim, or locked or disabled, isunknown.
A user who existed before the engine ran and was never invited reads accepted on
both, which is true of the account and says nothing of an invitation.
Parameters
realm
string
subject
string
The provider subject from IdentityProvider.ensureUser.
Returns
Promise<InvitationAcceptance>
Throws
not_found when the realm or the user does not
exist; unreachable when the provider could not be asked, which a caller reports
as not checked.
readRealm()
readRealm(
realm,options?):Promise<RealmView|undefined>
Defined in: packages/identity/src/port.ts:630
Reads a realm: its issuer and keys (from its own discovery document, never composed from configuration) and the settings this port knows.
Parameters
realm
string
The logical realm name.
options?
What to read beyond the realm's settings; see ReadRealmOptions.
Returns
Promise<RealmView | undefined>
The realm, or undefined when it does not exist.
readSessionSettings()
readSessionSettings(
realm):Promise<SessionView>
Defined in: packages/identity/src/port.ts:770
Reads the session and token settings, for the bring-your-own report, without writing.
Parameters
realm
string
Returns
Promise<SessionView>
resendInvitation()
resendInvitation(
realm,subject,actions,options?):Promise<void>
Defined in: packages/identity/src/port.ts:721
Sends the required-action mail again, to a user the engine created.
Parameters
realm
string
subject
string
The provider subject from IdentityProvider.ensureUser.
actions
readonly ("verify-email" | "update-password" | "configure-totp")[]
options?
The link's lifetime; see InvitationOptions.
Returns
Promise<void>
Throws
rejected when the realm has no working SMTP.
resolveMachineIdentity()
resolveMachineIdentity(
realm,clientId,secret):Promise<MachineIdentity|undefined>
Defined in: packages/identity/src/port.ts:761
Proves a machine client's secret is the one the engine holds, by using it, and returns what its tokens say. The secret is sent and never read back.
Parameters
realm
string
clientId
string
secret
Secret<string>
Returns
Promise<MachineIdentity | undefined>
The identity, or undefined when the provider refuses the secret.