Siirry sisältöön

B2B-organisaatiot ja roolit

tunnuspalvelu tukee B2B-organisaatiomallia yhden käyttäjän sijaan yhden organisaation (yrityksen, tiimin) valtuuttamiseen. Kaikki tämä on tenant-scopattua — yksi organisaatio ei voi ulottua usean tenantin yli.

Organisaatio (org)
└─ Jäsenet (org_members) — kiinteä rooli: owner | admin | member
└─ Ryhmät (org_groups) — nimettyjä alaryhmiä, ei omaa roolia
└─ Ryhmän jäsenet — pelkkä jäsenyys, edellyttää org-jäsenyyttä

Tämän lisäksi tenantti voi määritellä omia mukautettuja rooleja (esim. billing_admin, developer), jotka voidaan liittää käyttäjään joko globaalisti (koko tenantin laajuisesti) tai yhteen organisaatioon scopattuna. Tämä on erillinen järjestelmä kiinteästä owner/admin/member-roolista — molemmat voivat olla käytössä samanaikaisesti.

Ryhmäjäsenyys edellyttää org-jäsenyyttä: jos käyttäjä poistetaan organisaatiosta, hänet poistetaan automaattisesti myös kaikista sen ryhmistä.

Scope Claim ID tokenissa Sisältö
orgs orgs [{id, name, role, roles?, groups?}] — organisaatiojäsenyydet, kiinteä rooli ja (jos roles-scope mukana) org-scopatut mukautetut roolit ja ryhmät
groups groups ["org:{uuid}:{role}", ...] — litteä lista, sopii yksinkertaiseen includes()-tarkistukseen
roles roles Globaalit mukautetut roolit, esim. ["billing_admin"]. Org-scopatut mukautetut roolit näkyvät orgs[*].roles-kentässä, jos sekä roles että orgs on pyydetty
"orgs": [
{
"id": "5e3b1a2c-...",
"name": "Esimerkki Oy",
"role": "admin",
"roles": ["project_manager"],
"groups": ["laskuttajat"]
}
]
"groups": ["org:5e3b1a2c-...:admin"]

role-arvo on aina yksi kolmesta: owner, admin tai member. roles- ja groups-kentät org-tietueen sisällä puuttuvat kokonaan (eivät ole tyhjä lista) kun käyttäjällä ei ole niitä kyseisessä organisaatiossa. Täysi esimerkki kaikilla scopeilla: Tokenit ja claimit.

// TypeScript — käyttäen groups-claimia (yksinkertaisin)
const isOrgAdmin = (claims.groups ?? []).some((g) => g.endsWith(":admin"));
const isMemberOf = (orgId: string) =>
(claims.groups ?? []).some((g) => g.startsWith(`org:${orgId}:`));
// Mukautetun roolin tarkistus (globaali)
const isBillingAdmin = (claims.roles ?? []).includes("billing_admin");
// Mukautetun roolin tarkistus (org-scopattu)
const hasOrgRole = (orgId: string, roleName: string) =>
(claims.orgs ?? []).some(
(o) => o.id === orgId && (o.roles ?? []).includes(roleName),
);
# Python
is_org_admin = any(g.endswith(":admin") for g in claims.get("groups", []))
is_member_of = lambda org_id: any(
g.startswith(f"org:{org_id}:") for g in claims.get("groups", [])
)

Käytä groups-scopea, kun tarvitset vain nopean “onko jäsen / onko admin” -tarkistuksen. Käytä orgs-scopea, kun tarvitset organisaation nimen, useamman organisaation samanaikaisesti tai mukautettuja rooleja.

Uuden jäsenen lisääminen organisaatioon tapahtuu joko suoraan (jos käyttäjä on jo olemassa tunnuspalvelussa) tai kutsun kautta (jos ei ole). Kutsu sisältää kertakäyttöisen tokenin ja oletusarvoisesti 7 vuorokauden voimassaolon. tunnuspalvelu ei lähetä itse kutsuviestiä — kutsuvan palvelun vastuulla on toimittaa kutsulinkki (esim. sähköpostitse) käyttäen palautettua token-kenttää.

Kutsujen ja jäsenten hallinta ohjelmallisesti: ks. Machine API — Organisaatiot. Kutsujen ja jäsenten hallinta admin-paneelissa: ks. Organisaatiot hallinnassa.