Identity plugin · listing tai42/accounts-postgresInstall
Permissions
Provides
accounts-postgres
Identity — Postgres-backed accounts/identity provider — owns user accounts, password login, sessions, and invites.
login
Router — The public /api/login/* routes.
users
Router — The authed /api/auth/users/me/password self-service password route.
Provides human logins on Postgres — an email and password, a session, and a role.
Member administration is the Studio’s own generic Members page over the provider’s
declared member actions, so this plugin ships no Studio page of its own. The account
model itself stays central; see Accounts. This page wires the
provider and its two routers.
accounts-postgres
The identity provider. Mount it with both routers and register it as an auth provider:manifest.yml
Connect the database
The provider carries no connection of its own. It binds to a named database throughTAI_DB_BINDING_TAI42_ACCOUNTS_POSTGRES (default default) and uses that database’s
connection, keeping its own tables inside it. A single-database deployment leaves the
binding unset and configures TAI_DATABASE_DEFAULT_PG_*; give accounts its own
database by binding it to another declared name and configuring that one:
TAI_DATABASE_<NAME>_PG_*), not a variable of this package’s own. Sessions live in
Postgres. The login throttle’s counters (per-account backoff and per-IP failures) live
in Redis, on the plugin’s own connection: TAI_ACCOUNTS_REDIS_URL, falling back to
TAI_DEFAULT_REDIS_URL. A login with no reachable Redis fails closed.
Run the migrations
The plugin ships amigrations/ folder and declares it in its descriptor, so the
shared runner discovers it as the tai42-accounts-postgres component and applies it
alongside the core chain:
tai db migrate.
Tune sessions and login limits
login
The public/api/login/* routes: POST /api/login/password verifies an email and
password and mints a session, and POST /api/login/invite/accept sets a first password
from an invite. Passwords are at least ten characters.
The first owner is not created here. The platform’s one-step setup door creates the
owner principal and, when this provider is configured, attaches the owner’s login
through it — a password set now, or an invite link the owner follows later to set one.
The provider implements that attachment seam and owns no separate first-owner route.
users
PUT /api/auth/users/me/password is the one route this module carries: a signed-in
person changing their OWN password, which revokes every other session. It is
self-service, not member administration, so it is open to every user, not just an admin.
Member administration is not routes here. The provider declares its member actions —
invite a user, send a new login link, cancel an invitation, change a member’s role or
access, and remove a member — through the platform’s generic member-actions seam, and
the Studio’s own generic Members page renders them. The provider declares its display
name, “Postgres”, which the Members page shows on each of its member and invitation rows
and beside each of its page actions. There is no outbound email: inviting a user (or sending a new link) returns a one-time invite token and a /login?invite=...
path relative to your origin (the deployment’s declared login page and invite key,
HOSTED_UI_LOGIN_PATH and HOSTED_UI_INVITE_QUERY_KEY), shown once on the action’s result; the invitee sets a
password through POST /api/login/invite/accept, which consumes the token and mints a
session in one step. role names an existing access-control role template; an unknown
name is rejected and no user is created. A member’s role is read from the platform —
the role their principal holds, or No role when their access was not set from a
role. The platform refuses a change that would leave no enabled admin principal, and
every admin principal counts, not only accounts; see
the last enabled admin stays.
Login throttles behind a proxy
The per-IP login counters key on the client the platform resolves for every public door: the direct peer unless you declare your proxies withTAI_RATE_LIMIT_TRUSTED_PROXIES or TAI_RATE_LIMIT_TRUSTED_HOPS, in which case the
forwarded client. An IPv6 client is counted by its /64. See
which client a request is from.
See also
- Accounts — the model behind these routes.
- Access control — the policy every identity resolves to.

