Heute möchte ich euch ein kleines, aber sehr nützliches Tool an die Hand geben. Teller ist ein “Secrets Manager” für Entwickler, wenn es darum geht, Cloud-Native Applikationen zu entwickeln. Das Projekt wurde im März 2021 ins Leben gerufen und ist komplett in Go geschrieben.
Das Prinzip dahinter ist simpel. Nutze niemals das Terminal, um Passwörter im Klartext ein- oder auszugeben. Dazu wollen wir uns kurz ein kleines Beispiel anschauen und herausfinden, warum das keine gute Praxis ist.
Angenommen ihr nutzt im Unternehmen einen Secrets Manager wie beispielsweise AWS Secrets Manager um eure Secrets zu schützen. Passwörter oder auch Tokens sind damit “sicher” verwahrt und man kann sicher sein, dass nur derjenige das Secret sieht, der auch Zugriff auf die entsprechende Entity im Secrets Manager hat. So weit so gut.
Nun gibt es einen Bug auf einem System bei der Abfrage eines gesicherten Rest-Endpunkts und ihr wollt euch gerne lokal die Daten anschauen, die von diesem Endpunkt zurückkommen. Der Endpunkt ist in unserem Fall mit einer simplen “Basic Auth” abgesichert (natürlich sollte man hier eine sicherere Methode wählen, aber uns reicht das für ein anschauliches Beispiel). Wir öffnen also unsere Konsole und setzen einen curl
gegen den Endpunkt ab. Vorher kopieren wir uns noch das entsprechende Passwort aus unserem Secrets Manager in die Zwischenablage.
|
|
Als Antwort erhalten wir das gewünschte Ergebnis im JSON Format.
|
|
Wir erkennen, dass es einen Typo bei “title” gibt und können diesen auch sehr schnell beheben. Nun können wir uns dann erstmal einen Kaffee gönnen. Leider hast du vergessen den PC zu sperren, aber zum Glück wurde das Konsolenfenster geschlossen, damit niemand das Passwort sehen kann. Nun kommt jedoch ein Linux Experte vorbei und kennt den magischen Befehl, mit dem er das Passwort dennoch auslesen kann. Er setzt sich also an deinen PC, öffnet das Terminal und tippt den Befehl history
. Damit kann er sich alle Befehle anzeigen lassen, welche in deiner Konsole ausgeführt wurden. Er sieht also als letzten Eintrag den Curl Befehl und damit auch den Benutzer und das Passwort im Klartext.
Lange Rede kurzer Sinn. Passwörter im Klartext auf dem Terminal einzutippen, oder diese in ENV Variablen zu speichern ist keine wirklich gute Idee. Genau hier hilft uns Teller. Ausserdem bietet uns Teller auch jede Menge Möglichkeiten, Secrets in den verschiedenen Secret Manager zu verwalten oder auszutauschen.
Schauen wir uns das an einem Beispiel an. Als erstes müssen wir uns Teller lokal installieren. Es gibt jeweils ein Binary für macOS, Linux und auch Windows. Ich nutze macOS und gebe deshalb den folgenden Befehl ein.
|
|
Anschliessend erstellen wir ein neues Projekt. Dazu tippen wir teller new
und müssen anschliessend noch den Namen und die Provider konfigurieren. Der Name ist hier my-project
und als Provider nehmen wir erstmal nur AWS Secrets Manager.
|
|
Wie wir sehen können wurde nun eine Datei namens .teller.yml
in unserem Benutzerordner erstellt. Schauen wir uns diese Datei doch mal an.
|
|
Wie wir sehen können erhalten wir eine Konfigurationsdatei, welche wir nun im Detail besprechen wollen.
Linie 14 - 16: Hier können wir Options definieren, welche später mit opt
ausgelesen werden können. (z.B. region
)
Linie 22 - 30: Hier erfolgt die Konfiguration des Providers.
Damit wir dies nun testen können, müssen drei Dinge bereits gegeben sein: Ihr müsst im AWS Secrets Manger ein Secret haben, die AWS CLI muss installiert und konfiguriert sein und ihr müsst Zugriff auf das entsprechende Secret haben, welches ihr lesen wollt.
Ich habe mir für mein Beispiel einen Secret mit der ID dev/test/admin
und zwei Schlüsseln (user/pass) angelegt. Entsprechend kann ich diesen mit der AWS CLI folgendermassen auslesen:
|
|
Wer die AWS-CLI noch nicht installiert hat, sollte hier unterbrechen und dies tun. Nach der Installation muss man noch den Befehl aws configure
ausführen, um Zugriff per Token zu erhalten.
Nun können wir uns ans Eigentliche wagen. In der Datei .teller.yaml
ändern wir nun im aws_secretsmanager Provider bei env_sync:
den Wert von path: prod/foo/bar
zu path: dev/test/admin
und löschen die Sektion env
einfach raus. Die Datei sieht nun also folgendermassen aus:
|
|
Wollen wir unsere Änderungen also testen. Wir geben im Terminal den folgenden Befehl ein: show
|
|
Wie wir sehen können, werden die Secrets korrekt ausgelesen und wir können diese nun mit Teller nutzen. Die Secrets werden bei der Ausgabe maskiert, sodass man diese nicht in Klartext lesen kann.
ℹ️ Du kannst die Maskierung der Ausgabe in der .teller.yml
Konfigurationsdatei mit der Option redact_with steuern.
Natürlich können wir auch nur einen Schlüssel aus dem Secret auslesen. Dazu ändern wir in der .teller.yml
folgendes und lesen den Secret anschliessend wieder mit teller show
aus.
|
|
|
|
Nun können wir sehen, dass nur noch der entsprechende Secret ausgegeben wird.
Schauen wir uns als nächstes an, wie wir diese Secrets nun in einer Applikation nutzen können. Dafür schreiben wir uns eine einfache Hello World Go App in der wir uns den User ausgeben lassen wollen. Ich erstelle mir dafür ein neues Verzeichnis teller-golang
und lege hier eine Datei main.go
an.
|
|
Wenn ich das Programm jetzt ausführe erhalte ich folgende Ausgabe:
|
|
Wie wir sehen können ist die Variable ADMIN_USER nicht gesetzt. Führen wir das Programm erneut mit Teller aus:
|
|
Wir erhalten einen Fehler, weil in unserem Projektverzeichnis keine Teller Konfigurationsdatei enthalten ist. Durch den Fehler sehen wir nun, wie praktisch Teller an diese Stelle arbeitet. Für jedes Projektverzeichnis kann eine eigene Konfigurationsdatei angelegt werden. So wird sichergestellt, dass auch wirklich nur die Secrets genutzt werden, die es wirklich braucht. Diese Datei kann natürlich ins VCS (Version Control System) eingecheckt werden, damit alle Entwickler Zugriff auf die gleichen Secrets erhalten.
Kopieren wir uns also die Konfigurationsdatei in unser Projektverzeichnis und versuchen das ganze erneut.
|
|
Wie wir nun sehen können werden die Teller Variablen geladen und der Go Applikation in Form von Environment Variablen zur Verfügung gestellt. :rocket:
Secrets Management mit Teller
Teller bietet uns noch weitere nützliche Tools, welche uns nicht nur die Entwicklung, sondern generell den Umgang mit Secrets sehr stark vereinfachen. Wir können beispielsweise neue Secrets direkt im Provider anlegen. Dazu erweitern wir die .teller.yml
um folgenden Eintrag
|
|
Nun führen wir den folgenden Befehl im Terminal aus.
|
|
Durch diesen Befehl, wird direkt im AWS Secrets Manager ein neuer Schlüssel im angegebenen Pfad angelegt.
Weiterhin bietet uns Teller auch die Möglichkeit Secrets zwischen zwei oder mehreren Providern zu kopieren und diese sogar zu synchronisieren.
Dazu müssen wir natürlich erstmal einen weiteren Provider hinzufügen. Wir öffnen also die Teller Konfigurationsdatei und fügen Google Secrets Manager als Provider hinzu. Sollten Sie noch kein Google Konto haben, oder die CLI noch nicht installiert haben, können Sie dies hier tun. Ausserdem wird ein Service Account benötigt. Die Anleitung dazu finden Sie hier.
Ich erstelle mir in der Google Cloud Console ein neues Projekt teller-golang
und erstelle innerhalb von diesem Projekt ein Secret MY_USER=bnova-stefan
.
|
|
Nachdem wir den Provider eingefügt haben, können wir schauen, ob das Secret gelesen werden kann. Wenn alle Konfigurationen korrekt sind, sollten wir die folgende Ausgabe sehen.
|
|
Nun wollen wir den Secret vom Google Secrets Manager zum AWS Secret Manager kopieren. Synchronisierung ist leider im Google Secret Manager nicht möglich.
Dazu geben wir den folgenden Befehl im Terminal an.
|
|
Wir sehen eine Fehlermeldung, dass es den Key MY_USER
im AWS Secret Manager noch nicht gibt. Bevor wir also einen Secret Value kopieren können, muss es im Ziel erst das entsprechende Feld geben. Wir erweitern unsere .teller.yaml
also um den folgenden Eintrag und führen anschliessend den Befehl erneut aus.
|
|
|
|
Wie wir sehen können konnte der Befehl erfolgreich ausgeführt werden. Schauen wir uns das Ergebnis direkt im AWS Secret Manager an.
Et voilà! Der neue Secret wurde erfolgreich kopiert. Auch teller show
zeigt uns den neuen Secret im AWS natürlich an.
|
|
Nun haben wir gesehen, wie wir einen Secret anlegen und kopieren können. Wollen wir uns noch anschauen, wie man einen Secret wieder löschen kann. Hierzu bietet uns Teller den teller delete
Befehl. Wir wollen jetzt nicht mehr den Admin User in unserer Applikation nutzen, sondern neu MY_USER. Wir können ADMIN_USER also löschen. Dazu führen wir den folgenden Befehl aus.
|
|
Gelöscht! Wir schauen zur Sicherheit noch einmal direkt im AWS Secret Manager.
Und auch hier wurde das Secret gelöscht. Schauen wir uns doch noch an, was teller show
uns sagt.
|
|
Wir sehen in der letzten Zeile, dass der Status für das Secret ADMIN_USER im AWS Secret Manager “missing” ist. Das ist so richtig und wir können den Eintrag aus der teller.yaml
entfernen.
|
|
Wir haben das Secret so wieder vollständig entfernt.
ℹ️ Nicht alle Provider unterstützen auch alle Befehle. Der Google Secretmanager unterstützt beispielsweise teller delete
nicht.
Zusammenfassung
Teller ist ein sehr praktisches Tool, wenn man im Developer Team Secrets sharen will, ohne diese im Klartext anzeigen zu müssen. Durch die praktische Konfigurationsdatei teller.yaml
ist es so möglich, für alle Entwickler direkt die gleichen Secrets im Projekt zu hinterlegen. Die Entwickler müssen lediglich die Zugriffsberechtigungen auf die Secrets haben.
Das Secret Management mit Teller ist sehr effektiv, allerdings ist der grosse Nachteil, dass nicht alle Provider die gleichen Funktionalitäten unterstützen. So bietet beispielsweise AWS Secret Manager eine Synchronisation der Secrets an, während Google dies nicht unterstützt. Den Use-Case sehe ich allerdings im Daily Business nur bedingt (z.B Migrationsprojekt von AWS zu Google).
Teller bietet uns mit teller redact
ein weiteres Tool an, mit welchem wir Passwörter aus beispielsweise einer Logdatei rausfiltern können. Das ist ebenfalls sehr praktisch, um sicherzustellen, dass man keine Passwörter in der Vergangenheit geloggt hat, ohne dass man die Logdatei löschen muss.
Wir als b-nova werden Teller für zukünftige interne Entwicklungsprojekte auf jeden Fall in Betracht ziehen. Stay tuned! 😄