Überblick — was es leistet
Rollen und Teams sind Informationsbezeichnungen zur Einordnung von Personen. Das einzige, was den Zugriff auf Ansichten und Aktionen öffnet, ist die Stufe (user_level). Was eine Benutzerin oder ein Benutzer sehen darf und was gespeichert oder gelöscht werden darf, entscheidet zu 100 % die Stufe; Rollen („DBA“, „DevOps“, „Sicherheit“) und Teams („Infra-Team“, „Security-Team“) sind Anzeige- und Organisations-Tags, die keinerlei Berechtigungen erteilen.
Das hält das Berechtigungsmodell einfach. Um jemandem Administratorrechte zu geben, erhöhen Sie die Stufe — Sie ändern nicht die Rolle. Einen Benutzer mit „Sicherheit“ zu kennzeichnen öffnet die Sicherheitsansichten nicht; seine Stufe muss Mitarbeitende (5) oder höher sein.
Dieser Artikel behandelt drei Dinge:
- Rollen (
infr_role) — sechs Tätigkeitsbezeichnungen (DBA, DevOps, Sicherheit, Administrator, Mitarbeitende, Entwickler). - Teams (
infr_team) — Organisationseinheiten, genutzt für die Zugehörigkeit von Benutzern und die Verantwortung für Assets. - Die Verantwortlich-Auswahl — ein kombiniertes Auswahlmenü, mit dem sich entweder ein Benutzer oder ein Team zuweisen lässt, mit
App\Support\Ownersals einziger Quelle der Wahrheit. Das Feld „Verantwortlich“ bei Instanzen, Hardware und Speicher verwendet sie.
Zugriffssteuerung = nur die Stufe (
user_level). Rollen und Teams öffnen programmatisch keine Berechtigungen. Zum Stufensystem siehe Stufen verstehen (RBAC).
Wann Sie es verwenden
- Beim Onboarding einer neuen Person, um Tätigkeit (Rolle) und Zugehörigkeit (Team) zu kennzeichnen.
- Bei einer Reorganisation — ein Team anlegen oder dessen Leitung wechseln.
- Um Server-, Hardware- oder Speicher-Assets eine verantwortliche Person oder ein verantwortliches Team zuzuweisen, damit „wer ist dafür zuständig“ eindeutig ist.
- Für Audit und Übergabe: nachschlagen, „wer für dieses Asset verantwortlich ist“.
Aufbau
/admin/users (Verwaltung ▸ Benutzer und Rollen) hat zwei Registerkarten.
| Registerkarte | Inhalt |
|---|---|
| Benutzer | Benutzerliste (Login-ID · Name · E-Mail · Rolle · Team · Stufe · Status · zuletzt aktiv) + CRUD im Dialog |
| Teams | Teamliste (Name · Farbe · Leitung · Beschreibung · Mitgliederzahl) + CRUD im Dialog |
Der Bearbeitungsdialog für Benutzer enthält Auswahlfelder für Stufe / Rolle / Team, gefolgt von diesem Hinweis:
Die Stufe regelt den Zugriff — Demo (lesen), Mitarbeitende (bedienen), Admin (alles). Die Rolle ist nur ein Anzeigetext.
Verwendung
Rollen — Tätigkeitsbezeichnungen
Der Rollenstamm umfasst sechs Einträge, die InfrRoleSeeder idempotent anhand von key per Upsert schreibt.
| key | Bezeichnung | Farb-Token | seq |
|---|---|---|---|
dba |
DBA | info | 10 |
devops |
DevOps | accent | 20 |
security |
Sicherheit | crit | 30 |
admin |
Administrator | warn | 40 |
staff |
Mitarbeitende | muted | 50 |
developer |
Entwickler | good | 60 |
- Ein Benutzer hat höchstens eine Rolle (
users.role_id, nullable). Sie darf leer bleiben. - Rollen erscheinen ausschließlich als Bezeichnung und Farbe im Benutzermenü der Kopfleiste sowie als Badges in Listen.
- Die angezeigte Bezeichnung löst
App\Support\RolePolicy::roleLabel($roleId)mit einem 60-Sekunden-Cache auf (rufen Sie nach ÄnderungenRolePolicy::flush()auf).
Die Rolle
admin(Bezeichnung „Administrator“) hat nichts mit der Administratorstufe (10) zu tun. Eine Rolle ist nur eine Bezeichnung: Ein Benutzer mit der Rolle „Administrator“, aber der Stufe Demo (1), kann nichts speichern. Umgekehrt verfügt ein Administrator der Stufe 10 auch mit leerer Rolle über die vollständige Verwaltung.
Teams — Organisationseinheiten
Teams lassen sich in der Registerkarte Teams frei per CRUD verwalten. Die vier Seed-Teams:
| Name | Farbe | Beschreibung |
|---|---|---|
| Infra-Team | accent | Server-, Netzwerk- und Speicherbetrieb |
| Security-Team | crit | Erkennung · Reaktion · Sperrung |
| Dev-Team | good | Serviceentwicklung · Deployment |
| DBA-Team | info | Datenbankbetrieb · Tuning |
Felder der Teambearbeitung:
| Feld | Bedeutung |
|---|---|
Name (name) |
Pflichtfeld. Teamname |
Farbe (color) |
Farbton des Badges (accent/crit/good/info/muted …) |
Leitung (lead_user_id) |
Ein Benutzer (optional) |
Beschreibung (description) |
Freitext |
Aktiv (is_active) |
Inaktive Teams werden in der Verantwortlich-Auswahl ausgeblendet |
- Ein Benutzer gehört höchstens einem Team an (
users.team_id, nullable). - Beim Löschen eines Teams: Die
team_idder Mitglieder dieses Teams wird aufnullgesetzt (die Benutzer bleiben bestehen, sind nun nicht zugeordnet). Assets, die das Team überowner_type='team'referenzierten, sind eine eigene Angelegenheit — die Assets selbst werden also nicht gelöscht.
Die Verantwortlich-Auswahl — Benutzer und Teams kombiniert
Assets (Serverinstanzen, Hardware, Speicher) besitzen ein Feld „Verantwortlich“, das entweder eine Person oder ein Team enthalten darf. Die Regeln dieser kombinierten Auswahl liegen in App\Support\Owners (der SOT).
Speicherform = zwei Spalten
Die Asset-Tabelle speichert die Verantwortung in zwei Spalten.
| Spalte | Bedeutung |
|---|---|
owner_id |
Ganzzahliger Primärschlüssel eines Benutzers oder eines Teams |
owner_type |
'user' oder 'team' |
Austauschform im Frontend = eine einzelne ref-Zeichenkette
Der Browser (Formulare, Filter) tauscht owner_type und owner_id als eine Zeichenkette aus.
user:5 → user id 5
team:3 → team id 3
Die Bootstrap-Optionen (Owners::options()) liefern die beiden Gruppen für das optgroup-Rendering zurück (20-Sekunden-Cache). Geschlossene Benutzer (is_close=1) und inaktive Teams (is_active=0) werden ausgeschlossen.
{
"users": [ { "ref": "user:5", "id": 5, "name": "Jane Doe" } ],
"teams": [ { "ref": "team:3", "id": 3, "name": "Infra Team" } ]
}
Zerlegen / Zusammensetzen auf Serverseite
| Helfer | Verhalten |
|---|---|
Owners::split($ref) |
"user:5" → ['user', 5]. Fehlerhaftes Format → ['user', 0] (= nicht zugeordnet) |
Owners::ref($ownerId, $ownerType) |
(5, 'user') → "user:5". Leere ownerId → null |
Owners::resolveName($ownerId, $ownerType) |
Anzeigename für Karten und Listen (null, wenn keiner vorhanden, 20-Sekunden-Cache) |
Owners::flush() |
Cache nach Benutzer- oder Teamänderungen invalidieren |
Der Speicher-Controller der Instanzen macht beispielsweise Folgendes:
// ref der Verantwortung ("user:5"/"team:3") → owner_id + owner_type
[$ownerType, $ownerId] = Owners::split($request->input('owner_ref'));
$payload['owner_id'] = $ownerId ?: null;
$payload['owner_type'] = $ownerId ? $ownerType : 'user'; // Standard 'user', wenn nicht gesetzt
Dieselbe ref wird auch beim Filtern nach Verantwortung verwendet — die Listenabfrage zerlegt den Parameter owner (user:5/team:3) mit split() und schränkt auf WHERE owner_id = ? AND owner_type = ? ein.
Die Verantwortlich-Auswahl wird auf den Asset-Ansichten Instanzen, Hardware und Speicher und Dateien identisch wiederverwendet. Ein Team als Verantwortlichen einzutragen stellt das gesamte Team in die Verantwortung (robust gegenüber dem Weggang einer einzelnen Person).
Avatar · Initialen · Farbe
Der neben einer Bezeichnung angezeigte Avatar wird von RolePolicy aus dem Namen erzeugt.
- Initialen (
initials): CJK/Koreanisch → erstes Zeichen; lateinische Namen → erster Buchstabe des ersten und des letzten Wortes (2 Zeichen). - Farbton (
hue):crc32(name) % 360für einen stabilen HSL-Hintergrund. - Stufen-Farbton (
tierTone): Administrator (≥10) = crit · Mitarbeitende/Bedienung (≥2) = accent · Demo = muted.
Datenquellen
| Tabelle | Zweck |
|---|---|
infr_role |
Rollenstamm (6 Informationsbezeichnungen) — key·name·color·seq·is_active |
infr_team |
Teamstamm — name·color·lead_user_id·description·is_active·seq |
users |
Benutzer — user_level (entscheidet über den Zugriff), role_id (nullable), team_id (nullable) |
| Asset-Tabellen | Verantwortung gespeichert als die zwei Spalten owner_id + owner_type (user/team) (Instanzen/Hardware/Speicher usw.) |
SOT-Helfer:
App\Support\Owners— kombinierte Verantwortlich-Auswahl (options/split/ref/resolveName/flush).App\Support\RolePolicy— Stufenbezeichnungen und -töne, Rollenbezeichnungen (60-Sekunden-Cache), Avatar-Initialen und -Farbe.
Zugriff
- Der Zugang zur gesamten Ansicht ist Administratoren vorbehalten.
/admin/*wird durch die Gruppen-Middlewareinfr.level:10geschützt, undUserController/TeamControllerprüfen selbst noch einmal dasuser_level >= 10der Sitzung (RolePolicy::ADMIN). Demo (1) und Mitarbeitende (5) erhalten einen 403. - Stufenschwellen (zur Orientierung): Schreiben ≥ 2 (
RolePolicy::WRITE, blockiert Demo) · Verwalten ≥ 10 (ADMIN) · Entwicklung/Beobachtbarkeit ≥ 9 (DEV, schließt Administrator 10 ein). - Beim Speichern eines Benutzers ist
user_levelauf einen der Werte1,5,10beschränkt. - Jede Benutzer- oder Teamänderung wird in
infr_audit_logauditiert (team.create/team.update/team.delete, Speichern/Löschen von Benutzern usw.).
Schutzmechanismen (Schutz des letzten Administrators)
| Situation | Ergebnis |
|---|---|
| Den letzten aktiven Administrator herabstufen / deaktivieren / löschen | Abgelehnt — „Der letzte aktive Administrator kann nicht herabgestuft, deaktiviert oder gelöscht werden.“ |
| Die eigene Administratorstufe senken oder deaktivieren | Abgelehnt — „Sie können Ihren eigenen Administratorzugriff nicht herabstufen oder deaktivieren.“ |
| Sich selbst löschen | Abgelehnt — „Sie können sich nicht selbst löschen.“ |
| Login-ID bereits vergeben | Abgelehnt — „Diese Login-ID ist bereits vergeben.“ |
Fehlersuche und FAQ
F. Ich habe jemandem die Rolle „Sicherheit“ gegeben, aber die Sicherheitsansichten öffnen sich nicht. Rollen sind Bezeichnungen; sie öffnen keine Berechtigungen. Die Sicherheitsansichten (überwiegend lesend) benötigen eine Stufe — heben Sie die Person auf Mitarbeitende (5) oder höher an. Siehe RBAC-Stufen.
F. Ein Benutzer oder Team fehlt im Auswahlmenü für die Verantwortung.
Geschlossene Benutzer (is_close=1) und inaktive Teams (is_active=0) werden aus der Auswahl ausgeschlossen. Aktivieren Sie den Benutzer bzw. das Team erneut, oder warten Sie bei veralteter Liste den Ablauf des 20-Sekunden-Caches ab (Owners::flush() invalidiert ihn sofort).
F. Verschwinden die Personen, wenn ich ein Team lösche?
Nein. Die Benutzer bleiben bestehen; lediglich ihre team_id wird null (nicht zugeordnet). Die owner_type='team'-Referenz eines Assets ist davon unabhängig, das Asset wird also ebenfalls nicht gelöscht (nur seine Verantwortungsanzeige bleibt leer).
F. Ich habe eine Verantwortung gespeichert, es wird aber kein Name angezeigt.
resolveName() verwendet einen 20-Sekunden-Cache. Wenn Sie gerade etwas umbenannt haben, aktualisiert sich das in Kürze. Prüfen Sie außerdem, ob das ref-Format user:5/team:3 lautet — ein kaputtes Format behandelt split() als nicht zugeordnet (user:0).
F. Kann ein Benutzer zwei Rollen haben?
Nein. role_id ist ein einzelner (nullable) Wert. Wenn Sie zusätzlich eine organisatorische Gruppierung benötigen, verwenden Sie ein Team (ebenfalls ein einzelner Wert).
Verwandte Themen
- Stufen verstehen (RBAC) — die einzige Achse, die tatsächlich über den Zugriff entscheidet
- Konsole für Benutzer und Teams — Details zum CRUD von
/admin/users - Instanzen — die zentrale Asset-Ansicht, die die Verantwortlich-Auswahl nutzt
- Hardware — Verantwortliche für physische Assets
- Speicher und Dateien — Verantwortliche für Speicher-Assets
- Audit-Protokoll — Verlauf der Benutzer-, Team- und Verantwortungsänderungen
