skills: agent-provisioning - codified identity stand-up workflow
Policy rulings (#942): unique passwords, Cloudron-only SSO accounts, no reachableceo credentials, TOTP seeds MUST be captured to the vault. Cloudron admin API wrapper, cookie-jar OIDC login, RFC-6238-tested TOTP helper, per-system SSO/API references, incident log.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# Cloudron admin API + OIDC (verified 2026-09-08)
|
||||
|
||||
## Instance
|
||||
|
||||
- Dashboard: `https://my.knownelement.com` (admin surface; this host also
|
||||
fronts the org's public vhosts — it is NOT the tailscale-only control box).
|
||||
- API token: vault item `creds/cloudron`, password field, 64 chars, service
|
||||
user `api-token`. Verified: reads full user directory.
|
||||
|
||||
## Routes (this is a newer Cloudron — older route knowledge may not apply)
|
||||
|
||||
- Users are addressed by `uid-<uuid>`, never username.
|
||||
`GET /api/v1/users?limit=100` → list; `GET /api/v1/users/<uid>` → object
|
||||
(`twoFactorAuthenticationEnabled` is null/absent on objects even when
|
||||
enforced — the OIDC interaction is the source of truth).
|
||||
- There is NO `POST /api/v1/login`. Dashboard auth is its own OIDC browser
|
||||
flow; the SPA bundle (as of 2026-09-08) contains no login route.
|
||||
- There is NO admin route to reset another user's 2FA (PUT/PATCH/DELETE on
|
||||
`/users/<uid>` 2FA variants all 404; the dashboard UI only offers profile
|
||||
self-service enrollment). Consequence: TOTP seeds not captured at
|
||||
enrollment are unrecoverable without the founder.
|
||||
- Other useful routes seen in the SPA bundle: `/api/v1/tokens`,
|
||||
`/api/v1/oidc/clients`, `/api/v1/groups`, `/api/v1/eventlog`,
|
||||
`/api/v1/app_passwords`. Verify behavior at runtime before relying on a
|
||||
specific payload shape.
|
||||
|
||||
## OIDC interaction login (how identity SSO works)
|
||||
|
||||
The GLPI/Gitea/Discourse/Redmine SSO flows all redirect here:
|
||||
|
||||
1. `GET <app SSO start point>` → 302 to
|
||||
`https://my.knownelement.com/openid/interaction/<uid>` (Cloudron runs a
|
||||
node-oidc-provider at `/openid`). Cookies matter — keep a cookie jar.
|
||||
2. `POST /openid/interaction/<uid>/login` with JSON
|
||||
`{"username": "<login>", "password": "<unique password>"}`.
|
||||
- Field name is **`username`** — `login` returns
|
||||
`"A username must be non-empty string"` (400).
|
||||
- Success → `{"redirectTo": "..."}` (or
|
||||
`{"twoFactorRequired":true,"totpRequired":true}` if 2FA is enabled).
|
||||
- Wrong credentials → 401 `{"status":"Unauthorized","message":"Username
|
||||
and password does not match"}`.
|
||||
3. `GET` the `redirectTo` (same cookie jar) → completes at the app.
|
||||
|
||||
Email-style usernames work (`tsgstaff-coo@turnsys.com`); bare usernames also
|
||||
exist (`coo`). Identity emails follow `tsgstaff-<login>@turnsys.com`.
|
||||
|
||||
## 2FA
|
||||
|
||||
- TOTP enforced per user at the interaction step
|
||||
(`twoFactorRequired`/`totpRequired` in the login response).
|
||||
- Enrollment is profile self-service ONLY. Capture the base32 seed into the
|
||||
vault (`sm setfield "<login> Cloudron" totp_seed <seed>`) at enrollment —
|
||||
there is no admin reset and no recovery path.
|
||||
- Policy RULED (founder, 2026-09-08): TOTP seeds MUST be stored in Bitwarden.
|
||||
Enroll 2FA only when the seed is being captured to the vault item in the
|
||||
same step. Legacy identities whose seeds were never captured (the whole
|
||||
August batch) are reset-on-sight candidates: founder clears 2FA or hands
|
||||
over the seed, then re-enroll with capture.
|
||||
|
||||
---
|
||||
|
||||
**Records:** Redmine #942 — https://projects.knownelement.com/issues/942 · Discourse docs home: https://community.turnsys.com (skill topic pending admin-key provisioning, tracked on #942)
|
||||
Reference in New Issue
Block a user