W jaki sposób wdrożyć izolację dzierżawców SaaS za pomocą ABAC i AWS IAM

19 lipca 2021

Aplikacje obsługujące wielu użytkowników muszą zostać zaprojektowane w taki sposób, aby zasoby każdej dzierżawy zostały odizolowane i nie były dostępne dla innych dzierżawców w systemie. AWS Identity and Access Management (IAM) często stanowi kluczowy element w osiągnięciu tego celu. Jednym z wyzwań związanych z korzystaniem z IAM jest jednak to, że liczba i złożoność zasad uprawnień niezbędnych do obsługi dzierżawców może szybko rosnąć i wpływać na skalę oraz możliwości zarządzania modelem izolacji. Mechanizm kontroli dostępu opartej atrybutach (ABAC) IAM zapewnia programistom sposób na sprostanie temu wyzwaniu.

W tym artykule zostaną opisane oraz wyszczególnione sposoby użycia ABAC w uprawnieniach do implementacji izolacji dzierżawy w środowisku z wieloma dzierżawcami.

Wybierz metodę izolacji IAM

IAM umożliwia implementację izolacji dzierżawców i uprawnień do ograniczania zakresu w sposób zintegrowany z innymi usługami AWS. Opierając się na IAM, możesz tworzyć silne podstawy izolacji w swoim systemie i zmniejszyć ryzyko tego, że programiści nieumyślnie wprowadzą kod, który będzie prowadził do naruszenia granic dzierżawy. IAM zapewnia natywny, nieinwazyjny sposób na osiągnięcie izolacji w tych przypadkach, gdzie IAM obsługuje zasady zgodne z ogólnym modelem izolacji.

Istnieje kilka metod w uprawnieniach IAM, których można użyć do izolowania najemców i ograniczania dostępu do zasobów. Wybór właściwej metody dla Twojej aplikacji zależy od kilku parametrów. Liczba najemców i liczba definicji ról to dwa ważne wymiary, które w tej sytuacji należy wziąć pod uwagę.

Większość aplikacji wymaga wielu definicji ról dla różnych funkcji użytkownika. Definicja roli odnosi się do minimalnego zestawu uprawnień, których użytkownicy lub komponenty programistyczne potrzebują do wykonywania swojej pracy. Na przykład użytkownicy biznesowi i analitycy danych zazwyczaj posiadają inny zestaw uprawnień, aby zapewnić minimalny, niezbędny dostęp do zasobów, z których korzystają.

W aplikacjach typu oprogramowanie jako usługa (SaaS), oprócz granic funkcjonalnych, istnieją także granice pomiędzy zasobami dzierżawców. W efekcie dla każdej dzierżawy istnieje cały zestaw definicji ról. W wysoce dynamicznych środowiskach (scenariusze współpracy z dostępem między dzierżawcami) nowe definicje ról można dodawać ad-hoc. W takim przypadku liczba definicji ról i ich złożoność może znacznie wzrosnąć wraz z ewolucją systemu.

W uprawnieniach IAM istnieją trzy główne metody izolacji dzierżawy. Pora krótko przyjrzeć się każdej z nich, zanim skupimy się na ABAC w kolejnych sekcjach.

SaaS za pomoca ABAC i AWS IAM

RBAC – każdy z dzierżawców posiada określoną rolę uprawnień lub statyczny zestaw ról uprawnień, których używa w celu uzyskania dostępu do zasobów dzierżawy. Liczba ról uprawnień w RBAC jest równa liczbie definicji ról pomnożonej przez liczbę dzierżawców. RBAC działa dobrze, gdy posiadasz niewielką liczbę dzierżawców i stosunkowo statyczne zasady. Zarządzanie wieloma rolami uprawnień może okazać się trudne, ponieważ rośnie wtedy zarówno liczba dzierżawców, jak i złożoność dołączonych zasad.

