Ga naar inhoud

Autorisatie — wie wat mag doen, en hoe je dat aantoont

Control Center beantwoordt twee autorisatievragen, en die zijn wezenlijk verschillend. “Mag deze persoon deze operatie aanroepen?” gaat over mensen, rollen en repositories. “Mag deze agent dit effect veroorzaken?” gaat over acties, argumenten en impactbereik — die vraag staat bij Beveiligingen.

Deze pagina gaat over de eerste vraag, plus het spoor dat beide achterlaten.

Elke autorisatiebeslissing aan de menselijke kant verloopt via één enkele functie:

can(principal, permission, resource) → allow | deny + why

Een permissie heeft de vorm <domain>:<tier> — tickets:write, members:administer, repos:read. De catalogus is afgeleid, niet met de hand geschreven: hij wordt berekend uit het operatieoppervlak zelf (het naamvoorvoegsel van de op geeft het domein, de minimumrol die de op al afdwingt geeft het niveau), zodat alle ~550 operaties een permissie dragen zonder dat iemand er een intypt.

Die afleiding is de eigenschap die het waard is om te beschermen. Het betekent dat een NIEUWE operatie standaard achter een poort zit — het faalpatroon van een met de hand geannoteerd model is dat iemand iets vergeet, en wat diegene vergeet, is juist de poort. Een ratchet-test legt de resulterende set domeinen vast, zodat een operatie onder een nieuw voorvoegsel toevoegen een naamgevingsbeslissing is die een mens neemt, geen ongeluk.

De vier niveaus vallen exact samen met de ingebouwde rollen:

Niveau Minimumrol Voorbeeld
read Gast tickets:read
write Lid tickets:write
administer Beheerder members:administer
own Eigenaar workspace:own

Vijf ingebouwde rollen — Eigenaar, Beheerder, Lid, Kijker, Gast — zijn voorinstellingen boven op die catalogus. Eigenaarschap is één plek per werkruimte, die expliciet wordt overgedragen met Eigenaarschap overdragen (een eigenaar die vertrekt, is anders niet te verwijderen: SCIM-deprovisionering weigert elke eigenaar van een werkruimte — draag eerst over).

Aangepaste rollen zijn subtractief. Een aangepaste rol noemt een basisvoorinstelling (admin, member, viewer of guest — nooit owner) en een set permissies die daarvan WORDEN VERWIJDERD — “admin, maar kan geen leden beheren”. Hij kan nooit meer toekennen dan zijn basis, en dat is precies wat ze veilig maakt om in een bestaande installatie te introduceren: elke bestaande controle blijft een betrouwbare bovengrens. Leden hebben ze als custom:<id>, en een client die te oud is om die waarde te begrijpen, valt terug op gast in plaats van te gokken.

Onder de rollen zitten de verleningen per repository (none / read / review / write): lidmaatschap van een werkruimte geeft nooit stilzwijgend meer rechten dan de codehost. Elk oppervlak dat code toont, controleert ze — ook de oppervlakken die zijdelings bij de code komen, zoals een terminal of een editorsessie die op de worktree van een ruimte is geopend.

Sommige operaties gaan helemaal niet over een werkruimte: installatiebrede instellingen, de SSO-configuratie, de inloggegevens van providers, het beheer van modellen, back-ups van de hele installatie. Die verklaren serverautoriteit en worden voor iedereen geweigerd behalve voor de operator van de installatie (de geregistreerde servereigenaar). Er is met opzet één operatoridentiteit en één definitie daarvan.

Elke autorisatiebeslissing — toestaan en weigeren — wordt toegevoegd aan een per werkruimte bijgehouden auditlogboek dat met hashes is geketend.

Een logboek met alleen weigeringen beantwoordt de vraag “wat hebben we geblokkeerd?”, maar niet “wat heeft deze agent werkelijk gedaan, en wie heeft dat geautoriseerd?” — en dat is de vraag waarmee een incidentonderzoek begint. Elke vermelding legt daarom de volledige attributieketen vast: de handelende principal, de mens namens wie die handelde, de delegatie waarlangs die is binnengekomen, de actie en de argumenten daarvan (als digest), de beslissing, en de regel die de beslissing nam.

De vermeldingen zijn geketend: de hash van elke vermelding dekt die van de vorige, dus het bewerken, verwijderen of herordenen van een rij breekt elke hash daarna. Keten verifiëren leidt het geheel opnieuw af en noemt de eerste schakel die niet klopt. Een auditlog dat je niet kunt controleren, is een log; een dat je opnieuw kunt afleiden, is bewijs.

Twee gevolgen die je moet kennen:

  • De audittabel is uitgezonderd van opschoning op basis van leeftijd. Een hashketen kan niet in het midden worden ingekort. Bewaren gebeurt door te exporteren en daarna af te kappen, en het afkappen laat een checkpoint achter met de eindhash van het verwijderde segment, zodat wat overblijft nog steeds tot aan het begin verifieert.
  • Het staat naast de activiteitentijdlijn, niet erbovenop. De tijdlijn laat zien wat mensen deden; dit laat zien wat werd geautoriseerd en geweigerd. Een gedeelde correlatie-id leest één aanroep in beide.

Het wordt geëxporteerd als JSON met newlines als scheidingsteken en kan naar een SIEM streamen (Splunk, Elastic, Sentinel — een HTTP-endpoint met een bearer-token). Streamen is met opzet best effort: een SIEM die platligt, mag nooit de tool-aanroep van een agent blokkeren, en de duurzame, verifieerbare kopie staat hoe dan ook op schijf.

Een installatie kan een maximale sessieleeftijd en een inactiviteitstime-out instellen. Beide worden afgedwongen bij de controle van de apparaatreferenties waar elke geauthenticeerde route doorheen gaat — een sessiegrens die een client zou kunnen negeren, beantwoordt een vragenlijst, geen aanvaller. Een installatie kan ook SSO verplicht stellen, wat het handmatig koppelen van nieuwe apparaten uitschakelt (met een waarborg tegen buitensluiting: de verplichting wordt geweigerd zolang er geen werkende SSO-verbinding bestaat).

  • Geen ACL’s per object. Er is met opzet geen permissie per ticket of per bericht. Scheiding op repositoryniveau is waar teams echt om vragen, en die bestaat; delen per object is een combinatorisch oppervlak zonder aangetoonde vraag hier.
  • Geen beleidsengine die je in een DSL configureert. Het vocabulaire is met opzet gesloten, zodat het hele beleid kan worden weergegeven, uitgelegd en opgesomd.
  • Nergens anders afgedwongen dan op de server. Controles aan de clientzijde bestaan alleen om te voorkomen dat een bedieningselement wordt aangeboden dat geweigerd zou worden. De gezaghebbende beslissing is altijd die van de server.