kanidm-setup, all the way: desk groups from the content, no prefix, onboarding that works, the first person, redaktør, and Gitea sign-in

The desk groups are read from the content's qualifies: and named as it
names them - this Kanidm is the vel's own - with the old tomtervel_*
groups renamed in place. The onboarding account manages every desk
group, since adding a member takes that right (measured: 404 without).
Sign-in scopes to idm_all_persons. SEED_ADMIN_EMAIL and
RESPONSIBLE_GROUP (redaktor) reach portal.env, and bootstrap no longer
drops the onboarding token when it rewrites portal.env. A second OAuth2
client lets redaktor sign in to prosjekt.klingenbergbygg.no; on the
Gitea host the script adds that sign-in source itself.

The login page's own name and logo need the admin account; the script
now says so rather than failing with 'Item not found'. .env.example
quotes SITE_NAME, which has a space and broke sourcing it.

Tested end to end against a local Kanidm 1.11.2, including a rerun and
a legacy tomtervel_kasserer with a member.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GT37Z1Xtfd9pUuQtMTg6Yt
This commit is contained in:
bl
2026-09-29 15:45:41 +02:00
co-authored by Claude Opus 5.5
parent 415dea7230
commit b653536391
5 changed files with 207 additions and 65 deletions
+35
View File
@@ -64,6 +64,36 @@ Then `sudo systemctl reload caddy`, point the content repo's `lint-and-reload`
reload step at `nats://127.0.0.1:4223`, and retire the old systemd portal:
`sudo systemctl disable --now app@tomtervel-portal`.
## Accounts, all the way
`kanidm-setup.sh` sets up everything portal needs from this Kanidm,
and is safe to rerun:
- **Desk groups, named as the content names them.** Read from every
`qualifies:` under `questions/` in the content repo, so the list
cannot drift from the pages. This Kanidm is the vel's own, so there is
no prefix: the board's group is `styret`. Groups from before are
renamed in place (`tomtervel_styret` → `styret`), members and all.
- **Sign-in.** The OAuth2 client's scope map is `idm_all_persons`:
everyone here is the vel's, and what they see is decided by their
desk groups in the `groups` claim.
- **Onboarding.** The `portal-onboarding` service account manages
every desk group, so an invite from a desk and a `grants:` can add
people to them. Its token goes into `portal.env`.
- **The first person in.** `SEED_ADMIN_EMAIL` in `.env`: at start,
portal invites them into the most privileged group (the board) and
mails the link, once. Everyone else they invite from their desk.
- **The people who ask the questions.** Everyone a page names as
`responsible` gets an account at start, a mail saying they are listed
as responsible for asking that question, and a place in
`RESPONSIBLE_GROUP` (`redaktor`). Signed in, they can suggest changes
to their own pages.
- **The project Gitea.** With `GITEA_URL` set, `redaktor` may sign in
to it with the same account: its own OAuth2 client, only for that
group. Run on the Gitea host, the script adds the sign-in source
itself (and requires the `redaktor` claim there too); elsewhere it
leaves the secret in `gitea-oauth.secret` and prints the one command.
## People and desks
Each group in the content (`qualifies:` under `questions/`) is a
@@ -168,6 +198,11 @@ older server does not have, so `system domain set-displayname` and
about versions. The CLI warns on every call; the warning is worth
reading.
The same "Item not found" also comes back when the versions do match
and the account is `idm_admin`: the instance's own name and logo are
system settings only `admin` may change. `kanidm-setup.sh` sets them
when an `admin` session exists and says so when it does not.
The host's CLI comes from pacman and moves on its own, so the image is
what to bump: `image: kanidm/server:<version>` in `compose.yml`, then
`podman compose up -d kanidm`.