diff --git a/chapters/einleitung/problemstellung.tex b/chapters/einleitung/problemstellung.tex index 86def8a..7aa59cb 100644 --- a/chapters/einleitung/problemstellung.tex +++ b/chapters/einleitung/problemstellung.tex @@ -6,7 +6,7 @@ In der Arbeitsumgebung des Partnerunternehmens besteht zum Zeitpunkt der Themenfindung der hier beleuchteten Arbeit kein Management für Secrets und Logindaten zwischen Entwickler*innen. Logindaten zu den Projekten des Unternehmens liegen schlicht in einem \ac{1P}-Vault. \ac{1P} ist der vom Unternehmen verwendete Passwortmanager. Auf diesen Vault haben sämtliche internen Entwickler*innen Zugriff, jedoch keine externen Entwickler*innen. -Das ist so, weil anderenfalls Lesezugriff auf sämtliche Einträge dieses Vaults gegeben werden müssten. +Der Grund dafür ist, dass anderenfalls Lesezugriff auf sämtliche Einträge dieses Vaults gegeben werden müssten. \ac{1P} unterstützt keine Freigaben einzelner Einträge an andere Nutzer, ohne diese Einträge in einen eigenen Vault zu kopieren. Würden diese manuell in einen eigenen Vault kopiert werden, müssten diese Einträge fortan redundant gepflegt werden. Das ist eine Fehlerquelle, die zu asynchronen Einträgen führt. Außerdem ist das ein großer Arbeitsaufwand. diff --git a/chapters/technische-umsetzung/main.tex b/chapters/technische-umsetzung/main.tex index 97fead2..f45862d 100644 --- a/chapters/technische-umsetzung/main.tex +++ b/chapters/technische-umsetzung/main.tex @@ -57,9 +57,9 @@ Letztendlich entschied sich der Stakeholder gegen die Umsetzung der \ac{MASA}, d Aufwändig betrachtet wird und für den durch sie erbrachten Vorteil zu viel Aufwand und Angriffsfläche schaffen würde. \subsubsection{Ansatz 3} -Der letzte Lösungsansatz befasst sich mit dem Erstellen dedizierter Vaults für jede*n Entwickler*in $e$. -Hierbei existiert eine Python-Toolbox, die anhand eine Yaml-Datei Referenzen auf diese Passwort-Einträge -in $\text{Vault}_e$ legt und von dort entfernt, wenn ein solcher Zugriff laut der Yaml-Datei nicht mehr vorgesehen ist. +Der letzte Lösungsansatz befasst sich mit dem Erstellen dedizierter Vaults für jede*n Entwickler*in $d$. +Hierbei existiert eine Python-Toolbox, die anhand einer Yaml-Datei Referenzen auf diese Passwort-Einträge +in $\text{Vault}_d$ legt und von dort entfernt, wenn ein solcher Zugriff laut der Yaml-Datei nicht mehr vorgesehen ist. Diese Einträge können über feste Eintrags-IDs und über Regex bezogen auf die Eingrags-Titel einem/r Entwickler*in vorgesehen werden. \begin{nicepic} @@ -113,7 +113,7 @@ und auf welche nicht, übernimmt \textit{sync-dev-vault.py}. Die Funktionen der Die Funktionsweise des Programmes ist wie folgt: \begin{enumerate} \item{Wende die Schritte $2..n$ auf alle zu synchronisierenden Entwickler*innen $d \in D$ an.} - \item{Lösche alle Einträge in $e_d \in d$.} + \item{Lösche alle Einträge $e_d \in d$.} \item{Kopiere alle vorgesehenen Einträge $e_m \in \text{Master-Vault}$ nach $d$ und ergänze das Feld \enquote{Originale Eintrags-ID} mit dem \ac{UUID} von $e_m$.} \item{Erstelle ein ID-Mapping-Objekt von $e_d$ zu $e_m$ in $d$.} \end{enumerate} @@ -122,33 +122,32 @@ Die Funktionsweise des Programmes ist wie folgt: \subsubsection{Performanzprobleme und Optimierung} Eine Schwierigkeit, die sich im Rahmen der Umsetzung offenbart hat, ist, dass das \ac{1P}-CLI sehr langsam ist. Soll die Liste aller Einträge eines Vaults ausgelesen werden, dauert das nach Erfahrungen des Autors etwa eine Sekunde, da es sich hierbei um \emph{eine} Anfrage handelt. -Diese Listenansicht zeigt jedoch nur begränzte Informationen der Einträge. -Möchte man ein bestimmtes Feld eines Eintrages \(z.B. \enquote{Originale Eintrags-ID}\) in Erfahrug bringen, müssen alle Informationen eines Eintrages -abgefragt werden. Hier ist ein CLI-API-Aufruf pro Eintrag erforderlich. Sind einem*r Entwickler*in z.B. 30 Einträge zugeordnet, so dauert das Finden eines Eintrags +Diese Listenansicht zeigt jedoch nur begrenzte Informationen der Einträge. +Soll ein bestimmtes Feld eines Eintrages (z.B. \enquote{Originale Eintrags-ID}) in Erfahrug gebracht werden, müssen alle Informationen \textit{eines} Eintrages +abgefragt werden. Hier ist \textit{ein} CLI-API-Aufruf pro Eintrag erforderlich. Sind einem*r Entwickler*in z.B. 30 Einträge zugeordnet, so dauert das Finden eines Eintrages mit einer bestimmten originalen ID im Durchschnitt $n=30; \frac{n}{2} = 15$ Sekunden. Im langsamsten Fall wären es $n=30$ Sekunden. -Ein Kopierforgang stellt zwei Aufrufe dar (=\textit{lesen,erstellen}), also dauert das Kopieren von 30 Einträgen $n=30; 2n = 60$ Sekunden. -Das \ac{1P}-CLI kann zwar für Detail-Aufrufe mehrere Eintrags-IDs auf Standard-Input annehmen und bearbeiten, jedoch zeigen Versuche des Autors dies zu implementieren, dass das nicht die -Zeitkomplexität von $O(n)$ verändert. Das heißt, eine Anfrage für 10 Einträge zu stellen, dauert in etwa zehn mal so lange, +Ein Kopiervorgang stellt zwei Aufrufe dar (=\textit{lesen,erstellen}), also dauert das Kopieren von 30 Einträgen $n=30; 2n = 60$ Sekunden. +Das \ac{1P}-CLI kann zwar für Detail-Aufrufe mehrere Eintrags-IDs auf Standard-Input annehmen und bearbeiten, jedoch zeigen Versuche des Autors, dass das nicht die benötigte Zeit pro Eintrag beeinflusst. Das heißt, eine Anfrage für zehn Einträge zu stellen, dauert in etwa zehn mal so lange, wie zehn Anfragen für jeweils einen Eintrag zu stellen. - -Eine spätere Ergänzung, um die programmatische Auslesung der Einträge in $O(n)$ anstatt $O(n^2)$ zu gewährleisten, ist die Unterhaltung von Mapping-Objekten in Entwickler*innen-Vaults. +\\ +\\ +Die naive Herangehensweise, um einen Eintrag einer bestimmten originalen \ac{UUID} zu finden, ist es, jeden Eintrag auf dessen originale \ac{UUID} zu prüfen, bis der passende Eintrag gefunden wurde. +Diese Lösungsweg hat eine Zeitkomplexität von $O(n^2)$. +Eine spätere Ergänzung, um die programmatische Auslesung der Einträge einer bestimmten originalen \ac{UUID} in $O(n)$ anstatt $O(n^2)$ zu gewährleisten, ist die Unterhaltung von Mapping-Objekten in Entwickler*innen-Vaults. Je Entwickler*innen-Vault wird abschließend der Synchronisierung ein Mapping-Objekt erstellt. Diese Mapping-Objekte halten die Informationen vorrätig, welche öffentliche \ac{1P}-\ac{UUID} zu welcher privaten \ac{1P}-\ac{UUID} gehört. -Ohne diese Mapping-Objekte müssten für jeden Eintrag in Entwickler*innen-Vaults der nach einer öffentlichen \ac{UUID} identifiziert wird (=Fremdschlüssel \enquote{Originale Eintrags-ID}), alle Einträge im Entwickler*innen-Vault -abgefragt werden, bis ein Eintrag mit \enquote{Originaler Eintrag-ID = } gefunden wird. -Mit diesen Mapping-Objekten kann ein beliebiger Eintrag anhand einer öffentlichen ID +Mit diesen Mapping-Objekten kann ein beliebiger Eintrag anhand einer öffentlichen \ac{UUID} binnen zwei Anfragen erfasst werden: Anfragen des Mapping-Objektes und Anfragen des privaten Objektes. Das entspricht einer Zeitkomplexität von $O(2n) = O(n)$. - Desweiteren kann \ac{1P} Eintragsdaten lokal zwischenspeichern. -Diese Option lässt sich mit dem Flag \textit{--cache} auf Leseoperationen verwenden +Diese Option lässt sich mit dem Flag \textit{--cache} auf Leseoperationen anwenden und beschleunigt das Auslesen der angefragten Informationen, soweit diese im Cache existieren. Auf Unix-ähnlichen Betriebssystemen ist dieses Verhalten standardmäßig aktiviert. \cite{bib:1password-cli-caching} \subsubsection{Sicherheitsbedenken} -Die Konfigurationsdatei definiert Zielvaults, nach ihren \acp{UUID}. Anhand dieser IDs sieht ein*e Administrator*in keine Vaultnamen. -Wenn nun aus etwaigen Gründen dort die ID eines Nutzvaults des Partnerunternehmems aufgeführt wäre, würde das +Die Konfigurationsdatei definiert Entwickler*innen-Vaults, über ihre \acp{UUID}. In diesen IDs sieht ein*e Administrator*in keine Vaultnamen. Diese sind nicht sprechend. +Wenn nun aus etwaigen Gründen dort die \ac{UUID} eines Nutzvaults des Partnerunternehmems aufgeführt wäre, würde das Werkzeug alle sich dort befindlichen Zugänge löschen. Das wäre ein Super-GAU in Form von Datenverlust. \subsubsection{Sicherheitsvorkehrungen} @@ -158,7 +157,7 @@ Wenn diese Vault-ID nun in der Liste der fest kodierten Nutzvault-IDs vorkommt, Somit ist gewährleistet, dass selbst bei einer fatalen Fehlkonfiguration kein Datenverlust entseht. \section{Integration in Ansible} -Es ist Anforderung, dass \ac{1P}-Einträge von Entwickler*innen innerhalb von Ansible-Playbooks +Eine Anfordergung beschreibt, dass \ac{1P}-Einträge von Entwickler*innen innerhalb von Ansible-Playbooks dereferenziert und verwendet werden können. \ac{1P} unterstützt nativ das Ersetzen von \ac{1P}-Referenzen in Dateien durch Secrets. @@ -192,11 +191,13 @@ Ab hier wird die Nutzergruppe \enquote{Entwickler*innen} in zwei Untergruppen st Falls der*die jeweilige Entwickler*in Zugriff auf einen verlinkten Eintrag hat, dann nur auf eine Kopie des Eintrages in dessen*deren jeweiligen Entwickler*innen-Vaults. Diese Kopie hat eine andere \ac{UUID} als die, die in der Host-Konfiguration steht. Sie ist ja auf technischer Ebene ein anderer Eintrag, nur mit identischem Inhalt. Die in den Host-Konfigurationen vermerkten, öffentlichen \acp{UUID} müssen also zunächst in eine private, sich im Entwickler*innen-Vault befindliche, \ac{UUID} übersetzt werden. - Hierfür besitzen \end{description} -Um diese Problemstellung anzugehen, wird ein Ansible Filtermodul entworfen. Ein Filtermodul dient als -Texttransformator und kann in Jinja-Templates, wie sie von Ansible verwendet werden, wie folgt verwendet werden:\\ +Um diese Problemstellung anzugehen, wird ein Ansible Filtermodul entworfen. +Ein Filtermodul dient als +Texttransformator und kann in Ansible verwendet werden. +\\ +\\ \texttt{\{\{\ \enquote{hello world} | uppercase \}\}}.\\ \cite{bib:ansible-filter-plugins} Dieses Beispiel führt das \enquote{uppercase}-Filtermodul an. diff --git a/dexes/glossarydex.tex b/dexes/glossarydex.tex index c549252..2c5f6f2 100644 --- a/dexes/glossarydex.tex +++ b/dexes/glossarydex.tex @@ -9,6 +9,11 @@ Eine Gruppierung an Daten, die einen Login ermögliche. Z.B. $(\text{Nutzername},\text{Passwort})$. Eine solche Struktur kann bein \ac{1P} aus beliebig vielen Schlüsselwertpaaren bestehen. Wird in dieser Ausarbeitung synonym zu 'Secret' verwendet. \item [(1P-)Vault] \hfill \\ Eine Kollektion an Secret-Einträgen in einem Passwort-Manager (1Password). + \item [Nutzvault] \hfill \\ + Ein 1P-Vault, in dem die originalen Einträge des Partnerunternehmens verortet sind. Hier liegen keine Kopien, sondern Originale! + \item [Entwickler*innen-Vault] \hfill \\ + Ein 1P-Vault, in dem die Kopien bzw. Referenzen auf Einträge des Partnerunternehmens verortet sind. Hier liegen nur Kopien bzw. Referenzen! + Der Sinn eines solchen Vaultes ist es, Entwickler*innen beschränkten Lesezugriff auf Daten der Nutzvaults zu gewähren. \item [Ansible-Playbook/s] \hfill \\ Ansible-Playbooks sind Skripte, mit dem Ziel einen deklarierten Zustand herzustellen. \cite{bib:ansible} \item [Docker] \hfill \\ diff --git a/images/dev-stuff-via-api-keys.png b/images/dev-stuff-via-api-keys.png index e721387..7a2eb9f 100644 Binary files a/images/dev-stuff-via-api-keys.png and b/images/dev-stuff-via-api-keys.png differ diff --git a/main.pdf b/main.pdf index 0c04002..c1d0f3c 100644 Binary files a/main.pdf and b/main.pdf differ