WebDisk
Object Storage

STS w praktyce: dostęp do S3 kontem firmowym (SSO), bez stałych kluczy

Data publikacji:

Blog WebDisk · kategoria: Bezpieczeństwo · czas czytania: ~11 minut

W skrócie:- Stałe klucze S3 to sekrety bez daty ważności – wyciekają, nikt ich nie rotuje, a odejście pracownika z firmy ich nie unieważnia.- STS (Security Token Service) wydaje tymczasowe poświadczenia: działają godzinę lub kilka, potem stają się bezwartościowe.- Połączenie STS z logowaniem firmowym (SSO) sprawia, że do magazynu S3 wchodzisz swoim kontem firmowym – a uprawnieniami i dostępem zarządza się w jednym miejscu. >Nie pracujesz z terminalem? Pomiń przykłady kodu – opis działania i sekcja o WebDisk dają pełny obraz.

Wyobraź sobie, że każdy pracownik dostaje na start uniwersalny klucz do biura — dorobiony w punkcie za rogiem, bez ewidencji, ważny bezterminowo. Gdy ktoś odchodzi z firmy, klucz zostaje w jego szufladzie. Gdy ktoś go zgubi, wymieniacie zamki… teoretycznie, bo w praktyce nikt nie pamięta, ile kluczy krąży po świecie.

Brzmi absurdalnie? A dokładnie tak działa większość wdrożeń S3: stała para kluczy (access key + secret key) wygenerowana raz, wklejona do skryptów, konfiguracji i notatek – i żyjąca latami. W tym artykule pokazujemy alternatywę, którą świat chmury stosuje od dawna, a która wciąż jest zaskakująco mało znana: STS, czyli usługę wydającą poświadczenia tymczasowe, oraz jej najciekawsze zastosowanie — wejście do S3 kontem firmowym z SSO. Na końcu opisujemy, jak zbudowaliśmy na tym cały produkt w WebDisk.

Problem: sekret, który nigdy nie wygasa

Klasyczny dostęp do S3 to para: identyfikator klucza (access key) i sekret (secret key). Technicznie to rozwiązanie proste i wygodne – dlatego tak się przyjęło. Ale ma cztery wady, które z czasem tylko rosną:

  • Wyciek jest kwestią czasu. Klucz trafia do skryptu, skrypt do repozytorium, repozytorium na GitHuba. Automaty skanujące publiczne repozytoria znajdują takie sekrety w kilka minut od publikacji.
  • Rotacja boli, więc się jej nie robi. Wymiana klucza oznacza aktualizację wszystkich miejsc, gdzie go wklejono – a nikt nie wie, ilu ich jest. Efekt: klucze żyją latami.
  • Odejście pracownika nic nie zmienia. Konto w firmowym katalogu zostaje zablokowane, ale klucz S3 to osobny byt – działa dalej, dopóki ktoś sobie o nim nie przypomni przy audycie.
  • Jeden klucz, wielu użytkowników. W praktyce zespoły współdzielą klucze, więc dziennik zdarzeń mówi tylko „ktoś z kluczem X” – bez informacji, kto.

Każda z tych wad ma wspólne źródło: poświadczenie jest wieczne i oderwane od tożsamości człowieka. Naprawić to można tylko w jeden sposób – poświadczenia muszą być krótkotrwałe i wydawane na podstawie prawdziwej, firmowej tożsamości.

Czym jest STS: przepustka zamiast klucza

STS (Security Token Service) to usługa z rodziny API AWS – zaimplementowana także w Ceph RGW, silniku naszej platformy – która robi jedną rzecz: wydaje tymczasowe poświadczenia dostępowe. Zamiast wiecznej pary kluczy dostajesz trójkę:

  • tymczasowy access key i secret key – wyglądają i działają jak zwykłe klucze S3,
  • session token – dodatkowy element dołączany do każdego żądania,
  • oraz datę wygaśnięcia – po jej upływie cała trójka staje się bezwartościowa.

Najlepsza analogia to przepustka gościa w biurowcu: recepcja sprawdza, kim jesteś, drukuje identyfikator ważny do 17:00 i tyle. Nie trzeba go odbierać przy wyjściu, nie trzeba wymieniać zamków, gdy go zgubisz – po prostu jutro już nie działa.

Kluczowe pytanie brzmi: na jakiej podstawie STS wydaje przepustkę? Sposobów jest kilka (rodzina wywołań AssumeRole*), ale nas interesuje najbardziej eleganckie: na podstawie dowodu z firmowego logowania.

SSO + S3, czyli AssumeRoleWithWebIdentity

