Connexion unique
La connexion unique permet à un fournisseur d’identité (IdP) externe de décider qui peut se connecter à votre serveur Control Center. Deux protocoles sont pris en charge — SAML 2.0 et OpenID Connect — et tous deux aboutissent au même endroit : un identifiant d’appareil fraîchement émis, indiscernable d’une invitation ou d’un appairage par QR partout en aval.
La forme d’une connexion
Section intitulée « La forme d’une connexion »Les connexions SAML passent par le navigateur. L’IdP n’ouvre jamais de connexion vers votre serveur ; c’est le navigateur de l’utilisateur qui transporte tout :
browser ──> /saml/login ──> IdP ──POST SAMLResponse──> /saml/acs │ verify ▼ provision user (maybe) │ ▼ browser handoff: device PSK in the URL fragment (never a query parameter)Parce que c’est le navigateur qui fait le coursier, un serveur derrière un NAT fonctionne parfaitement pour les connexions : localhost, réseau local, Tailscale, VPN ou tunnel font tous l’affaire — seul le navigateur de l’utilisateur doit pouvoir joindre l’URL ACS. Le relais WebSocket utilisé par le contrôle à distance depuis un téléphone ne peut pas transporter l’aller-retour HTTP, et c’est pourquoi les points d’entrée SSO ciblent toujours l’origine HTTP du serveur.
OpenID Connect suit la même forme avec un aller-retour code d’autorisation + PKCE ; les claims sont lus sur le point de terminaison de jeton de l’émetteur via TLS, si bien que le navigateur ne fournit jamais la moindre donnée d’identité.
Les adaptateurs
Section intitulée « Les adaptateurs »Control Center répartit délibérément les responsabilités :
| Élément | Emplacement | Responsabilité |
|---|---|---|
cc_saml (natif) |
packages/cc_natives/native/saml/ |
Vérification XML-DSig, canonicalisation, validation du profil SAML — déléguées à la crate saml en Rust pur épinglée derrière une ABI C sans état |
SamlService / OidcService |
cc_server_core |
état de connexion (suivi des requêtes en attente, déduplication des rejeux), réglages de la politique de validation, l’appel de provisionnement partagé |
SsoProvisioner |
cc_server_core |
trouver ou créer l’utilisateur, épingler le sujet du fournisseur, accorder les adhésions selon la politique d’adhésion automatique |
ScimService |
cc_server_core |
l’interface de push SCIM 2.0 (cycle de vie provisionnement/déprovisionnement) |
SsoSettingsService |
cc_server_core |
les lignes de connexion enregistrées, la réapplication à chaud, le jeton SCIM |
Il n’existe délibérément aucun repli cryptographique SAML en pur Dart : le
XML-DSig et la canonicalisation écrits à la main sont précisément là où vivent
les vulnérabilités de contournement de signature, si bien qu’une bibliothèque
cc_saml manquante fait échouer à la fois la connexion SAML et le démarrage du
serveur. Le natif est sans état par conception — l’état inter-requêtes réside
dans les services Dart, à usage unique et de courte durée.
Ce que vérifie une connexion
Section intitulée « Ce que vérifie une connexion »Dans le natif vérifié et dans le service, dans l’ordre :
- la signature de l’assertion (toujours exigée ; celle de l’enveloppe de réponse est facultative selon la configuration) — structurellement résistante au contournement de signature, car la charge utile validée est liée à l’élément vérifié,
- l’émetteur correspond à l’IdP configuré,
- l’audience désigne ce fournisseur de service,
- la destination est bien notre URL ACS,
InResponseTocorrespond à une AuthnRequest en attente que nous avons émise (les réponses non sollicitées, initiées par l’IdP, sont désactivées par défaut),- les fenêtres de durée de vie tiennent dans le décalage d’horloge toléré (90 s par défaut) et
- l’identifiant d’assertion n’a jamais été vu auparavant (cache anti-rejeu).
Les échecs reviennent sous forme de codes typés — signature, expired, audience, destination, issuer, request-match — et les points de terminaison répondent par des erreurs génériques, de sorte qu’un attaquant n’apprend rien sur la raison de l’échec d’une falsification.
Comptes et épinglage du sujet
Section intitulée « Comptes et épinglage du sujet »La première connexion SSO épingle sur le compte le sujet immuable du fournisseur
(issuer, plus le NameID SAML / le sub OIDC, ou l’externalId SCIM). À partir
de là, c’est le sujet — et non l’adresse e-mail — qui identifie la connexion. Si
quelqu’un d’autre présente ensuite la même adresse e-mail depuis le même IdP ou
un autre, le compte épinglé le refuse. C’est ce qui empêche une adresse e-mail
recyclée chez un fournisseur de se transformer en prise de contrôle de compte.
Provisionnement et déprovisionnement
Section intitulée « Provisionnement et déprovisionnement »Le provisionnement JIT a lieu à la connexion (SsoProvisioner). SCIM est une
surface de push distincte (ScimService) qui épingle le même sujet sur la ligne
utilisateur ; elle n’accorde pas d’adhésion à un espace de travail. Le
déprovisionnement — active: false ou DELETE via SCIM — est refusé si le
compte est propriétaire d’un espace de travail (transférez d’abord). Sinon, il
révoque d’abord chaque identifiant d’appareil (les sessions tombent en quelques
secondes via la surveillance des appareils), retire toutes les adhésions aux
espaces de travail et marque le compte comme désactivé. La ligne utilisateur
survit : l’attribution est permanente. La réactivation restaure la connexion
mais ne réaccorde jamais les adhésions.
Ce qui reste en dehors
Section intitulée « Ce qui reste en dehors »- La correspondance groupe→rôle se fait à la connexion, à partir des attributs SAML / claims OIDC — les groupes poussés par SCIM ne sont pas stockés.
- Le rôle de propriétaire est inaccessible depuis le SSO — ni comme rôle par défaut, ni par une correspondance de groupe.
- Le relais WebSocket n’est jamais un canal SSO ; les téléphones qui ne joignent le serveur que par le relais ne peuvent pas effectuer d’aller-retour navigateur contre lui.