Repository navigation
v0.28.0
@kanzo-tech/auth
Roles inside an organization come from organization[alias].resource_access[clientId].roles, and group paths are no longer read.
session.organizations[n].rolesis now what Keycloak writes inside each organization entry: the
roles an organization's administrator mapped onto the groups the person is in, with composite
roles expanded. The realm needs the Organization Group Membership mapper on theorganization
scope withaddGroupRoleMappingson, which needs Keycloak 26.7 or later; without it every
organization reads as a membership holding no roles.services/authin this repository already
configures it.- Group names are not read at all, so a group called
/board/editorgrants nothing any more. If
your realm named groups/<client>/<role>, map the client role onto the group instead (the
console, orservices/auth/scripts/map-group-role.sh ALIAS GROUP CLIENT ROLE); the group can then
be called anything. roleFromGroupPathis removed. Delete any call to it:organizationOf(session, alias)?.roles
is already the roles for your client.- An organization's roles are still not merged into
session.roles. - If you wrote a hierarchy out at the call site (
can(s, "owner", org) || can(s, "member", org)),
declare it as composite roles in your client registration instead and ask for the lowest role
once: the token carries the expanded set.
The realm this package reads now ships beside it, in services/auth. Keycloak 26.8 with the
platform realm as code: one realm, organizations as tenants, and the claim mappers set so that an
application's roles in an organization arrive as organization[alias].resource_access[clientId].roles,
composites expanded, on both tokens. docker compose up -d --wait in that directory gives you a
working login; scripts/verify.sh checks the claims on a live token.
Register your application from your own repository with the modules/app Terraform module — client,
audience and roles, a hierarchy declared once as composites — pinned to the release you build against:
source = "git::https://github.com/Kanzo-Tech/ui.git//services/auth/modules/app?ref=v0.28.0"and map your roles onto an organization's groups with scripts/map-group-role.sh. Nothing in the
realm names an application.
@kanzo-tech/graph
GraphStatus says where the graph is in one word, and GraphCounts stops saying "drawn".
- New part
GraphStatus: a badge with a status dot that reads Loading, Laying out 42%, Ready or
Failed. It folds the data'sstatusand the layout'smotionandprogresstogether, so a
running layout over a loaded graph no longer shows as "idle". If your footer drew its own badge
fromuseGraphState((s) => s.status), delete it and render<GraphStatus />. The word is a polite
live region; the badge isaria-busywhile loading or laying out. GraphCountsnow reads "5K nodes · 8K edges" with no filter and "1.2K of 5K nodes match · 3K edges"
under the page's filter, instead of "1.2K of 5K nodes drawn · 8K edges". A test or a snapshot that
matched the old sentence needs the new one. Thespinnerprop is gone: remove it, and put
<GraphStatus />beside the counts where you relied on the spinner.GraphStatehas a new field,matching: how many vertices of the corpus the page's filter keeps,
ornullwhen nothing is filtered.- The type
GraphStatusis renamedDataStatus, because the part takes the name. Edit
import type { GraphStatus }toimport type { DataStatus }; the values are unchanged.
@kanzo-tech/llm
The gateway createGateway talks to now ships beside it, in services/ai. LiteLLM serving the
chat and complete aliases: docker compose up -d --wait there runs both on open models through
Docker Model Runner, offline. For a deployment, modules/gateway runs it as Swarm services with your
own profile (which upstream answers each alias) and keys, and modules/team gives each of your
tenants a budget and the key its server presents.