Jeśli Twoja firma ma SSO (single sign-on – jedno logowanie do wszystkich aplikacji), to każdy pracownik ma już cyfrową tożsamość: konto w firmowym katalogu, z hasłem, MFA i przynależnością do grup. Standard OpenID Connect (OIDC), na którym działa większość współczesnych SSO, po zalogowaniu wystawia tzw. id_token – podpisany cyfrowo „dowód osobisty”: kto się zalogował, gdzie i dla jakiej aplikacji.

Wywołanie STS o nazwie AssumeRoleWithWebIdentity pozwala wymienić ten dowód na tymczasowe poświadczenia S3. Krok po kroku:

  1. Logujesz się firmowym kontem (SSO: hasło, MFA – jak do każdej innej aplikacji). Dostajesz id_token.
  2. Przedstawiasz id_token usłudze STS, wskazując rolę IAM (IAM – Identity and Access Management, system ról i uprawnień w świecie AWS/S3), którą chcesz przyjąć. Rola to wzór przepustki, który recepcja trzyma w segregatorze: zestaw polityk opisujących, co posiadaczowi wolno (np. „czytaj i zapisuj buckety zaczynające się od firma-”).
  3. STS weryfikuje dowód: sprawdza podpis tokenu u wystawcy (Twojego SSO), jego ważność i to, czy polityka zaufania roli (trust policy) pozwala posiadaczom takich tokenów tę rolę przyjmować.
  4. Dostajesz trójkę poświadczeń ważną np. godzinę – i pracujesz z S3 dokładnie tak, jak dotychczas: aws CLI, rclone, boto3, dowolne narzędzie zgodne z S3.
  5. Po wygaśnięciu logujesz się ponownie (albo narzędzie odświeża poświadczenia samo – o tym niżej).

Zwróć uwagę na rozdział ról: SSO odpowiada na pytanie „kim jesteś”, rola IAM – „co ci wolno”, a STS jest recepcją, która sprawdza jedno i drukuje przepustkę według wzoru. Ta separacja to sedno całej konstrukcji:

  • tożsamościami zarządza dział IT w jednym miejscu (katalog firmowy) – blokada konta odcina dostęp do wszystkiego naraz,
  • uprawnieniami do danych zarządza właściciel danych – polityką roli, nie rozdawaniem kluczy,
  • a w dzienniku zdarzeń każda sesja ma nazwę, którą można powiązać z osobą. Jedno zastrzeżenie: nazwę sesji deklaruje wołający, więc wiarygodna rozliczalność wymaga wymuszenia jej po stronie polityki zaufania albo brokera, który wykonuje wymianę (tak robimy w WebDisk – o tym niżej).

Ciekawostka techniczna: AssumeRoleWithWebIdentity to jedno z niewielu wywołań w świecie AWS API, które nie wymaga żadnych wcześniejszych poświadczeń – nie podpisujesz go kluczem, bo Twoim uwierzytelnieniem jest sam id_token. To dlatego cały łańcuch może działać dla użytkownika, który nie ma i nigdy nie miał statycznych kluczy S3.

Jak wygląda rola IAM

Rola składa się z dwóch części, które warto rozróżniać, bo odpowiadają na dwa różne pytania. W przykładach pojawia się ARN (Amazon Resource Name) — unikalny identyfikator zasobu w świecie AWS/S3: roli, bucketa czy wystawcy tożsamości.

Polityka zaufania (trust policy) – kto może przyjąć rolę. Wskazuje zarejestrowanego wystawcę OIDC (Twoje SSO) i warunki, np. że token musi być wystawiony dla konkretnej aplikacji:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "Federated": "arn:aws:iam::<konto>:oidc-provider/sso.firma.example/realms/firma" },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": { "StringEquals": { "sso.firma.example/realms/firma:aud": "s3-firma" } }
  }]
}

Polityki uprawnień (permission policies) – co posiadacz roli może zrobić. Zwykły dokument IAM, np.:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["s3:ListBucket", "s3:GetObject", "s3:PutObject"],
    "Resource": ["arn:aws:s3:::firma-*"]
  }]
}

Dokładna składnia kluczy warunków różni się między dostawcami (AWS, Ceph RGW) — ale konstrukcja jest zawsze ta sama: zaufanie do wystawcy tożsamości + granice uprawnień.

Zrób to sam: STS w terminalu i w kodzie