Dynamicznie generowane zasady IAM – ta metoda w dynamiczny sposób generuje zasady IAM dla dzierżawców zgodnie z tożsamością użytkownika. Wybierz tę metodę w bardzo dynamicznych środowiskach ze zmieniającymi się lub często dodawanymi definicjami ról (np. scenariusz współpracy z dzierżawcami). Możesz także wybrać zasady generowane dynamicznie, jeśli wolisz generować zasady uprawnień i zarządzać nimi przy użyciu kodu, zamiast polegać na wbudowanych funkcjach usługi IAM. Więcej szczegółów na ten temat znajdziesz w artykule blogowym Isolating SaaS Tenants with Dynamically Generated IAM Policies.

ABAC – metoda ta jest odpowiednia dla szerokiej gamy aplikacji SaaS, chyba że przypadek użycia wymaga obsługi często zmienianych lub dodawanych definicji ról, którymi z kolei łatwiej zarządzać dzięki dynamicznie generowanym zasadom uprawnień. W przeciwieństwie do dynamicznie generowanych zasad uprawnień, w przypadku których zarządzasz i stosujesz zasady za pomocą mechanizmu samozarządzania, ABAC umożliwia bardziej bezpośrednie poleganie na uprawnieniach IAM.

ABAC do izolacji dzierżawców

ABAC jest osiągany poprzez użycie parametrów (atrybutów) służących do kontroli dostępu dzierżawcy do zasobów. Wykorzystywanie ABAC do izolacji dzierżawy skutkuje tymczasowym dostępem do zasobów, który jest ograniczony zgodnie z tożsamością i atrybutami wywołującego.

Jedną z kluczowych zalet modelu ABAC jest możliwość skalowania do dowolnej liczby dzierżawców z jedną rolą. Osiąga się to poprzez użycie tagów (takich jak ID dzierżawy) w zasadach uprawnień IAM i tymczasowej sesji tworzonej specjalnie w celu uzyskania dostępu do danych dzierżawy. Sesja hermetyzuje atrybuty jednostki żądającej (np. użytkownika dzierżawcy). W czasie oceny zasad uprawnienia IAM zastępują te tagi atrybutami sesji.

Kolejnym składnikiem ABAC jest przypisywanie atrybutów do zasobów dzierżawców przy użyciu specjalnych konwencji nazewnictwa lub tagów zasobów. Dostęp do zasobu jest przyznawany, gdy atrybuty sesji i zasobów są zgodne (na przykład sesja z atrybutem TenantID: atrybut yellow może uzyskać dostęp do zasobu oznaczonego jako TenantID: yellow).

Aby uzyskać więcej informacji na temat ABAC w IAM, zapoznaj się z „What is ABAC for AWS?”.

ABAC w typowej architekturze SaaS

Aby przedstawić Ci, w jaki sposób korzystać z ABAC w uprawnieniach IAM do izolacji dzierżawców, autorzy artykułu przeprowadzą Cię przez przykład typowej aplikacji opartej na mikrousługach. Autorzy w szczególności skupią się na dwóch mikrousługach, które implementują przepływ śledzenia przesyłek w aplikacji e-commerce obsługującej wielu dzierżawców.

Nasz przykładowy dzierżawca, Yellow, który posiada wielu użytkowników w wielu rolach, posiada wyłączny dostęp do danych przesyłek należących do konkretnej dzierżawy. Aby to osiągnąć, wszystkie mikrousługi w łańcuchu wywołań działają w ograniczonym kontekście, który uniemożliwia dostęp między dzierżawcami.

izolacja dzierzawcow SaaS za pomoca ABAC i AWS IAM

Pora przyjrzeć się bliżej kolejności zdarzeń i omówić szczegółowo wdrożenie.

Żądanie śledzenia przesyłki jest inicjowane przez uwierzytelnionego użytkownika Tenant Yellow. Ze względu na zwięzłość procesu uwierzytelniania pominięto zakres tej dyskusji. Tożsamość użytkownika wyrażona w tokenie sieci Web JSON (JWT) obejmuje oświadczenia niestandardowe, z których jednym jest tenant ID. W tym przykładzie TenantID jest równy yellow.

JWT jest dostarczany z przeglądarki użytkownika w nagłówku HTTP żądania „Pobierz przesyłkę” do usługi wysyłkowej. Ta usługa wysyłkowa następnie uwierzytelnia żądanie i zbiera wymagane parametry w celu uzyskania szacowanego czasu przybycia przesyłki (ETA). Serwis wysyłkowy wysyła żądanie GetShippingETA, używając parametrów do usługi śledzenia wraz z JWT.

