Czym jest Azure Entra ID? — Tożsamości, role i model mentalny, którego naprawdę potrzebujesz
Opublikowano 29 kwietnia 2026
Tożsamość to coś więcej niż logowanie
Wyobraź sobie pięćdziesiąt funkcji Azure działających na produkcji. Wszystkie łączą się z tym samym kontem Storage Account — przez connection string, który ktoś dwa lata temu wkleił w ustawieniach aplikacji. I właśnie teraz zespół bezpieczeństwa rotuje klucze Storage Account. Co się dzieje?
Wszystkie pięćdziesiąt funkcji przestaje działać. W tej samej chwili. Na produkcji.
To nie jest scenariusz hipotetyczny. Tak rzeczywiście się zdarza. A dzieje się dlatego, że wielu programistów nadal myśli o tożsamości w Azure tak, jak myślało się o niej dziesięć lat temu: nazwa użytkownika, hasło i tyle. W chmurze takie podejście to nie tylko przestarzałe — to realne ryzyko.
Azure Entra ID to fundament, który pozwala uniknąć takich sytuacji już na poziomie projektu architektury — pod warunkiem, że naprawdę rozumiesz, jak to działa, a nie tylko wiesz, co kliknąć w portalu.
Ten artykuł nie jest instrukcją krok po kroku — nie znajdziesz tu zrzutów ekranu. Dostajesz model mentalny, dzięki któremu zaprojektujesz bezpieczną architekturę, sprawnie zdiagnozujesz błąd i od pierwszego dnia będziesz przynosić organizacji konkretną wartość.
Czym jest Azure Entra ID — w kilku zdaniach
Od 2023 roku oficjalna nazwa Azure Active Directory to Microsoft Entra ID. To zmiana znacznie głębsza niż sam rebranding — Microsoft jasno daje do zrozumienia, że tożsamość traktuje jako osobną dziedzinę, projektowaną od początku z myślą o chmurze i niezależną od klasycznego Active Directory.
Entra ID jest kręgosłupem tożsamości w całym Microsoft Cloud: w Microsoft 365, w zasobach Azure, w zewnętrznych aplikacjach SaaS, a coraz częściej również w przypadku tożsamości nieosobowych — agentów, potoków CI/CD i innych usług.
Zacznijmy od jasnego rozgraniczenia: Entra ID nie zastępuje lokalnego Active Directory. To zupełnie inna technologia. Lokalne AD opiera się na Kerberosie, LDAP-ie i Group Policy. Entra ID stoi na OAuth 2.0, OpenID Connect i interfejsach REST. Protokoły są fundamentalnie różne — kto je miesza, projektuje rozwiązania hybrydowe, które potem zachowują się zupełnie inaczej, niż się tego spodziewał.
Rodzina Entra to kilka oddzielnych produktów:
Entra ID stanowi rdzeń: uwierzytelnianie, autoryzacja, jednokrotne logowanie (SSO) i MFA dla organizacji. To na nim opierają się pozostałe usługi.
Entra Workload ID obejmuje swoim działaniem tożsamości nieosobowe — aplikacje, usługi, agentów. Temu poświęcona jest trzecia część tej serii.
Entra ID Governance automatyzuje zarządzanie cyklem życia uprawnień: kto i kiedy dostaje dostęp, jaki zakres uprawnień otrzymuje i kto cyklicznie ten dostęp przegląda.
Entra External ID obsługuje scenariusze zewnętrzne: klientów, partnerów oraz współpracę B2B.
W tym artykule skupiamy się na samym rdzeniu Entra ID i pojęciach, z którymi spotykamy się na co dzień.
Tenant — pojęcie, od którego trzeba zacząć
Zanim tożsamości, role i tokeny ułożą się w spójną całość, trzeba dobrze zrozumieć jedno pojęcie: tenanta.
Tenant to dedykowana, w pełni odizolowana instancja Entra ID przypisana do danej organizacji. Microsoft tworzy go automatycznie w momencie, gdy zakładasz konto w Azure. Każdy zasób, każda tożsamość i każde uprawnienie w Azure żyją wewnątrz konkretnego tenanta.
Najistotniejszą cechą tenanta jest izolacja. Tożsamości z tenanta A nie mają żadnego dostępu do zasobów w tenancie B, dopóki nie skonfigurujesz tego jawnie. To nie jest błąd — to świadomy element modelu bezpieczeństwa.
Relacja między tenantem a subskrypcjami często sprawia trudność na początku, więc napiszmy to wprost: jeden tenant może zawierać wiele subskrypcji Azure, ale każda subskrypcja należy zawsze do dokładnie jednego tenanta. Subskrypcja to nie to samo co tenant.
Pomocna analogia: tenant to siedziba firmy. Subskrypcje są poszczególnymi piętrami, grupy zasobów — działami na danym piętrze, a pojedyncze zasoby — pokojami. Entra ID jest wtedy ochroną przy wejściu, która sprawdza, kto może gdzie wejść.
Kiedy faktycznie potrzebujesz wielu tenantów? W praktyce znacznie rzadziej, niż mogłoby się wydawać. Najczęstsze powody to: pełna separacja spółek w grupie kapitałowej, wymogi regulacyjne dotyczące rozdziału danych albo bliska współpraca z partnerami w modelu B2B. Rozdzielenie środowisk produkcyjnego i deweloperskiego prawie zawsze wystarczy zrealizować osobnymi subskrypcjami — kolejny tenant nie jest do tego potrzebny.
Typy tożsamości — kto (a właściwie co) ma dostęp?
W Entra ID nie chodzi tylko o ludzi. Istnieje cała, uporządkowana klasyfikacja tożsamości — i to, czy ją rozumiesz, decyduje o tym, czy zaprojektujesz architekturę bezpieczną, czy łatwą do przejęcia.
Tożsamości osobowe
Użytkownicy (User) to konkretne osoby z kontem w Entra ID. Logują się, korzystają z MFA, podlegają politykom Conditional Access. Klasyczny przypadek.
Grupy (Groups) to zbiory użytkowników lub innych podmiotów (principals). Zamiast nadawać role pojedynczym osobom, nadajesz je grupie — i właśnie to pozwala skalować zarządzanie uprawnieniami. W środowiskach korporacyjnych role powinny trafiać niemal wyłącznie na grupy, a nie na konkretne konta użytkowników.
Tożsamości nieosobowe (Workload Identities)
To w tym miejscu pojawia się najwięcej błędów.
Service Principal jest tożsamością aplikacji lub usługi w Entra ID. Powstaje automatycznie, kiedy rejestrujesz aplikację (App Registration) — i to właśnie jemu nadajesz role. Posiada własne poświadczenia: albo Client Secret, który trzeba przechowywać i regularnie rotować, albo certyfikat — bezpieczniejszy, ale wymagający większego nakładu pracy.
Managed Identity to rozwiązanie, po które warto sięgać w zdecydowanej większości sytuacji. Pod spodem działa na bazie Service Principala, ale poświadczeniami zarządza za ciebie Microsoft. Nie widzisz żadnego sekretu, nie musisz go rotować, nie wygaśnie ci w środku nocy i nie wyłączy aplikacji. A do tego konfiguracja jest banalnie prosta.
Występują w dwóch wariantach:
System-assigned — na stałe powiązana z konkretnym zasobem Azure. Skasujesz Function App, znika i tożsamość. Relacja jeden do jednego.
User-assigned — samodzielny zasób Azure. Tworzysz raz, podpinasz pod dowolną liczbę usług. Jeśli dziesięć Function Apps ma czytać z tego samego konta Storage, jedna user-assigned MI obsłuży wszystkie.
Workload Identity Federation to nowoczesne podejście dla wszystkiego, co działa poza Azure: GitHub Actions, obciążeń w Kubernetes, zewnętrznych systemów CI/CD. Zamiast trzymać długożyjący sekret, konfigurujesz relację zaufania — platforma zewnętrzna przedstawia się krótkotrwałym tokenem, a Entra ID wymienia go na token dostępu do Azure. Żadnego sekretu do przechowywania.
| System-assigned MI | User-assigned MI | Service Principal | |
|---|---|---|---|
| Kto zarządza poświadczeniami | Microsoft | Microsoft | Ty |
| Cykl życia | = zasób | niezależny | niezależny |
| Wiele zasobów | Nie | Tak | Tak |
| Przypadek użycia | Pojedynczy zasób | Współdzielona tożsamość | Poza Azure / legacy |
RBAC — jak działa model uprawnień w Azure
Role-Based Access Control to model autoryzacji w Azure. Każda próba dostępu do zasobu przechodzi przez RBAC. Model opiera się na trzech składowych.
Security Principal — kto wykonuje żądanie? Może to być użytkownik, grupa, Service Principal albo Managed Identity.
Role Definition — co dany principal może zrobić? Definicja roli to zestaw uprawnień podzielony na Actions (operacje na zarządzaniu zasobem) i DataActions (operacje na samych danych). To rozróżnienie ma duże znaczenie w praktyce:
Microsoft.Storage/storageAccounts/write — operacja zarządzania (utworzenie lub konfiguracja zasobu)
Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read — DataAction (faktyczny odczyt zawartości blobów)
Scope — na jakim poziomie obowiązuje przypisanie? Azure definiuje cztery poziomy, od najszerszego do najwęższego: management group → subskrypcja → grupa zasobów → pojedynczy zasób. Uprawnienia dziedziczą się w dół tej hierarchii. Rola nadana na poziomie subskrypcji obejmuje automatycznie wszystkie znajdujące się pod nią grupy zasobów i zasoby.
Połączenie tych trzech elementów tworzy Role Assignment. W praktyce oznacza ono coś w rodzaju: „ten principal (Managed Identity Function Appa) może wykonywać te operacje (Storage Blob Data Reader) w tym zakresie (konto Storage w rg-prod/sa-data)”.
Zasada jest prosta: scope nadawaj możliwie wąsko. Jeśli Managed Identity ma odczytywać dane tylko z jednego kontenera blobów, nadaj rolę na poziomie tego kontenera, a nie całej subskrypcji. Wymaga to nieco więcej pracy, ale dokładnie to odróżnia bezpieczną architekturę od takiej, którą łatwo przejąć.
RBAC jest kumulatywny: rzeczywiste uprawnienia danego principala to suma wszystkich przypisań ról, jakie posiada. Domyślnej semantyki „deny” nie ma — z wyjątkiem jawnych przypisań typu deny, które stosuje się rzadko.
Jeszcze jedno kluczowe rozróżnienie: Azure RBAC to nie to samo co role w Entra ID. Azure RBAC kontroluje dostęp do zasobów Azure (Storage, maszyn wirtualnych, Key Vaulta itd.). Role w Entra ID dotyczą samego katalogu — zarządzania użytkownikami, nadawania ról, rejestrowania aplikacji. Te dwa systemy działają obok siebie. Global Administrator w Entra ID nie dostaje automatycznie prawa do odczytu danych z konta Storage — do tego potrzebne jest osobne przypisanie roli w Azure RBAC.
Definicja roli niestandardowej — gotowy szablon
Zamiast sięgać po zbyt szeroką rolę Contributor, warto stworzyć rolę niestandardową, która zawiera dokładnie te uprawnienia, których aplikacja potrzebuje — i nic ponad to.
{
"Name": "Storage Blob Reader (Custom)",
"Description": "Odczytuje obiekty blob z określonych kontenerów — bez zapisu i bez zarządzania kontem.",
"Actions": [],
"NotActions": [],
"DataActions": [
"Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read"
],
"NotDataActions": [],
"AssignableScopes": [
"/subscriptions/{twoja-subscription-id}"
]
}# Utwórz rolę niestandardową
az role definition create --role-definition role-storage-reader.json
# Przypisz rolę do Managed Identity
az role assignment create \
--assignee <object-id-managed-identity> \
--role "Storage Blob Reader (Custom)" \
--scope /subscriptions/{sub-id}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/{sa}Jak naprawdę przebiega uwierzytelnianie — tokeny i przepływy
Entra ID nie wystawia „sesji” w klasycznym rozumieniu — wystawia tokeny, a konkretnie JSON Web Tokens (JWT). Wszystko opiera się na tokenach. Kiedy zrozumiesz, jak to działa, debugowanie problemów z uwierzytelnianiem zajmuje minuty, a nie godziny — bo od razu wiesz, gdzie szukać przyczyny.
Co znajduje się w JWT?
JWT składa się z trzech zakodowanych w Base64 części oddzielonych kropkami: Header.Payload.Signature. Payload zawiera tzw. claims — informacje o tożsamości, dla której token został wystawiony.
Claims, które warto znać w praktyce:
oid — Object ID principala w Entra ID. Jest stały i jednoznaczny — to właśnie tego identyfikatora używasz przy nadawaniu ról RBAC i w logach audytowych.
aud — odbiorca (audience). Czyli: dla jakiego zasobu token został wystawiony. Token wystawiony dla https://storage.azure.com zostanie odrzucony przez Microsoft Graph — i odwrotnie. Każdy zasób przyjmuje wyłącznie tokeny wystawione specjalnie dla niego.
roles — role aplikacyjne principala. W przypadku wywołań Graph API: pusta wartość zwykle oznacza brak zgody administratora (Admin Consent) na wymagane uprawnienia.
exp — moment wygaśnięcia tokena (znacznik czasu Unix). Po tym czasie wywołania kończą się błędem 401. Biblioteki SDK zwykle odświeżają token same — przy ręcznej obsłudze właśnie tu rodzi się większość błędów.
tid — identyfikator tenanta. Istotny w scenariuszach wielotenancyjnych, kiedy musisz potwierdzić, skąd token pochodzi.
Przepływy OAuth 2.0 — który z nich i kiedy?
OAuth 2.0 nie jest jednym protokołem — to cała rodzina przepływów. Trzy najważniejsze to:
Authorization Code Flow — dla rzeczywistych użytkowników. Użytkownik zostaje przekierowany do logowania w Entra ID, uwierzytelnia się, a aplikacja otrzymuje kod autoryzacyjny, który następnie wymienia na token. MFA, Conditional Access — wszystko działa właśnie w tym przepływie.
Client Credentials Flow — dla aplikacji działających bez kontekstu użytkownika. Aplikacja uwierzytelnia się własną tożsamością (Client ID plus sekret lub certyfikat, albo Managed Identity). Żaden użytkownik w to nie jest zaangażowany. Tak działa zdecydowana większość usług w tle, agentów i procesów automatycznych.
On-Behalf-Of Flow — delegacja. Usługa A ma token użytkownika i chce w jego imieniu wywołać usługę B. Wymienia więc token użytkownika na nowy token przeznaczony dla usługi B — kontekst użytkownika zostaje przy tym zachowany.
W rozwiązaniach w pełni zautomatyzowanych — a takich jest dziś większość architektur chmurowych — właściwym wyborem jest Client Credentials.
Odświeżanie tokena — proaktywnie i reaktywnie
Odświeżanie proaktywne — przed każdym wywołaniem API aplikacja sprawdza, czy token nie wygaśnie w najbliższym czasie (np. zostało mniej niż pięć minut), i jeśli trzeba, pobiera nowy bez angażowania użytkownika. Nigdy nie pojawia się 401 ani nieudane wywołanie. Microsoft Authentication Library (MSAL), powszechnie używana w aplikacjach na Azure, robi to domyślnie.
Odświeżanie reaktywne — aplikacja używa aktualnie posiadanego tokena, a dopiero kiedy dostanie 401, odświeża go i ponawia żądanie. Implementacja jest prostsza, ale każde pierwsze wywołanie po wygaśnięciu kończy się niepowodzeniem i wymaga ponownej próby.
*
Powyższy diagram obrazuje wariant reaktywny, ponieważ pokazuje przebieg krok po kroku.
MSAL łączy oba podejścia: cache'uje tokeny, czyta claim exp, odświeża proaktywnie, a w razie błędu sięga po ścieżkę reaktywną. Z punktu widzenia programisty zwykle wystarczy wywołać AcquireTokenSilent() — MSAL sam decyduje, czy token z cache'a wciąż jest ważny, czy trzeba go odświeżyć.
Ważna uwaga: sam Refresh Token również ma określony czas życia. W Entra ID domyślnie wynosi on 90 dni i przy regularnym użytkowaniu jest automatycznie przedłużany (sliding window). Gdy refresh token też wygaśnie, użytkownik musi przejść pełny proces logowania od początku.
Managed Identity — poświadczenia, których nie musisz przechowywać
Managed Identity odpowiada na pytanie, które każdy zespół deweloperski powinien sobie zadać: po co właściwie ręcznie zarządzać poświadczeniami?
Odpowiedź: nie musisz — pod warunkiem, że twoja aplikacja działa na zasobie Azure.
Managed Identity korzysta z usługi Azure Instance Metadata Service (IMDS). To wewnętrzny endpoint HTTP pod adresem http://169.254.169.254/metadata/identity/oauth2/token, dostępny wyłącznie z wnętrza zasobu Azure. Aplikacja prosi go o token, IMDS go zwraca, Entra ID go wystawia — i żaden sekret nigdy nie wychodzi poza tę chronioną ścieżkę.
SDK całkowicie ukrywa tę mechanikę. DefaultAzureCredential z pakietu Azure Identity próbuje po kolei kilku metod uwierzytelniania: zmiennych środowiskowych (lokalna praca deweloperska), Managed Identity (produkcja), poświadczeń z Azure CLI. Ten sam kod działa lokalnie i w chmurze — bez żadnych zmian w samej aplikacji.
Niebezpiecznie kontra bezpiecznie — różnica kilku linijek kodu
Niebezpiecznie — tak, jak pisze się to zbyt często:
# Connection string z App Settings — zrotowany klucz wyłącza wszystko zależne
import os
from azure.storage.blob import BlobServiceClient
connection_string = os.environ["STORAGE_CONNECTION_STRING"]
client = BlobServiceClient.from_connection_string(connection_string)Bezpiecznie — tak, jak powinno się to robić:
# Managed Identity — brak sekretu, brak rotacji ręcznej, brak awarii z tego powodu
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient
credential = DefaultAzureCredential()
client = BlobServiceClient(
account_url="https://{storageaccount}.blob.core.windows.net",
credential=credential
)Dwie linijki różnicy — i ogromna różnica w poziomie bezpieczeństwa.
Włączenie system-assigned Managed Identity dla Function Appa i nadanie roli RBAC — w jednym poleceniu, bez wchodzenia do portalu:
# Włącz system-assigned Managed Identity
az webapp identity assign \
--name moja-function-app \
--resource-group rg-prod
# Object ID Managed Identity
PRINCIPAL_ID=$(az webapp identity show \
--name moja-function-app \
--resource-group rg-prod \
--query principalId -o tsv)
# Rola Storage Blob Data Reader
az role assignment create \
--assignee $PRINCIPAL_ID \
--role "Storage Blob Data Reader" \
--scope /subscriptions/{sub-id}/resourceGroups/rg-prod/providers/Microsoft.Storage/storageAccounts/moje-konto-storageW praktyce — co sprawdzisz trzema skryptami od ręki
Bez klikania w portalu i bez zrzutów ekranu. Trzy skrypty, które możesz uruchomić jutro rano i mieć przejrzysty obraz tego, jak wygląda twoje środowisko.
Skrypt 1: szukamy Service Principali z nadmiernymi uprawnieniami
# Service Principals z Owner lub Contributor na poziomie subskrypcji
az role assignment list \
--scope /subscriptions/{subscription-id} \
--query "[?roleDefinitionName=='Owner' || roleDefinitionName=='Contributor'] | [?principalType=='ServicePrincipal']" \
--output table
Co dalej? Zweryfikuj każdego znalezionego Service Principala. Czy on naprawdę potrzebuje roli Contributor? Najczęściej nie — wystarczy rola niestandardowa z kilkoma precyzyjnie wybranymi uprawnieniami.
Skrypt 2: znajdujemy Function Appy bez Managed Identity
# Wszystkie Function Apps w subskrypcji
az functionapp list --query "[].{Name:name, RG:resourceGroup, Identity:identity.type}" --output table
# Tylko bez tożsamości
az functionapp list \
--query "[?identity==null].{Name:name, ResourceGroup:resourceGroup}" \
--output tableMasz w ten sposób gotowy plan działania. Każda aplikacja z tej listy to kandydat do wdrożenia Managed Identity. Wiesz, od czego zacząć.
Skrypt 3: eksport przypisań RBAC do CSV na potrzeby audytu
# Eksport wszystkich Role Assignments w subskrypcji do CSV
Get-AzRoleAssignment | Select-Object `
DisplayName, `
ObjectType, `
RoleDefinitionName, `
Scope | Export-Csv -Path "rbac-audit-$(Get-Date -Format 'yyyy-MM-dd').csv" -NoTypeInformation
Write-Host "Eksport zakończony."Gotowy załącznik na kolejny przegląd bezpieczeństwa. Warto uruchamiać go raz na kwartał i archiwizować w repozytorium — w ten sposób budujesz pełną historię RBAC dla swojego środowiska.
Pięć najczęstszych błędów — i jak ich uniknąć
Błąd 1: rola Contributor „bo szybciej”
Skutek: aplikacja może modyfikować, kasować i tworzyć zasoby w całej grupie zasobów. Wystarczy jedna przejęta usługa, żeby zagrozić całemu środowisku.
Rozwiązanie: wbudowana rola dopasowana do konkretnego scenariusza albo rola niestandardowa zawierająca tylko niezbędne akcje.
Błąd 2: connection stringi w ustawieniach aplikacji
Skutek: jedna rotacja kluczy unieruchamia naraz wszystkie zależne aplikacje. Sekrety lądują w logach. Programiści znają poświadczenia produkcyjne.
Rozwiązanie: Managed Identity oraz odwołania do Key Vaulta dla wszystkich pozostałych sekretów. Connection stringi znikają z konfiguracji aplikacji.
Błąd 3: jeden Service Principal dla wielu obciążeń
Skutek: przejęcie jednego obciążenia daje atakującemu dostęp do wszystkiego, do czego uprawniony jest ten Service Principal. Logi audytu nie pozwalają stwierdzić, które konkretnie obciążenie wykonało daną operację.
Rozwiązanie: jedna tożsamość na jedno obciążenie. User-assigned Managed Identity wtedy, gdy kilka zasobów rzeczywiście musi współdzielić tożsamość, ale nadal trzeba zachować wyraźną separację uprawnień.
Błąd 4: Client Secret bez monitorowania daty wygaśnięcia
Skutek: sekret wygasa, aplikacja przestaje działać, nikt nie wie dlaczego — najczęściej w piątek wieczorem.
Rozwiązanie: alert w Azure Monitor na zbliżające się wygaśnięcie poświadczeń Service Principala. Jeszcze lepiej — Managed Identity, w której nie ma żadnego sekretu, który mógłby wygasnąć.
Błąd 5: scope na poziomie subskrypcji zamiast zasobu
Skutek: aplikacja może czytać ze wszystkich kont Storage w subskrypcji — w tym z tych, których w ogóle nie powinna dotykać.
Rozwiązanie: scope zawsze tak wąski, jak tylko to ma sens. W razie wątpliwości poziom pojedynczego zasobu prawie zawsze jest właściwym wyborem.
Podsumowanie
Trzy zdania, które warto sobie zapamiętać:
Managed Identity jest lepsze niż Service Principal, a Service Principal lepszy niż connection string. Zawsze i bez wyjątku.
RBAC to model, a nie tylko zakładka w portalu. Kto rozumie zależność principal — rola — scope, podejmuje dobre decyzje w kilka minut, zamiast spędzać godziny na klikaniu po interfejsie.
Tokeny to serce całego mechanizmu. Zrozumienie, co znajduje się w aud, oid i roles, pokazuje od razu, od czego zacząć analizę problemu.
