Als zentrales Infrastruktur Team, stellen wir bei Integration Services unter anderem Anwendungen für den Austausch von Daten bereit. Diese Anwendungen nutzen nicht nur OTTO Tech-Teams sondern auch Teams aus den Konzerngesellschaften. Unser Ziel ist es, den Nachrichtenaustausch professionell, hoch verfügbar und möglichst einfach zu gestalten. Seit 2017 stellen wir für den Austausch von sensiblen Daten Hashicorp Vault zur Verfügung. Das Produkt ist sehr gefragt und wird mittlerweile von ca. 270 Clients genutzt. Jedem Team wird ein isolierter Bereich im Vault bereitgestellt in dem Daten abgelegt werden können. Spezielle Anwendungsfälle behandeln auch die Möglichkeit Geheimnisse zwischen Teams untereinander zu teilen.
Für die Ablage der Geheimnisse werden sogenannte Secret Engines verwendet. Meist genutzt sind die Key-Value Backends, in denen man Schlüssel-Wert Paare ablegen kann. Es gibt auch die Möglichkeit dynamische Secrets erzeugen zu lassen zum Beispiel OTPs (One-Time-Passwords), die sicherlich jeder schon einmal bei der Zwei-Faktor-Authentifizierung genutzt hat, oder auch dynamische AWS IAM Nutzer für den Zugriff auf Cloud-Ressourcen.
Zugriffe auf Vault sind ebenfalls vielfältig implementiert, so können persönliche Nutzer authentifiziert werden über zum Beispiel das Open-ID-Connect Verfahren (OIDC) oder auch technische User unter anderen über das Vault interne AppRole Verfahren.
Was bringt mir aber eine Secret-Verwaltung, wenn ich für den Zugriff ebenfalls wieder Zugangsdaten ablegen muss? In diesem Artikel wird dieses Problem durch eine Vertrauensbrücke zwischen der Google Cloud Plattform (GCP) und Vault gelöst.
Natürlich muss man das Rad nicht neu erfinden und kann sich für die Zugriffe auf Vault bestehender Bibliotheken bedienen. Speziell für die Entwicklung mit Java und Spring Boot bietet sich hier die Spring Cloud Vault Bibliothek an. Diese wird, ganz in Spring Manier nur über die Property Dateien konfiguriert. Es werden unter anderem die Vault URL als auch die Authentifizierung und der Secret-Store adressiert.
Eine Referenzimplementierung ist auf GitHub zu finden.
Wie aus der Konfiguration zu entnehmen ist, wird hier GCP IAM für die Authentifizierung an Vault verwendet und eine GCP-Service-Account-Mail Adresse übergeben. Damit das funktioniert, muss im Vault die GCP-Authentifizierungsmethode zunächst aktiviert und konfiguriert werden.
Vault und der Client benötigen jeweils einen eigenen GCP Service Account. Für Vault werden die Berechtigungen iam.serviceAccounts.get und iam.serviceAccountKeys.get benötigt und für den Client die Berechtigung roles/iam.serviceAccountTokenCreator. Der Service Account von Vault überprüft dann, ob der Client für das Vault Backend berechtigt ist und gibt Zugriff oder nicht.
In der Spring Boot Anwendung wird der Service Account des Clients in die Spring Properties eingetragen. Um die Anwendung zum Beispiel in GCP zu betreiben, kann man sie mit Cloud Run lauffähig machen. Beim Starten wird die Verbindung hergestellt und der Client ist authentifiziert. Es werden keine weiteren Zugangsdaten benötigt, man findet lediglich die Mailadresse des Service Accounts in der Konfiguration.
Dadurch dass Cloud Run an den Metadaten-Service von GCP angebunden ist, kann mithilfe dessen bereits ein Access-Token generiert werden und die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS gesetzt werden.
Diese wird dann von der Spring Cloud Vault Bibliothek für die Authentifizierung gegen GCP verwendet.
Vault nutzt den bei der Einrichtung des Authentifizierung Backends übergebenen Service-Account, um sich bei GCP anzumelden.
Durch eine Freischaltung dieses Service-Accounts auf das GCP-Projekt des Clients entsteht eine Vertrauensbrücke zwischen den GCP Projekten (Vault Service Account Projekt und Client Service Account Projekt). Vault kann den Service-Account des Clients überprüfen und den Zugriff gewähren. Vault stellt dann ein kurzlebiges Token aus, mit dem die Geheimnisse ausgelesen werden können.
Startet man die Applikation lokal oder in einer Umgebung außerhalb von GCP dann ist es nötig den Schlüssel des Client Service Accounts für die Authentifizierung in einer JSON-Datei bereitzustellen und diese Datei unter der genannten Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS zu verknüpfen.
Durch die sogenannten Policies, die sich im Vault einrichten lassen, kann der Zugriff auf Geheimnisse sehr feingranular erfolgen. Geheimnisse sind in Vault in einer Baumstruktur angeordnet. Durch konfigurierte Policies kann der Zugriff auf jeden Pfad in der Baumstruktur feingranular beschränkt werden.
Zusätzlich gibt es die Möglichkeit die Operationen auf diesen Pfaden zu regulieren. So ist es beispielsweise möglich in einer Richtlinie nur einen Pfad eines Backends mit nur lesenden Rechten zu versehen.
Diese Policy kann zum Beispiel einem anderen Team übergeben werden bzw. an die Authentifizierungsmethode eines anderen Teams geknüpft werden. So hat dann das andere Team die Möglichkeit dieses eine, für sie bestimmte Geheimnis auszulesen und zu nutzen, kann es aber nicht verändern oder gar löschen.
Dieses Vorgehen kann zum Beispiel verwendet werden, um Verschlüsselungs-Schlüssel auszutauschen. Der Ersteller der Schlüssel verschlüsselt eine Nachricht mit dem Schlüssel und der Empfänger liest den Schlüssel aus und kann die Nachricht entschlüsseln (symmetrische Verschlüsselung).
Es ist sehr einfach Hashicorp Vault in seine Anwendungen zu integrieren. Die Authentifizierung ist sehr vielfältig konfigurierbar und lässt sich sehr gut mit den Cloud-nativen Authentifizierungsmethoden nutzen. Gerade wenn sensible Daten zwischen mehreren Teams geteilt werden müssen, die möglicherweise unterschiedliche Cloud Technologien einsetzen, können hier Vorteile aus der Verwendung von Vault gezogen werden. Auch die Dokumentation für die Nutzung von Vault seitens des Herstellers Hashicorp ist klar verständlich und sehr hilfreich.
Möchtest du Teil des Teams werden?
We have received your feedback.