Usługa śledzenia zarządza danymi śledzenia przesyłek w repozytorium danych. Repozytorium przechowuje dane dla wszystkich dzierżawców, ale każdy rekord wysyłki ma dołączony tag zasobu TenantID, na przykład yellow, jak w przedstawionym przykładzie.

Rola IAM dołączona do usługi śledzenia w tym przykładzie nazwana, jako TrackingServiceRole, określa zasoby AWS, do których dostęp ma mikrousługa i czynności, jakie może wykonać.

Zauważ, że sama TrackingServiceRole nie posiada uprawnień dostępu do śledzenia danych w magazynie danych. Aby uzyskać dostęp do rekordów śledzenia, usługa śledzenia tymczasowo przyjmuje inną rolę o nazwie TrackingAccessRole. Ta rola zachowuje ważność przez określony czas, do momentu aż wygasną poświadczenia reprezentujące tę tymczasową sesję.

Aby zrozumieć, w jaki sposób to działa, najpierw należy omówić relację zaufania pomiędzy TrackingAccessRole i TrackingServiceRole. Poniższe zasady zaufania wymieniają TrackingServiceRole jako zaufaną jednostkę.

{

  "Version": "2012-10-17",

  "Statement": [

    {

      "Effect": "Allow",

      "Principal": {

        "AWS": "arn:aws:iam::<account-id>:role/TrackingServiceRole"

      },

      "Action": "sts:AssumeRole"

    },

    {

      "Effect": "Allow",

      "Principal": {

        "AWS": "arn:aws:iam::<account-id>:role/TrackingServiceRole"

      },

      "Action": "sts:TagSession",

      "Condition": {

        "StringLike": {

          "aws:RequestTag/TenantID": "*"

        }

      }

    }

  ]

}

Ta zasada musi być powiązana z TrackingAccessRole. Możesz zrobić to na karcie Trust relationships na stronie Szczegóły Roli w konsoli IAM lub poprzez metodę AWS CLI update-assume-role-policy. Stowarzyszenie to jest tym, co pozwala usłudze śledzenia z dołączoną rolą TrackingServiceRole założyć TrackingAccessRole. Zasady umożliwiają również TrackingServiceRole dołączenie tagu sesji TenantID do tworzonych roli tymczasowych.

Tagi sesji to główne tagi, które określasz podczas żądania sesji. W ten sposób wprowadzasz zmienne do kontekstu żądania dla wywołań API wykonywanych podczas sesji. Dzięki temu zasady uprawnień oceniane w kolejnych wywołaniach interfejsu API mogą odwoływać się do identyfikatora Tenant ID za pomocą klucza kontekstu aws:PrincipalTag.

Teraz pora omówić TrackingAccessPolicy. Jest to polityka tożsamości dołączona do TrackingAccessRole. Polityka ta korzysta z klucza aws:PrincipalTag/TenantID do dynamicznego zakresu dostępu dla określonej dzierżawy.

W dalszej części tego artykułu zobaczysz przykłady takich zasad dostępu do danych dla trzech różnych usług przechowywania danych.

Kolejny etap jest ustawiony tak, aby przedstawić, jak usługa śledzenia tworzy sesję tymczasową i wprowadza TenantID do kontekstu żądania. Poniższa funkcja Pythona robi to za pomocą AWS SDK for Python (Boto3). Funkcja pobiera TenantID (wyodrębniony z JWT) i TrackingAccessRole Amazon Resource Name (ARN) jako parametry i zwraca obiekt sesji Boto3 w zakresie.

import boto3

 