Zanim zaczniesz. Potrzebujesz trzech rzeczy od administratora platformy: adresu endpointu S3/STS, ARN roli, którą możesz przyjąć, oraz ważnego id_tokenu ze swojego SSO. Ten ostatni jest w praktyce najtrudniejszy: token wystawia Twoje SSO po zalogowaniu, a zdobywa się go własną integracją OIDC (przepływ Authorization Code + PKCE) albo narzędziami typu oidc-agent. W usłudze WebDisk nie musisz robić nic z tego – panel samoobsługowy loguje Cię przez SSO i wykonuje całą wymianę za Ciebie (o tym w następnej sekcji); poniższe przykłady pokazują, co dzieje się pod maską, i są punktem wyjścia dla integratorów.

Wymiana tokenu na poświadczenia w aws CLI:

aws sts assume-role-with-web-identity \
  --role-arn "arn:aws:iam::<konto>:role/firma-s3" \
  --role-session-name "jkowalski" \
  --web-identity-token file://id_token.jwt \
  --duration-seconds 3600 \
  --endpoint-url https://s3.twoj-dostawca.example

W odpowiedzi dostajesz blok Credentials z trójką poświadczeń i datą wygaśnięcia. Wstaw je do zmiennych środowiskowych – i od tej chwili każde narzędzie zgodne z S3 działa jak zwykle:

export AWS_ACCESS_KEY_ID="ASIA...tymczasowy"
export AWS_SECRET_ACCESS_KEY="...tymczasowy-sekret..."
export AWS_SESSION_TOKEN="...dlugi-token-sesji..."

aws s3 ls s3://firma-dokumenty/ --endpoint-url https://s3.twoj-dostawca.example

Jeszcze wygodniej: CLI i SDK AWS znają zmienne AWS_ROLE_ARN i AWS_WEB_IDENTITY_TOKEN_FILE. Gdy je ustawisz, wymiana tokenu i odświeżanie poświadczeń dzieją się automatycznie – narzędzie samo woła STS, gdy poprzednia przepustka wygasa:

export AWS_ROLE_ARN="arn:aws:iam::<konto>:role/firma-s3"
export AWS_WEB_IDENTITY_TOKEN_FILE="$HOME/.config/firma/id_token.jwt"
export AWS_ENDPOINT_URL_STS="https://s3.twoj-dostawca.example" # bez tego CLI zawoła STS Amazona!

aws s3 ls s3://firma-dokumenty/ --endpoint-url https://s3.twoj-dostawca.example

Dwie pułapki, które trzeba znać:

  • --endpoint-url dotyczy tylko samego wywołania S3. Automatyczna wymiana tokenu to osobne, ukryte wywołanie STS – bez wskazania endpointu narzędzie skieruje je do domyślnego STS Amazona (sts.<region>.amazonaws.com): przykład skończy się błędem, a Twój firmowy id_token trafi do obcej usługi. Dlatego przy zewnętrznym dostawcy zawsze ustaw także AWS_ENDPOINT_URL_STS (u dostawców na Ceph RGW, w tym u nas, S3 i STS żyją pod tym samym adresem). Wymaga to aktualnych narzędzi z obsługą endpointów per-usługa: aws CLI v2 ≥ 2.13 (v1 ≥ 1.29), boto3 ≥ 1.28; starsze SDK tej konfiguracji nie znają. Jawne wywołania – jak pierwszy przykład wyżej – są poprawne niezależnie od wersji.
  • Automatyka jest tak świeża, jak token w pliku. Przy każdym odświeżeniu narzędzie czyta plik z tokenem na nowo – a id_tokeny OIDC żyją krótko (typowo kilka–kilkadziesiąt minut), zwykle krócej niż wydana na ich podstawie przepustka. Z ręcznie zapisanym tokenem odświeżenie uda się więc raz–dwa razy, a potem STS odpowie błędem ExpiredToken. Do pracy dłuższej niż życie tokenu potrzebujesz czegoś, co odnawia sam token: integracji OIDC z refresh tokenem, ponownego logowania – albo środowiska, które rotuje plik za Ciebie (tak działa np. Kubernetes, gdzie kubelet regularnie podmienia token serwisowy poda).

To samo programistycznie w Pythonie (boto3):

import boto3

sts = boto3.client("sts", endpoint_url="https://s3.twoj-dostawca.example")

resp = sts.assume_role_with_web_identity(
    RoleArn="arn:aws:iam::<konto>:role/firma-s3",
    RoleSessionName="jkowalski",
    WebIdentityToken=open("id_token.jwt").read(),
    DurationSeconds=3600,
)
c = resp["Credentials"]

s3 = boto3.client(
    "s3", endpoint_url="https://s3.twoj-dostawca.example",
    aws_access_key_id=c["AccessKeyId"],
    aws_secret_access_key=c["SecretAccessKey"],
    aws_session_token=c["SessionToken"],
)
listing = s3.list_objects_v2(Bucket="firma-dokumenty")
print([o["Key"] for o in listing.get("Contents", [])])

