Repository navigation
AKB Backend v0.16.2
Authentication
-
The bundled Keycloak's sign-in pages use AKB's login theme (
akb, source in
frontend/keycloak-theme): AKB's tokens and typeface, light and dark,
English and Korean. Every page is one card laid out after Astryx's login
card: the mark and name above it, a centred title, 36px controls, the
account form with a monochrome primary button, then the identity providers
under "Or continue with", and language and theme below the card. The frontend image now carries the assembled theme at
/usr/share/akb/keycloak-theme/akb, outside nginx's web root. The
standalone-ssooverlay and the Helmssotemplate give the Keycloak
StatefulSet alogin-themeinit container, using the frontend Deployment's
image reference, that copies the theme into anemptyDirmounted read-only
at/opt/keycloak/themes/akb; Keycloak's own image is unchanged. A new
receipt profile,bundled-keycloak-v6, makes the realm use it:loginTheme
akb, internationalization on withenandko(defaulten), and the
administration client attributeakb.login.native-only=true, with which the
theme draws that client's sign-in page without identity-provider buttons.
New installs record v6. Existing installs keep their receipt and converge
read-only (login_presentation=pending_upgrade); the one-time upgrade client
moves v1–v5 to v6 and sends only those settings, so the realm's other
settings and the client's secret, redirects and other attributes stay as
they are. The bootstrap report addslogin_presentation(converged,
driftwith a warning, orpending_upgrade), which never blocks startup. A
Keycloak without the theme serves its built-in pages. The v6 receipt is a new
row, so an older image still reads its v5 receipt. On the theme's "Page has
expired" page, a sign-in step the browser requested twice resumes once per
tab by itself, and from the second time the page explains instead. -
The bundled Keycloak (the
standalone-ssooverlay and the Helmsso
template) no longer serves Keycloak's own client-registration endpoint
(KC_SPI_CLIENT_REGISTRATION_DEFAULT_ENABLED=false). That endpoint accepts
a whole client representation, including an authentication-flow override,
so a client registering itself could run a flow without the brokered-account
guard. Clients that register themselves, such as MCP clients, use the OpenID
Connect registration endpoint, which is unchanged and cannot set an
override. The bootstrap report addsnative_client_registration
(disabled,enabled, orunknown), read with one anonymous request whose
body is not JSON so it can register nothing;enabledandunknownare
logged as warnings and never block startup. -
The bundled Keycloak realm's sign-in flows refuse a realm password to an
account that arrived through an identity provider. Such an account could
set one through Keycloak'sUPDATE_PASSWORDaction (also the account
console's "set up password") and then sign in with it, without the
upstream, at the realm's own form (the one AKB'slocalprovider opens) or
at the password grant, and AKB accepted that form's token as theirs. Every
identity provider now grants the realm roleakb-brokered-accounton each
brokered sign-in, and the realm bindsakb browserandakb direct grant,
copies of Keycloak's built-in flows in which a holder of that role is denied
after the password step. The guard lives in these realm-bound flows; a
client given its own authentication-flow override does not use them.
Accounts without an identity-provider link, the product administrator
included, sign in as before; creating the password is not blocked, using it
is. New installs record abundled-keycloak-v5receipt. Existing installs
keep their receipt and converge read-only
(brokered_account_guard=pending_upgrade); the one-time upgrade client
moves a v1–v4 install to v5, adds the mapper to every existing provider,
and grants the role to the accounts each provider already links. Moving
from v4 leaves the event settings as they are. The upgrade stops before
changing anything if the realm binds a browser or direct-grant flow other
than Keycloak's built-in one or AKB's copy
(keycloak_authentication_flow_binding_unexpected). The v5 receipt is a new
row, so an older image still reads its v4 receipt after a rollback. The
bootstrap report addsbrokered_account_guard. On v5 the guard is a startup
gate: a realm whose bound flows no longer deny the role fails with
keycloak_brokered_account_guard_readback_failed, and one with an enabled
provider that does not grant it fails with
keycloak_identity_provider_guard_mapper_missing. Upgrade modes are now
namedupgrade-vN-to-v5, and a callback change on a v5 receipt
upgrade-v5-callback. Configuring or enabling a provider writes the mapper
when the realm has the role, and enabling fails closed when it cannot;
disabling is unaffected, and realms without the role are left alone. The
permanentakb-sso-managergains no authority. -
The bundled Keycloak realm now keeps seven days of user events: login and
broker outcomes, restarts of an expired login, and credential or broker-link
changes. New installs record abundled-keycloak-v4receipt with the events
on. Existing installs stay on v3 and keep converging read-only; supplying the
one-time upgrade client moves a v2 or v3 install to v4. The v4 receipt is a
new row, so rolling back to an older image still reads its v3 receipt. The
permanentakb-sso-managergains no events authority. The bootstrap report
addsrealm_events(converged,drift, orpending_upgrade); drift is
logged and never blocks startup. -
Settings → Security (sign out all sessions, delete account) is always
available according toauth_mode; theaccount_self_service_enabled
rollout flag is retired. Existing configs that still set the key keep
loading, and the value is ignored. Account deletion still requires a healthy
cleanup worker heartbeat and reportscleanup_unavailableotherwise. -
POST /api/v1/auth/registerrejects passwords shorter than 8 characters
with 422invalid_argument, matching the existing change-password minimum.
Registration and password change also reject passwords over 72 UTF-8 bytes
(the bcrypt limit) as client errors instead of failing with 500.
Search retrieval
- Scoped pgvector posting searches choose term-first, scope-first, or bounded
point lookups while retaining the same filters and exact sparse scores.
Explicit Native document scopes use separate indexed path and UUID lookups. - pgvector dense candidates are sorted by actual distance before rank fusion,
with iterative HNSW scans enabled for source-type-only filters too. search_retrieval_timeout_secsbounds pgvector pool acquisition, concurrent
retrieval, payload loading and cleanup (default 30 seconds). Healthy peer
results survive a timeout; cancellation drains queries without masking
authorization or schema failures. This is a retrieval budget, not an HTTP
request timeout.- Incomplete search responses keep available hits usable, distinguish an
incomplete empty response from no matches, and avoid definitive result counts.
Vault-member app installation status
- Added
GET /api/v1/apps/{app_id}/installations/{vault_id}/activefor Vault
owners and members with reader, writer, or admin access. It returns only the
canonical active boolean, uses the authenticated user identity, checks live
membership, and disables caching.
Installation execution
- A newly accepted
installorfreshcommand now persists one sealed,
single-installation rollout job and its target in the same transaction as the
command acknowledgement. The existing worker executes the schema plan, an
app-wide request skips installations that already have a queued target, and
a command cannot commit accepted without a job. The job records the
authenticated owner/admin command path.
This compatible patch adds no schema migration. Existing SSO receipts remain
unchanged unless the separate one-time upgrade workflow is run; Keycloak and
frontend image updates are outside this installation rollout.
Deployment verification
The backend installation executor is covered by all seven required CI checks, including real PostgreSQL tests and the app-control-plane shell E2E suite. The paired Reef fix is tracked in dnotitia/reef#522.
Existing Native installations retain their identity and initialization receipts. An API/worker image rollout does not perform the separately documented Keycloak receipt upgrade or deploy the frontend login theme.
Deployed API and worker source: 6382e9daecd11d949c1610eeaf4b21e84470e902. Immutable backend image: 192.168.110.11:5000/akb-backend@sha256:cc2d763b57d3c150226ab44375d76fc2ef0ef82a9284388bdccff23ad944399d. Both deployments passed rollout and readiness with existing resources/Native identity preserved. Production SSO remains enabled; authenticated MCP discovery passed 12/12 requests through an operator port-forward to one API pod; Kubernetes readback separately confirmed both API replicas ready. The local-login shell smoke is not applicable to this SSO deployment; the repository’s real Keycloak CI gate passed before release.