def create_temp_tenant_session(access_role_arn, session_name, tenant_id, duration_sec):

    """

    Create a temporary session

    :param access_role_arn: The ARN of the role that the caller is assuming

    :param session_name: An identifier for the assumed session

    :param tenant_id: The tenant identifier the session is created for

    :param duration_sec: The duration, in seconds, of the temporary session

    :return: The session object that allows you to create service clients and resources

    """

    sts = boto3.client('sts')

    assume_role_response = sts.assume_role(

        RoleArn=access_role_arn,

        DurationSeconds=duration_sec,

        RoleSessionName=session_name,

        Tags=[

            {

                'Key': 'TenantID',

                'Value': tenant_id

            }

        ]

    )

    session = boto3.Session(aws_access_key_id=assume_role_response['Credentials']['AccessKeyId'],

                    aws_secret_access_key=assume_role_response['Credentials']['SecretAccessKey'],

                    aws_session_token=assume_role_response['Credentials']['SessionToken'])

    return session

 

Użyj tych parametrów, aby utworzyć tymczasowe sesje dla konkretnego dzierżawcy o czasie trwania odpowiadającym Twoim potrzebom:

access_role_arn  – przyjęta rola z dołączoną szablonową polityką. Polityka IAM musi zawierać klucz tagu aws:PrincipalTag/TenantID.

session_name – nazwa sesji. Użyj nazwy sesji roli, aby jednoznacznie zidentyfikować sesję. Nazwa sesji roli jest używana w ARN założonego podmiotu roli i jest zawarta w dziennikach AWS CloudTrial.

tenant_id – identyfikator dzierżawcy, który opisuje, dla którego z dzierżawców jest tworzona sesja. Aby uzyskać lepszą zgodność z nazwami zasobów w zasadach uprawnień, zaleca się generowanie identyfikatorów dzierżawców, które nie są możliwe do odgadnięcia.

duration_sec – czas trwania sesji tymczasowej.

Uwaga: Szczegóły zarządzania tokenami można wyodrębnić z aplikacji, wyodrębniając generowanie tokenów do oddzielnego modułu zgodnie z opisem w poście na blogu „Isolating SaaS Tenants with Dynamically Generated IAM Policies”. W tym artykule kod aplikacji wielokrotnego użytku do pozyskiwania tymczasowych tokenów sesji nazywa się automatem do sprzedaży tokenów.

Zwrócona sesja może służyć do tworzenia obiektów o zakresie uprawnień IAM, takich jak usługa magazynu. Po tym, jak sesja zostaje zwrócona, każde wywołanie interfejsu API wykonane z tymczasowymi poświadczeniami sesji zawiera parę klucz-wartość aws:PrincipalTag/TenantID w kontekście żądania.

Kiedy usługa śledzenia próbuje uzyskać dostęp do danych śledzenia, uprawnienia IAM wykonują kilka kroków oceny, aby określić, czy zezwolić na żądanie, czy je odrzucić. Obejmują one ocenę zasad opartych na tożsamości podmiotu zabezpieczeń, które w tym przykładzie są reprezentowane przez TrackingAccessPolicy. Na tym etapie klucz tagu aws:PrincipalTag/TenantID jest zastępowany rzeczywistą wartością, warunki zasad są rozwiązywane, a dostęp do danych dzierżawy jest przyznawany.

Typowe scenariusze ABAC

Pora rzucić okiem na kilka typowych scenariuszy z różnymi usługami przechowywania danych. Dla każdego przykładu dołączony jest diagram ilustrujący dozwolony dostęp do danych dzierżawy oraz sposób partycjonowania danych w usłudze.

Te przykłady opierają się na architekturze opisanej wcześniej i zakładają, że tymczasowy kontekst sesji zawiera parametr TenantID. Autorzy zademonstrują teraz różne wersje TrackingAccessPolicy, które mają zastosowanie do różnych usług. Sposób użycia aws:PrincipalTag/TenantID zależy od funkcji uprawnień specyficznych dla tej usługi, takich jak obsługa tagowania, warunki zasad i możliwość parametryzacji zasobów ARN za pomocą tagów sesji. Przykłady zamieszczone poniżej ilustrują te techniki zastosowane do różnych usług.

Izolacja pamięci masowej w puli za pomocą Dynamo DB

Wiele aplikacji SaaS opiera się na modelu partycjonowania danych w puli, w którym dane ze wszystkich dzierżawców są łączone w jedną tabelę. Identyfikator dzierżawcy jest następnie wprowadzany do każdej tabeli w celu identyfikacji elementów, które są kojarzone z każdym dzierżawcą. Rysunek nr 3 przedstawia przykład tego modelu.