A jeśli wolisz rclone: poświadczenia tymczasowe podajesz jak zwykłe, dodając token sesji (session_token w konfiguracji zdalnego S3 albo env_auth = true, żeby rclone czytał trzy zmienne środowiskowe pokazane wyżej).

Co to daje – i czego nie daje

Uczciwy bilans wygląda tak:

Zyskujesz:

  • Brak wiecznych sekretów. Nie ma czego wkleić do repozytorium na lata; wyciek poświadczeń jest groźny przez godzinę, nie przez dekadę.
  • Centralny offboarding. Zablokowanie konta w SSO odcina możliwość pobrania nowych poświadczeń – do wszystkich systemów naraz, w jednym miejscu.
  • Rozliczalność. Każda sesja ma nazwę powiązaną z osobą (jeśli wymusza ją broker lub polityka); dziennik zdarzeń przestaje być anonimowy.
  • Granice ustawiane polityką, nie kluczem. Zmiana uprawnień to edycja polityki roli – natychmiastowa dla wszystkich kolejnych sesji, bez wymiany sekretów.

Musisz wiedzieć:

  • Wydana przepustka żyje do końca swojej ważności. Zablokowanie konta w SSO nie unieważnia poświadczeń wydanych minutę wcześniej – wygasną same, ale do tego czasu działają. Właśnie dlatego ustawia się krótki czas życia: godzinę, nie dobę.
  • Narzędzia muszą umieć się odświeżać. Skrypt działający dłużej niż ważność poświadczeń musi je odnowić – automatyka z AWS_WEB_IDENTITY_TOKEN_FILE zrobi to za Ciebie pod warunkiem, że w pliku jest świeży id_token (patrz pułapki wyżej).
  • Automaty to inna historia. STS z SSO rozwiązuje problem ludzi. Procesy serwisowe (backup, integracje) nie logują się hasłem i MFA – dla nich stosuje się osobne mechanizmy: konta serwisowe o minimalnych uprawnieniach, tożsamości maszyn, a stałe klucze, jeśli muszą istnieć, trzyma się w menedżerze sekretów i rotuje automatycznie.

Jak robimy to w WebDisk: Tenant Manager

Wszystko, co opisaliśmy wyżej, składamy w całość w naszej usłudze S3 dla organizacji, zarządzanej przez WebDisk Tenant Manager. Projektując ją, podjęliśmy decyzję, która porządkuje cały model bezpieczeństwa: końcowi użytkownicy w ogóle nie mają stałych kluczy S3 – dostęp jest wyłącznie przez STS.

Każda organizacja (tenant) dostaje komplet:

  • własny katalog tożsamości – wydzielony obszar w naszym SSO, w którym administrator organizacji sam zakłada konta dla swoich ludzi; to tu odbywa się logowanie i tu blokuje się konta odchodzących pracowników,
  • twardo odizolowane konto na platformie Ceph – buckety, role i polityki jednej organizacji są niewidoczne i niedostępne dla innych; izolację domyka wydzielony prefiks nazw bucketów,
  • role IAM z zaufaniem wyłącznie do katalogu tej organizacji – polityka zaufania wskazuje konkretnego wystawcę OIDC, więc token z katalogu innej firmy jest bezwartościowy,
  • graficzny edytor polityk IAM – administrator organizacji zarządza uprawnieniami z panelu, bez pisania JSON-a ręcznie,
  • oraz własny klucz szyfrowania SSE-KMS – dane w spoczynku szyfrowane są kluczem organizacji, który można zrotować lub wyłączyć z panelu (o wariantach szyfrowania w S3 pisaliśmy w poprzednim artykule z tego cyklu).

Dla pracownika organizacji wygląda to tak: wchodzi na stronę samoobsługi, loguje się swoim kontem firmowym (SSO organizacji), a panel – działający jako broker – wykonuje za niego opisane wyżej AssumeRoleWithWebIdentity i pokazuje gotowe poświadczenia ważne godzinę wraz z gotowymi fragmentami konfiguracji do wklejenia: zmienne środowiskowe, konfiguracja aws CLI, konfiguracja rclone. Broker nadaje też nazwę sesji na podstawie zalogowanej tożsamości – więc rozliczalność nie zależy od dobrej woli wołającego. Jeden klik odświeża przepustkę. Zero kluczy do zapamiętania, zero sekretów do rotowania, pełna zgodność z każdym narzędziem S3.

Usługa S3 dla organizacji jest obecnie w fazie wczesnego dostępu – jeśli chcesz przetestować ten model u siebie, napisz do nas, a przygotujemy środowisko dla Twojej organizacji.

