# Per-system SSO + API key details (verified 2026-09-07/08 unless noted) ## GLPI (cmdb.knownelement.com) — SSO VERIFIED WORKING - SSO: "Login with KNEL Cloud" = plugin route `/plugins/singlesignon/front/callback.php/provider/1?remember=1` → Cloudron OIDC → auto-provision. - The login page defaults to whichever tab was last toggled ("Use GLPI login form" / "Use Single Sign-on"); a hidden `noAUTO=1` input forces the local form — irrelevant under Cloudron-only policy, useful to recognize. - API: GLPI 11 is OAuth/token-based. The legacy REST at `/apirest.php/initSession` exists: password login is DISABLED (400); user_token auth exists but the tokens in `creds/glpi` / `creds/mglpi` are STALE (401 ERROR_GLPI_LOGIN_USER_TOKEN). The app token in `creds/glpi` password field IS accepted (used as `App-Token` header). - Per-user API token: My account (self-service) after SSO provisioning. Pair with the app token: `GET /apirest.php/initSession` with headers `App-Token: ` + `Authorization: user_token `. - Local web login as `glpi` super-admin hits a 6-digit TOTP at `/MFA/Prompt` whose secret is not stored anywhere — do not rely on the admin UI; the SSO path makes it unnecessary. ## Gitea (git.knownelement.com) - SSO: `/user/oauth2/cloudron` (button "Sign in with …" on the login page). - Standalone install behind nginx on the shared box — local accounts exist from the August batch; Cloudron-only policy means new identities use SSO and legacy ones migrate. - API: tokens via `POST /api/v1/users//tokens` REQUIRE basic auth AS that user (admin tokens cannot mint for others; there is no `/admin/users//tokens` route; `Sudo` header needs a real site admin). - Token auth against `/api/v1/user`: the JSON has `login`; admin-ness shows in `site_admin` (absent = not admin; do not misread null as false). - KNOWN BROKEN (2026-09-07/08): receive-pack 500s during the box incident — RESOLVED after the 09-08 repair (pushes verified). If pushes 500 again, check the shared box first (see incident-log.md). ## Discourse (community.turnsys.com) - SSO: `/auth/openid_connect` — a bare GET returns 403 (CSRF-gated); that is NORMAL and means the route exists. Complete the flow from the login page button or with a session + CSRF token. - The login page is an Ember SPA: server-rendered HTML shows no SSO markers, which fooled one audit (2026-09-07) into "no SSO" — wrong. Check routes, not page source. - API: user API keys (User-Api-Key header) minted via the user-approval flow; admin Api-Key + Api-Username impersonation needs an admin key. The vault's `creds/discourse` NOTE says its keys are NOT admin (they are also not hex — do not assume key format). `creds/vptechops-discourse` holds a WORKING user key (user `vptechopsvptechops`) — #933's "dead key" note is wrong. ## Redmine (projects.knownelement.com) - SSO: "Continue with KNEL Cloud" button POSTs/GETs `/oauth`. KNOWN BROKEN: `/oauth` 302-bounces straight back to /login with no provider redirect — verified 2026-09-07 AND 2026-09-08 (IdP healthy both times), so it is a Redmine plugin configuration issue, NOT the IdP. Retest before relying on it; until fixed, Redmine accounts cannot be created via SSO. - API keys: `GET /users/current.json` (session or basic auth) returns the user's `api_key`; X-Redmine-API-Key header for calls. Vault convention: the API key is stored in the item's password field. - Admin surface: `/users.json` lists users (admin only — 403 otherwise). Every admin candidate tested in the vault so far is NON-admin (they are all the founder's personal accounts anyway — RESTRICTED). ## Shared infrastructure hazard Gitea, Redmine, Discourse, GLPI, the pwvault, and the my. vhost all run on ONE box (152.53.37.179 = mail.knownelement.com). Symptoms there cluster: when several systems misbehave at once, suspect the box (see incident-log.md), file/update one ticket, and do not burn hours debugging four clients.