Gå til innholdet

Enkel pålogging

Enkel pålogging lar en ekstern identitetsleverandør (IdP) avgjøre hvem som får logge inn på Control Center-serveren din. To protokoller støttes — SAML 2.0 og OpenID Connect — og begge ender på samme sted: en nyutstedt enhetslegitimasjon som er umulig å skille fra en invitasjon eller QR-paring nedstrøms.

SAML-innlogginger er nettleserformidlet. IdP-en åpner aldri en tilkobling til serveren din; brukerens nettleser frakter alt:

browser ──> /saml/login ──> IdP ──POST SAMLResponse──> /saml/acs
│ verify
▼
provision user (maybe)
│
▼
browser handoff: device PSK in the URL
fragment (never a query parameter)

Fordi nettleseren er kurer, fungerer en server bak NAT helt fint for innlogginger: localhost, LAN, Tailscale, VPN eller en tunnel duger alle — det er bare brukerens nettleser som må nå ACS-URL-en. WebSocket-reléet som telefonfjernstyringen bruker, kan ikke frakte HTTP-rundturen, og derfor retter SSO-inngangspunktene seg alltid mot serverens HTTP-origin.

OpenID Connect følger samme form med en autorisasjonskode- + PKCE-rundtur; claims leses fra utstederens token-endepunkt over TLS, så nettleseren leverer aldri identitetsdata i det hele tatt.

Control Center deler ansvaret med vilje:

Del Hvor Eier
cc_saml native packages/cc_natives/native/saml/ XML-DSig-verifisering, kanonisering, SAML-profilvalidering — delegert til den fastpinnede saml-craten i ren Rust bak en tilstandsløs C-ABI
SamlService / OidcService cc_server_core innloggingstilstand (sporing av ventende forespørsler, deduplisering ved replay), brytere for valideringspolicy, det delte provisjoneringskallet
SsoProvisioner cc_server_core finn-eller-opprett brukeren, fest leverandørens subjekt, gi medlemskap etter policyen for automatisk medlemskap
ScimService cc_server_core pushflaten for SCIM 2.0 (livssyklus for provisjonering/deprovisjonering)
SsoSettingsService cc_server_core de lagrede tilkoblingsradene, re-anvendelse i sanntid, SCIM-tokenet

Det finnes bevisst ingen kryptografisk SAML-reservevei i ren Dart: håndrullert XML-DSig/kanonisering er nøyaktig der sårbarheter for signaturinnpakking holder til, så et manglende cc_saml-bibliotek avviser både SAML-innlogging og serveroppstart. Native-modulen er tilstandsløs med vilje — tilstand på tvers av forespørsler ligger i Dart-tjenestene, til engangsbruk og kortvarig.

I den verifiserte native-modulen og tjenesten, i denne rekkefølgen:

  1. Signaturen til assertionen (alltid påkrevd; svarkonvoluttens er valgfri per konfigurasjon) — strukturelt motstandsdyktig mot signaturinnpakking fordi den validerte nyttelasten er bundet til det verifiserte elementet,
  2. utstederen samsvarer med den konfigurerte IdP-en,
  3. audience navngir denne tjenesteleverandøren,
  4. destinasjonen er vår ACS-URL,
  5. InResponseTo samsvarer med en ventende AuthnRequest vi utstedte (uoppfordrede, IdP-initierte svar er av som standard),
  6. levetidsvinduene holder seg innenfor klokkeavviket (standard 90 s) og
  7. assertion-id-en er aldri sett før (replay-cache).

Feil kommer tilbake som typede koder — signature, expired, audience, destination, issuer, request-match — og endepunktene svarer med generiske feil, så en angriper ikke lærer noe om hvorfor en forfalskning mislyktes.

Den første SSO-innloggingen fester leverandørens uforanderlige subjekt (issuer pluss SAML NameID / OIDC sub, eller SCIM externalId) til kontoen. Fra da av er det subjektet — ikke e-postadressen — som identifiserer innloggingen. Hvis noen andre senere oppgir den samme e-postadressen fra samme eller en annen IdP, avviser den festede kontoen dem. Det er dette som hindrer at en resirkulert e-postadresse hos en leverandør blir til en kontoovertakelse.

JIT-provisjonering skjer ved innlogging (SsoProvisioner). SCIM er en separat pushflate (ScimService) som fester det samme subjektet på brukerraden; den gir ikke medlemskap i arbeidsområder. Deprovisjonering — SCIM active: false eller DELETE — avvises hvis kontoen er eier av et arbeidsområde (overfør først). Ellers tilbakekaller den først all enhetslegitimasjon (øktene faller innen sekunder via enhetsvakten), fjerner alle medlemskap i arbeidsområder og merker kontoen som deaktivert. Brukerraden består: attribusjonen er permanent. Reaktivering gjenoppretter innlogging, men gir aldri medlemskapene tilbake.

  • Gruppe→rolle-tilordning skjer ved innlogging fra SAML-attributtene / OIDC-claimene — grupper som pushes via SCIM, lagres ikke.
  • Eierrollen er ikke oppnåelig via SSO — verken som standardrolle eller gjennom en gruppetilordning.
  • WebSocket-reléet er aldri en SSO-kanal; telefoner som bare når serveren gjennom reléet, kan ikke fullføre en nettleserrundtur mot den.