izolacja dzierzawcow SaaS za pomoca ABAC i AWS IAM_3

W tym przykładzie użyto Amazon DynamoDB, przechowując każdy identyfikator dzierżawcy w kluczu partycji tabeli. Teraz można użyć szczegółowej kontroli dostępu ABAC i IAM, aby zaimplementować izolację dzierżawy dla elementów w tej tabeli.

Następnie TrackingAccessPolicy używa klucza warunku dynamodb:LeadingKeys, aby ograniczyć uprawnienia tylko do elementów, których klucz partycji jest zgodny z identyfikatorem dzierżawy przekazanym w tagu sesji.

{

  "Version": "2012-10-17",

  "Statement": [

    {

      "Effect": "Allow",

      "Action": [

        "dynamodb:GetItem",

        "dynamodb:BatchGetItem",

        "dynamodb:Query"

      ],

      "Resource": [

        "arn:aws:dynamodb:<region>:<account-id>:table/TrackingData"

      ],

      "Condition": {

        "ForAllValues:StringEquals": {

          "dynamodb:LeadingKeys": [

            "${aws:PrincipalTag/TenantID}"

          ]

        }

      }

    }

  ]

}

W tym przykładzie w zasadach został zastosowany klucz warunku dynamodb:LeadingKeys, aby opisać, w jaki sposób możesz kontrolować dostęp do zasobów dzierżawcy. Zauważysz, że nie związano tej polityki z żadnym konkretnym najemcą. Zamiast teg, zasady opierają się na tagu aws:PrincipalTag, aby rozwiązać parametr TenantID w czasie wykonywania.

Takie podejście oznacza, że możesz dodawać nowych dzierżawców bez potrzeby tworzenia nowych konstrukcji uprawnień IAM. Zmniejsza to obciążenie związane z utrzymaniem i ogranicza szanse na przekroczenie limitów uprawnień.

Wyciszona izolacja pamięci masowej przy pomocy Amazon Elasticsearch Service

Pora przyjrzeć się kolejnemu przykładowi ilustrującemu, w jaki sposób można zaimplementować izolację dzierżawcy zasobów usługi Amazon Elasticsearch Service. Rysunek nr 4 prezentuje model partycjonowania danych, w którym każdy dzierżawca systemu posiada osobny indeks Elasticsearch dla każdego dzierżawcy.

izolacja dzierzawcow SaaS za pomoca ABAC i AWS IAM

Możesz izolować zasoby dzierżawy, tworząc sparametryzowane zasady tożsamości z głównym tagiem TenantID jako zmienną (podobna była tworzona dla DynamoDB). W poniższym przykładzie znacznik główny jest częścią nazwy indeksu w elemencie zasobu zasad. W czasie dostępu tag Principal jest zastępowany identyfikatorem dzierżawcy z kontekstu żądania, w wyniku którego otrzymuje się indeks Elasticsearch ARN.

{

  "Version": "2012-10-17",

  "Statement": [

    {

      "Effect": "Allow",

      "Action": [

        "es:ESHttpGet",

        "es:ESHttpPut"

      ],

      "Resource": [

        "arn:aws:es:<region>:<account-id>:domain/test/${aws:PrincipalTag/TenantID}*/*"

      ]

    }

  ]

}

W sytuacji, gdy masz wiele indeksów należących do tego samego najemcy, możesz zezwolić na dostęp do nich za pomocą symbolu wieloznacznego. Powyższe zasady umożliwiają podejmowanie działań es:ESHttpGet i es:ESHttpPut na dokumentach, jeśli dokumenty te należą do indeksu o nazwie zgodnej ze wzorcem.

Ważne: Aby to zadziałało, identyfikator dzierżawcy musi być zgodny z tymi samymi ograniczeniami nazewnictwa, co indeksy.

Chociaż to podejście skaluje strategię izolacji dzierżawy, należy pamiętać, że to rozwiązanie jest ograniczone liczbą indeksów, które może obsługiwać klaster Elasticsearch.

Strategia Amazon S3 prefix-per-tenant