Warto podkreślić różnicę względem naszych aplikacji końcowych. W webowych aplikacjach WebDisk Files czy WebDisk Send poświadczeń S3 nie dotykasz — dostępem do magazynu zarządza za Ciebie aplikacja. Oferta STS jest dla sytuacji odwrotnej: gdy Twoi ludzie i Twoje własne narzędzia mają rozmawiać z S3 wprost – skrypty analityczne, rclone, integracje – a Ty chcesz, żeby robiły to Twoją firmową tożsamością, a nie widmowym kluczem z notatnika.

Częste pytania

Czy do używania STS muszę zmieniać swoje narzędzia? Nie. Tymczasowe poświadczenia to zwykłe poświadczenia S3 plus token sesji — obsługują je aws CLI, wszystkie SDK, rclone i praktycznie każde narzędzie zgodne z S3. Zmienia się tylko sposób ich pozyskiwania.

Co się dzieje, gdy pracownik odejdzie z firmy? Administrator blokuje jego konto w katalogu (SSO) – i to koniec procedury. Nowych poświadczeń już nie pobierze. Ostatnia wydana przepustka wygaśnie najpóźniej po godzinie sama.

Czy STS działa tylko w AWS? Nie – to API zdefiniowane przez AWS, które stało się de facto standardem i implementują je też inne platformy, w tym Ceph RGW, na którym działa nasza platforma obiektowa. Z perspektywy narzędzi nie ma różnicy: te same wywołania, ten sam format poświadczeń.

Czym różni się AssumeRole od AssumeRoleWithWebIdentity? AssumeRole wymaga, by wołający już miał jakieś poświadczenia (klucz lub inną rolę) – służy do przechodzenia między rolami. AssumeRoleWithWebIdentity uwierzytelnia samym tokenem OIDC z SSO – i dlatego jest właściwym wyborem, gdy punktem wyjścia jest konto firmowe, a nie istniejący klucz.

Godzina ważności to nie za krótko? W praktyce nie: nowe poświadczenia pozyskuje się jednym kliknięciem w panelu (albo automatycznie, jeśli Twoja integracja OIDC dba o świeży id_token w pliku), a krótka ważność jest dokładnie tym, co czyni wyciek mało groźnym. To świadomy kompromis – im dłuższa przepustka, tym dłużej działa w niepowołanych rękach.

Mam automaty i procesy serwisowe. Czy one też mogą używać STS? Same wywołania – tak, ale automat nie zaloguje się hasłem z MFA, więc potrzebuje innego źródła tożsamości. To osobny temat (tożsamości maszyn, konta serwisowe); w typowym wdrożeniu ludzie korzystają z SSO + STS, a nieliczne konta serwisowe mają minimalne uprawnienia i klucze pod opieką menedżera sekretów.

Podsumowanie

Stałe klucze S3 to dług bezpieczeństwa, który rośnie z każdym miesiącem: sekrety się mnożą, wiedza o nich ginie, a odejścia pracowników nic nie zmieniają. STS odwraca ten model – poświadczenia stają się krótkotrwałe, imienne i wydawane na podstawie firmowego logowania:

  • SSO mówi, kim jesteś (i pozwala to konto centralnie zablokować),
  • rola IAM mówi, co ci wolno (i pozwala to zmienić jedną polityką),
  • STS wymienia jedno na drugie – na godzinę, nie na zawsze.

W WebDisk uczyniliśmy z tego fundament usługi S3 dla organizacji: własny katalog tożsamości, twarda izolacja, edytor polityk i samoobsługowe poświadczenia tymczasowe – bez jednego stałego klucza w rękach użytkowników. Usługa jest w fazie wczesnego dostępu – jeśli chcesz zobaczyć ten model u siebie, napisz do nas. A jeśli interesuje Cię, jak szyfrujemy dane w spoczynku, zajrzyj do poprzedniego artykułu cyklu o SSE-S3, SSE-KMS i SSE-C.


Artykuł jest częścią cyklu o bezpieczeństwie danych w usługach WebDisk. Przykłady wykonasz na dowolnej platformie S3 z obsługą STS i OIDC. Parametr --endpoint-url w aws CLI wskazuje endpoint S3 Twojego dostawcy, a przy automatycznej wymianie tokenu dodatkowo AWS_ENDPOINT_URL_STS wskazuje jego endpoint STS – w Ceph RGW oba API żyją pod jednym adresem, w AWS to dwie różne usługi.

STS: dostęp do S3 kontem firmowym, bez stałych kluczy | WebDisk