Försvar på djupet: Del 1 Modellering av identitet
19 September 2023Nästan alla system vi bygger i dag delar data över publika nätverk. Det betyder att de är tillgängliga för vem som helst. Det vill vi sällan att de ska vara, varför vi begränsar tillgången till dem.
Ofta vill vi också kunna skilja på olika typer av användare och ge dem tillgång till olika typer av information. En användare på en nivå ska inte heller kunna skaffa sig tillgång till information på en annan nivå. Vi behöver också skydda våra system från riktade, externa attacker.
Det här innebär att vi behöver bygga in säkerheten i flera delar och nivåer av systemet. Ett av våra viktigaste verktyg för att åstadkomma det är hur vi hanterar behörigheter. Hur och var vi inför dem påverkar både hur säkert vårt system blir, och hur enkelt det blir för oss att justera behörigheter i efterhand.
Att säkra system enbart med hjälp av nätverkslösningar och andra former av skalskydd fungerar allt sämre i en modern arkitektur. För att bygga försvar på djupet med en stark behörighetskontroll behöver ett distribuerat systems olika delar självständigt verifiera identitet och rättigheter.
Systemet till vänster är skyddat med IP baserad säkerhet via en brandväggsprodukt. All trafik innanför brandväggen är “Full Trust” och har tillgång till det kompletta systemet.
I systemet till höger är varje tjänst skyddad på djupet i flera lager. Varje tjänst tillämpar “Zero Trust” och litar inte på någon inkommande trafik. Det högra systemet har ett betydligt starkare skydd genom säkerhet baserad på identitet och är mycket mer flexibelt för integrationer och drift.
Många av de system som vi designar idag bygger på att vi bryter ner domänen i mindre, självständiga tjänster. Integrationer över publika nätverk är allt oftare ett krav och systemet behöver säkerställa en stark autentisering av den som använder tjänsten.
En gemensam syn på identitet i form av en centraliserad Identity Provider (IdP) är en grundförutsättning för att alla tjänster ska kunna fatta korrekta behörighetsbeslut när antalet tjänster växer. Identitet är ett centralt och gemensamt begrepp, tolkningen av vad identitet ger för rättigheter hör hemma i varje tjänst.
För att få ett säkert system som är flexibelt över tid, allteftersom det ändras och utökas, behöver vi en modell över vilka användare, klienter och resurser som finns i systemet. Det ger oss de verktyg vi behöver för att definiera vad som är central identitet och vad som är lokal behörighet i just vårt system.
Den här artikeln går igenom hur du modellerar identitet och hur du kan använda OAuth2 och OpenID Connect för att bygga ett säkert API. Det ger oss ett par olika koncept att arbeta med:
- Användare
- Klienter
- Tjänster (resurser)
- Scopes
- Audiences
Vi börjar med att rita en bild över alla användartyper, klienter och tjänster som systemet består av. Här är ett exempel:
Scopes — är rättigheter som vi delar ut till klienter och det gäller att hitta en granularitet som är rätt för just ditt system. Här kommer din domänmodell till god användning.
Audience — är en gruppering av de API som vårt system består av. En bra start är en (1) audience per API, men vi kan gruppera hur vi vill, t.ex. en enda audience som representerar samtliga API.
Nu är det dags att göra själva modelleringen. Ett sätt är att rita pilar från användare till klient och från klient till tjänst. På så sätt kan vi identifiera vem som använder vad och vilket finmaskighet vår modell behöver stödja. I vårt exempel kanske följande kan vara rätt modell.
product.read
Ger läsåtkomst till produkter product.manage
Ger tillgång till att läsa, skapa, ta bort och hantera produkter order.read
Beviljar läsåtkomst till beställningar order.create
Ger tillgång till att läsa och skapa nya beställningar
Val av audience och scope påverkar hur mycket vi kan begränsa en giltig biljett i vårt system av API. Om vi i vårt exempel har en enda audience för alla API, så finns det t ex inte någon möjlighet att begränsa en biljett med scope order.read till bara statistik API. Audience i kombination med scope ska ge dig den granularitet som du behöver.
En Identity Provider (IdP) kan ge användaren möjlighet att kombinera scopes med audience vid inloggning. Det ser lite olika ut i olika IdP produkter, men i princip så ger användaren sin klient rätt att använda ett urval av scopes för ett urval av audiences. Till exempel kan en administratör i vårt fall ge en klient rätt att hantera produkter för produkt API, men ingenting annat, vilket ofta kallas för User Consent.
Till sist har vi behörighetsmodellen, vad en användare har rätt till. Varje API får information om vilka scopes och audiences som användaren godkänt, hennes identitet, samt detaljer kring inloggningstillfället. I nästa artikel kommer vi att diskutera hur vi använder informationen för att bygga en stark behörighetskontroll.
Behörighetskontroll för vad Eva Svensson tillåts göra implementeras i varje API. I artikel 3 kommer vi att gå på djupet på vad du behöver tänka på.
Joel Harsten, Omegapoint
Jag ser ofta att man glömmer bort själva behörighetskontrollen. Man behöver vara noggrann med att begränsa tillgång till resursen så att den inte bara baseras på en giltig biljett, utan också baseras på dina rättigheter i systemet.
En dokumenterad, genomtänkt modell för identitet är grunden för en bra behörighetsmodell och ett säkert system. Vår erfarenhet är att det kan vara en utmaning att hitta en modell som balanserar centralt mot lokalt, inte är för enkel, inte för stor, och som kan anpassas för framtida behov. En genomtänkt domänmodellering är en mycket god start för detta arbete.
Tobias Ahnoff, Omegapoint
Var försiktig med att återanvända dina klienter. Enligt principen “Least Privilege” ska varje klient ha minimal behörighet för att kunna utföra sina uppgifter. Om du återanvänder klienter så riskerar du att behöva ge den mer behörighet än vad som är nödvändigt, du kan försvåra spårbarheten i system och riskerar att få beroenden som gör det svårt att rotera credentials.
En bra utgångspunkt kan vara att aldrig återanvända klienter mellan olika bounded contexts.
Som alltid behöver du hitta en balans mellan många klienter att administrera och få klienter med stora behörigheter och reducerad spårbarhet.
Se Defense in Depth för ytterligare material och kodexempel kopplade till den här artikelserien.
Fler artiklar i serien:
- Försvar på djupet: Del 1 Modellering av identitet
- Försvar på djupet: Del 2 Claimsbaserad behörighetskontroll
- Försvar på djupet: Del 3 Klienter och sessioner
- Försvar på djupet: Del 4 Säkra API:er
- Försvar på djupet: Del 5 Infrastruktur och lagring av data
- Försvar på djupet: Del 6 Webbläsare
- Försvar på djupet: Del 7 Sammanfattning