Skip to main content
Author an identity provider plugin — the piece that answers one question for the access-control gate: who is this token? An identity provider validates an opaque inbound credential and returns the caller’s identity, or None if the token is not its own. It depends on tai42-contract only and never imports the skeleton: the contract’s IdentityProvider base and the module-level registry are the entire surface it touches.

Implement the contract

Subclass IdentityProvider and implement validate_token. Return an AuthIdentity (a user_id plus a claims dict) for a token you recognise, and None for one you do not — never raise on an unrecognised token. Raise only on a backend failure: the gate treats a raised error as fail-closed, while None falls through to the next provider in the chain.
Two optional overrides let core health-check your backing store without naming it:
  • healthcheck — probe your own storage and raise loudly on failure. The skeleton awaits it at startup for whatever provider is active, so a broken backend fails the boot rather than the first request. A provider that validates over HTTP against an external issuer has nothing to probe and inherits the no-op.
  • readiness_targets — declare the backing store(s) core’s /ready probe should ping on your behalf. Core dedupes a shared store against every other subsystem’s connections, so a store you share is pinged once.

Minting keys is a separate interface

A validate-only provider — an OIDC/JWT verifier, for instance — implements the plain IdentityProvider above and mints nothing. A provider that also issues API keys implements ApiKeyIdentityProvider, adding provision (and the key lifecycle methods), which writes the key→identity record into the provider’s own storage. Ownership is a mint-path guarantee the gate enforces centrally: provision records the owning account via the OWNER_USER_ID_CLAIM, and the verifier strips that claim from any provider that is not an ApiKeyIdentityProvider. An external issuer can therefore never assert key ownership it did not mint — you do not have to defend against it, the gate does.

Register on import

Register the factory through the module-level registry at import — no app handle, no decorator that needs the skeleton:
Importing the module registers the provider; the application activates it only when its name appears in the configured chain. Registration alone activates nothing, and a duplicate name raises loudly.

Load it

The host loads the provider by naming its module under lifecycle_modules and listing its registration name in the ordered ACCESS_CONTROL_AUTH_PROVIDERS chain. The gate tries each provider in order, first match wins. Document your provider’s own settings (issuer URLs, audiences, store connections) in your repository’s README — that impl-specific configuration lives in your repo, not on this site.

Shipped implementations

Shipped identity providers appear in the ecosystem catalog, each linking to its own repository.

See also