Zasobniki Amazon Simple Storage Service (Amazon S3) są powszechnie używane jako magazyny obiektów współdzielonych z dedykowanymi prefiksami dla różnych dzierżawców. W celu zwiększenia bezpieczeństwa można opcjonalnie użyć dedykowanego klucza głównego klienta (CMK) na dzierżawcę. Jeśli zamierzasz to zrobić, dołącz odpowiedni tag zasobu TenantID do CMK.

Korzystając z ABAC i IAM, możesz upewnić się, że każda dzierżawa może pobierać i odszyfrowywać tylko obiekty w udostępnionym zasobniku S3, które posiadają prefiksy odpowiadające dzierżawie.

Izolacja dzierzawcow SaaS za pomoca ABAC i AWS IAM_5

W poniższych zasadach pierwsza instrukcja używa najważniejszego tagu TenantID w elemencie zasobu. Zasady udzielają uprawnienia s3:GetObject, ale tylko wtedy, gdy żądany klucz obiektu zaczyna się od prefiksu dzierżawcy.

Druga instrukcja zezwala na operację kms:Decrypt na kluczu KMS, za pomocą którego zaszyfrowany jest żądany obiekt. Klucz KMS musi mieć dołączony tag zasobu TenantID z odpowiednim identyfikatorem dzierżawy jako wartością.

{

  "Version": "2012-10-17",

  "Statement": [

    {

      "Effect": "Allow",

      "Action": "s3:GetObject",

      "Resource": "arn:aws:s3:::sample-bucket-12345678/${aws:PrincipalTag/TenantID}/*"

    },

    {

      "Effect": "Allow",

      "Action": "kms:Decrypt",

       "Resource": "arn:aws:kms:<region>:<account-id>:key/*",

       "Condition": {

           "StringEquals": {

           "aws:PrincipalTag/TenantID": "${aws:ResourceTag/TenantID}"

        }

      }

    }

  ]

Ważne: Aby zasada działała, identyfikator dzierżawy musi być zgodny z wytycznymi dotyczącymi nazw kluczy obiektów S3.

Dzięki podejściu prefix-per-tenant można obsługiwać dowolną liczbę dzierżawców. Jeśli jednak zdecydujesz się na użycie dedykowanego klucza KMS zarządzanego przez klienta na dzierżawę, będziesz ograniczony liczbą kluczy KMS na region AWS.

Wnioski

Metoda ABAC w połączeniu z IAM zapewnia zespołom budującym platformy SaaS atrakcyjny model wdrażania izolacji dzierżawców. Korzystając z tego dynamicznego modelu opartego na atrybutach, możesz skalować zasady izolacji uprawnień IAM do dowolnej, praktycznej liczby dzierżawców. To podejście umożliwia również poleganie na uprawnieniach do zarządzania, skalowania i wymuszania izolacji w sposób zintegrowany z ogólnym schematem tożsamości dzierżawy. Możesz rozpocząć eksperymentowanie z uprawnieniami ABAC, korzystając z przykładów w tym artykule lub z zasobu: IAM Tutorial: Define permissions to access AWS resources based on tags.

Jeśli posiadasz uwagi do tego artykułu, pozostaw komentarz w sekcji Komentarze znajdującej się poniżej. Jeśli masz pytania dotyczące tego artykułu, rozpocznij nowy wątek na forum AWS IAM lub skontaktuj się z pomocą techniczną AWS.

Case Studies
Referencje

Z przyjemnością polecamy firmę Hostersi, z którą mieliśmy przyjemność współpracować przy okazji wdrożenia skalowalnej infrastruktury w Amazon Web Services, opartej o technologię Kubernetes i metodykę DevOps.  Hostersi okazali się niezwykle proaktywnym partnerem, który nie tylko wdrażał wskazane rozwiązania, ale proponował optymalne narzędzia i technologie, które sprawiły, że efekt wdrożenia jest dla nas w pełni satysfakcjonujący. Polecamy!

Grzegorz Lentzy
IT Director LINK Mobility
W skrócie o nas
Specjalizujemy się w dostarczaniu rozwiązań IT w obszarach projektowania infrastruktury serwerowej, wdrażania chmury obliczeniowej, opieki administracyjnej i bezpieczeństwa danych.