Compare commits
43 Commits
c53cbdaf93
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
bd2096f494
|
|||
|
09781d02c2
|
|||
|
8a3210bc3c
|
|||
|
df86b1cf95
|
|||
|
fad8920281
|
|||
|
5a0ae52ce0
|
|||
|
07ede6ab3a
|
|||
|
c87deb721d
|
|||
|
45ad50de47
|
|||
|
19d3a869e6
|
|||
|
1852c52bd8
|
|||
|
d4d8c5de18
|
|||
|
dce211db0c
|
|||
|
897ab23fda
|
|||
|
df208d2dd7
|
|||
|
efb8de0aeb
|
|||
|
f49a991c36
|
|||
|
226b4204fb
|
|||
|
bc6f0dbc1a
|
|||
|
818809a16f
|
|||
|
3d33e0c536
|
|||
|
c5675e8ef6
|
|||
|
e1465aa3f4
|
|||
|
61c30e6af5
|
|||
|
16b10d9f87
|
|||
|
fc5911df8c
|
|||
|
d0a48376e0
|
|||
|
f3a1cb1ea9
|
|||
|
7950098865
|
|||
|
75d3e82db5
|
|||
|
8c88e3a1f2
|
|||
|
01a0a603d3
|
|||
|
edaee1db5a
|
|||
|
13184d1c6e
|
|||
|
89c871f9cb
|
|||
|
|
c9bba59d43 | ||
|
|
ff01f03e11 | ||
|
|
7ee53418fd | ||
|
|
ce4c4045cc | ||
|
6a2fa002e3
|
|||
|
6bf893ee0f
|
|||
|
d61e410048
|
|||
|
7153c2bd01
|
@@ -4,4 +4,6 @@
|
||||
|
||||
\begin{appendices}
|
||||
\input{appendix/interview-jochen}
|
||||
\input{appendix/ideensammlung}
|
||||
\input{appendix/old-relation-diagram}
|
||||
\end{appendices}
|
||||
|
||||
9
appendix/ideensammlung.tex
Normal file
@@ -0,0 +1,9 @@
|
||||
\chapter{Ideensammlung}
|
||||
\label{app:ideensammlung}
|
||||
|
||||
\begin{nicepic}
|
||||
\includegraphics[width=0.75\textwidth]{images/ideensammlung.jpg}
|
||||
\captionof{figure}{Ideensammlung}
|
||||
\caption*{Quelle: Eigene Darstellung}
|
||||
\label{fig:ideensammlung}
|
||||
\end{nicepic}
|
||||
@@ -1,4 +1,84 @@
|
||||
\chapter{Stakeholder-Interview}
|
||||
\label{app:stakeholder-interview}
|
||||
|
||||
\textbf{!!!TODO TODO TODO ADD APPENDIX INTERVIEW!!!}
|
||||
\textbf{Anforderungserfassung 1Password-Berechtigungsverwaltung}\\
|
||||
\textbf{und -Schnittstelle} \\
|
||||
\textbf{16.10.2024 und 23.10.2024, Bad Dürkheim} \\
|
||||
\textbf{Teilnehmer: Leon Etienne, Jochen Stange} \\
|
||||
|
||||
\textbf{Frage:} Was sind die Aufgabenbereiche von externen Entwickler*innen?
|
||||
\begin{quote}
|
||||
Externe steigen z.B. für die Umsetzung großer Projekte ein und arbeiten in diesem Umfang mit uns in agilen Entwicklungsprozessen wie z.B. Scrum.
|
||||
Je nach dem Projekt braucht man da schon einige Zugänge.
|
||||
Es kommt aber auch vor, dass Entwickler wie \emph{<Name geschwärzt>} selbstständig Projekte umsetzen, gegebenfalls auch kleine Projekte.
|
||||
Die brauchen dann eigentlich nur den Backend-Login. Den können wir auch auch mailen.
|
||||
Es war aber auch schon im Diskurs TYPO3-Upgrades outzusourcen. Das ist sowieso undankbare Arbeit und wir wären froh, das aus den Füßen zu haben.
|
||||
Da müssten wir schon einige Zugänge übermitteln.
|
||||
\end{quote}
|
||||
|
||||
\textbf{Frage:} Und wieso lagern wir solche Upgrades nicht schon aus?
|
||||
\begin{quote}
|
||||
Naja die dafür zuständigen Dienstleister brauchen dafür unser Docker-Ansible. Das können wir aber nicht rausgeben, das ist ja voll mit Email und Datenbankzugängen.
|
||||
Wir sind ja schon lange dran das zu fixen, nur wir kommen wir nie so wirklich dazu.
|
||||
\end{quote}
|
||||
|
||||
|
||||
\textbf{Frage:} Könntest du dir vorstellen, diese Zugänge in unseren Passwortmanager auszulagern? Damit könnten wir die Berechtigungsverwaltung an 1Password abgeben.
|
||||
\begin{quote}
|
||||
Sicher, wenn Ansible dann noch drankommt, klingt das gangbar. Wie funktioniert die Berechtigungsverwaltung da überhaupt?
|
||||
\clearpage
|
||||
\emph{<Es wird gemeinsam durch die administrative 1Password-Oberfläche gestöbert>}
|
||||
\\
|
||||
\\
|
||||
Mh. Ich finde nur Berechtigungen, um Vaults freizugeben, nicht aber für einzelne Einträge.
|
||||
Wir haben doch eigentlich durch unseren relativ teuren Tarif Zugang zu Live-Support.
|
||||
Ich stelle nachher mal eine Support-Anfrage. Die sollen mir erklären, wie das geht. Muss ja gehen.
|
||||
\\
|
||||
\\
|
||||
\emph{<Das Interview wird bis nach dem Support-Zoom-Call mit 1Password pausiert>}
|
||||
\\
|
||||
\\
|
||||
Leon, das glaubst du nicht. Das geht wirklich nicht. Man kann nur ganze Vaults freigeben.
|
||||
Man kann noch nicht mal Verknüpfungen auf einzelne Einträge in diesen erstellen. Wenn wir jetzt \emph{<Name geschwärzt>} Zugang auf 2 oder 3 Einträge geben wollten, müssten wir die von Hand kopieren und ab dann
|
||||
doppelt Pflegen. Das ist ja unglaublich.
|
||||
\end{quote}
|
||||
|
||||
\textbf{Frage:} Ich verstehe. Und wenn wir je Projekt einen Vault erstellen würden?
|
||||
\begin{quote}
|
||||
Dann müssten wir ja den ganzen Passwortmanager umbauen. Außerdem haben wir über 200 Projekte. Mit so vielen Vaults würde sich
|
||||
niemand mehr zurecht finden. Lass das mal lieber sein.
|
||||
\end{quote}
|
||||
|
||||
\textbf{Frage:} Ich lasse mir etwas einfallen. Klingt, als müssten wir etwas eigenes bauen. Wäre es OK, wenn wir Zugänge in YAML definieren?
|
||||
\begin{quote}
|
||||
Solange es mit etwas technischem Know-How nicht zu aufwändig zu pflegen ist, gerne.
|
||||
Ich will aber nicht, dass wir nachher für jedes Projekt 20 Einträge einzeln jedem Entwickler zuweisen müssen. Das muss projektbasiert gehen.
|
||||
Trotzdem muss es aber funktionieren, dass wir projektunabhängige Einträge so zuweisen können. Für interne Werkzeuge z.B.
|
||||
\end{quote}
|
||||
|
||||
\textbf{Frage:} Vlt. könnten wir Wildcards verwenden, um die Eintragstitel zu durchsuchen? Die sind bei uns ja sehr einheitlich.
|
||||
\begin{quote}
|
||||
Klingt pragmatisch. Da kann man dann notfalls auch komplette Eintragstitel reinschreiben, oder?
|
||||
Die Einträge, auf die so eine Wildcard passt, werden dann der Entwicklerin zugewiesen.
|
||||
\end{quote}
|
||||
|
||||
\textbf{Frage:} Ja, das würde gehen. Vlt wären aber 1Password-IDs eindeutiger. Das wäre auch kein nennenswerter Mehraufwand
|
||||
\begin{quote}
|
||||
Ok, dann nimm das noch mit dazu. Aber nicht anstatt.
|
||||
Äh und noch was. Das ist ja nicht nur für Ansible. Wir würden damit ja auch Accountzugänge verteilen. Wie sollen die Entwickler das dann einsehen? Über das Terminal wäre das sehr unhandlich.
|
||||
\end{quote}
|
||||
|
||||
\textbf{Frage:} Wenn wir Entwicklern eigene Vaults geben würden, in die Einträge hinenkopiert werden, könnten sie die Einträge in der 1P App einsehen.
|
||||
\begin{quote}
|
||||
Klingt gut. Aber müssen wir die dann nicht doch wieder doppelt pflegen?
|
||||
\end{quote}
|
||||
|
||||
\textbf{Frage:} Nein, ich würde einen Mechanismus bauen, der sich darum kümmert, diese Vaults aktuell zu halten. Wenn überhaupt müssen wir einen Sync-Prozess anstoßen. Passt das?
|
||||
\begin{quote}
|
||||
Wenn du das so hinkriegst, wäre das gut. Zwar nicht ideal, aber 1P scheint ja nicht mehr herzugeben.
|
||||
\end{quote}
|
||||
|
||||
\textbf{Frage:} Super. Wenn du sonst keine Fragen oder Anregungen mehr hast, würde ich gleich damit loslegen :)
|
||||
\begin{quote}
|
||||
Im Moment nicht. Ich melde mich wenn doch.
|
||||
\end{quote}
|
||||
|
||||
10
appendix/old-relation-diagram.tex
Normal file
@@ -0,0 +1,10 @@
|
||||
\chapter{Relationsdiagramm (Überholt)}
|
||||
\label{app:old-relation-diagram}
|
||||
|
||||
\begin{nicepic}
|
||||
\includegraphics[width=0.75\textwidth]{images/old-usage-diagram.jpg}
|
||||
\captionof{figure}{Relationsdiagramm: (Überholt) Relationsdiagramm}
|
||||
\caption*{Quelle: Eigene Darstellung}
|
||||
\label{fig:relationsdiagramm-old}
|
||||
\end{nicepic}
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
\input{chapters/anforderungen.tex}
|
||||
\input{chapters/technische-umsetzung/main.tex}
|
||||
|
||||
\input{chapters/evaluation.tex}
|
||||
\input{chapters/fazit.tex}
|
||||
\input{chapters/evaluation-fazit.tex}
|
||||
\input{chapters/ausblick.tex}
|
||||
|
||||
|
||||
@@ -7,15 +7,16 @@
|
||||
\section{Anforderungserfassung}
|
||||
Obwohl bereits vor Beginn des Projektes einige Anforderungen bekannt sind,
|
||||
müssen manche Details nachträglich in Erfahrung gebracht werden.
|
||||
Hierfür wurde ein semistrukturiertes Interview mit dem Stakeholder durchgeführt.
|
||||
Im Rahmen dieses Interviews wurden vorbereitete Fragen gestellt, dem Stakeholder aber auch die Möglichkeit
|
||||
gegeben frei heraus zu sprechen und Wünsche zu äußern.
|
||||
Notizen zu diesem Interview befinden sich im Anhang unter
|
||||
Hierfür wurde ein informelles Interview mit dem Stakeholder durchgeführt.
|
||||
Im Rahmen dieses Interviews wurde frei gesprochen.
|
||||
Eine Mitschrift dieses Interviews befinden sich im Anhang unter
|
||||
\fullref{app:stakeholder-interview}.
|
||||
|
||||
\section{Ergebnisse}
|
||||
Das Ergenis der Anforderungserfassung ist ein Lastenheft, das in constraints, funktionale und
|
||||
nicht-funktioniale Anforderungen zu unterteilen ist.
|
||||
Das Ergebnis der Anforderungserfassung ist ein Lastenheft, das in Constraints, funktionale und
|
||||
nicht-funktioniale Anforderungen unterteilt ist. Im Zuge des Interviews und diversen anderen, ad-hoc geführten Gesprächen,
|
||||
hat sich der Autor ein tiefes Verständnis für das vorliegende Problem des Auftraggebers angeignet.
|
||||
Das untenstehende Lastenheft wurde mit dem Stakeholder besprochen und bestätigt.
|
||||
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
@@ -23,21 +24,25 @@ nicht-funktioniale Anforderungen zu unterteilen ist.
|
||||
\begin{tabular}{|p{14cm}|}
|
||||
\hline
|
||||
\textbf{Funktionale Anforderungen} \\ \hline
|
||||
Entwickler erhalten verschiedene Zugänge, definiert in einer YAML-Datei. \\ \hline
|
||||
Wildcard-Matching auf den \ac{1P}-Eintragstitel für zusammenhängende Einträge. \\ \hline
|
||||
\ac{1P}-Einträge sollen einzeln zuweisbar sein. \\ \hline
|
||||
Nicht im YAML gelistete Zugänge sollen bei Anwendung entfernt werden. \\ \hline
|
||||
Ansible Secrets müssen aus 1Password dereferenziert werden können. \\ \hline
|
||||
Entwickler*innen erhalten verschiedene Zugänge zu verschiedenen \ac{1P}-Einträgen (Zugänge),
|
||||
definiert in einer YAML-Datei. \\ \hline
|
||||
Wildcard-Matching auf den \ac{1P}-Eintragstitel. \\ \hline
|
||||
\ac{1P}-Einträge sollen Entwicklern*innen einzeln zuweisbar sein. \\ \hline
|
||||
Nicht in der Konfiguration gelistete Zugänge sollen bei Anwendung entfernt werden. \\ \hline
|
||||
Ansible-Secrets müssen aus \ac{1P} dereferenziert werden können. \\ \hline
|
||||
Einträge sollen für Entwickler*innen einsehbar sein. \\ \hline
|
||||
\textbf{Nicht-funktionale Anforderungen} \\ \hline
|
||||
Das System muss Berechtigungen von Entwicklern verwalten. \\ \hline
|
||||
Das System muss Berechtigungen von Entwickler*innen verwalten. \\ \hline
|
||||
Das System muss benutzerfreundlich sein. \\ \hline
|
||||
Das System darf nicht aufwändig zu pflegen sein. \\ \hline
|
||||
Die benötigte Zeit zur Ausführung der Anwendung soll nicht sehr lange sein. \\ \hline
|
||||
Das System muss robust gegenüber Misskonfigurationen sein, die zur Lösung von\\
|
||||
den zugrunde liegenden \ac{1P}-Einträgen führen könnten.\\ \hline
|
||||
Das System muss einfach zu pflegen sein. \\ \hline
|
||||
Die benötigte Zeit zur Ausführung der Anwendung soll angemessen lange sein. \\ \hline
|
||||
Das System muss robust gegenüber Misskonfigurationen sein, die zur Löschung
|
||||
der zugrunde liegenden \ac{1P}-Einträge führen könnten.\\ \hline
|
||||
\textbf{Constraints} \\ \hline
|
||||
Nutzung von 1Password ist zwingend erforderlich. \\ \hline
|
||||
Nutzung von \ac{1P} ist zwingend erforderlich. \\ \hline
|
||||
Die Übermittlung der Secrets muss über das Internet erfolgen. \\ \hline
|
||||
\end{tabular}
|
||||
\caption{Anforderungen}
|
||||
\caption{Lastenheft}
|
||||
\label{tbl:lastenheft}
|
||||
\end{table}
|
||||
|
||||
|
||||
16
chapters/ausblick.tex
Normal file
@@ -0,0 +1,16 @@
|
||||
%
|
||||
% Chapter: Evaluation
|
||||
%
|
||||
|
||||
% Let chapter stay on the same page
|
||||
\begingroup
|
||||
\let\clearpage\relax
|
||||
|
||||
\chapter{Ausblick}
|
||||
Auf diese Umsetzung aufbauend sollten die bestehenden Ansible-Roles im Docker-Ansible-Repository
|
||||
des Partneruntehmens so angepasst werden, dass diese das \textit{resolve\_1p\_secret} Filtermodul verwenden.
|
||||
Ebenso sollte das bestehende Inventar an Host-Konfigurationsdateien migriert werden, sodass diese keine Klartext-Secrets mehr beinhalten,
|
||||
sondern diese nach \ac{1P} ausgelagert werden und die Host-Konfigurationsdateien lediglich eine IT-sicherheitstechnisch unbedenkliche Referenz auf \ac{1P}-Einträge
|
||||
aufweisen.
|
||||
|
||||
\endgroup
|
||||
@@ -7,5 +7,5 @@ Einige Anforderungen sind bereits im Voraus definiert.
|
||||
Weiterführende Anforderungen werden im Rahmen einer Anforderungserfassung ermittelt.
|
||||
Anschließend werden verschiedene Lösungsansätze betrachtet und auf Tauglichkeit geprüft.
|
||||
Nachdem ein akzeptabler Lösungsweg gefunden ist, wird dieser umgesetzt.
|
||||
Abschließend wird der Erfolg des Unterfanges evaluiert und mögliche, auf dieses Projekt aufbauende Arbeiten in Ausblick gestellt.
|
||||
Abschließend wird der Erfolg des Unterfangens evaluiert und mögliche, auf dieses Projekt aufbauende.
|
||||
|
||||
|
||||
@@ -4,19 +4,18 @@
|
||||
|
||||
\section{Problemstellung}
|
||||
In der Arbeitsumgebung des Partnerunternehmens besteht zum Zeitpunkt der Themenfindung der hier beleuchteten Arbeit kein
|
||||
Management für Secrets und Logindaten zwischen Entwicklern. 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 interne Entwickler Zugriff, jedoch keine externen Entwickler.
|
||||
Das ist so, weil anderenfalls dem externen Entwickler Lesezugriff auf sämtliche Einträge dieses Vaults gegeben werden müssten.
|
||||
Management für Secrets und Logindaten zwischen Entwickler*innen. Logindaten zu den Projekten des Unternehmens liegen in einem großen \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.
|
||||
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.
|
||||
All das gestaltet das Einbinden von externen Entwicklern, wie z.B. Freelancern, schwer.
|
||||
All das gestaltet das Einbinden von externen Entwickler*innen, wie z.B. Freelancer*innen, schwer.
|
||||
\\
|
||||
\\
|
||||
Ein weiteres Problem ist, dass Secrets in Konfigurationsdateien, die firmeninternen Ansible-Scripten
|
||||
beilegen, unverschlüsselt einsichtig sind. Das macht es zu einem großen Sicherheitsrisiko und somit
|
||||
impraktikabel externen Entwicklern Zugriff auf dieses Ansible-Repository zu gewähren.
|
||||
inpraktikabel externen Entwickler*innen Zugriff auf dieses Ansible-Repository zu gewähren.
|
||||
Dieses Ansible-Repository ist jedoch zwingend erforderlich, um eine Entwicklungsungebung für
|
||||
Firmenprojekte auf dem lokalen Rechner zu schaffen. Auch hier sind Lösungen für externe
|
||||
Entwickler zumeist unschöne Workarounds.
|
||||
|
||||
Entwickler*innen zumeist unschöne Workarounds.
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
%
|
||||
|
||||
\section{Zielsetzung}
|
||||
Ziel ist es, eine Umgebung zu schaffen, in der beliebigen Entwicklern bestimmte
|
||||
Ziel ist es, eine Umgebung zu schaffen, in der beliebigen Entwicklern*innen bestimmte
|
||||
\ac{1P}-Einträge zugewiesen werden können.
|
||||
Der Pflegeaufwand sollte hierbei überschaubar bleiben.
|
||||
Das heisst, dass z.B. ganze Gruppen von Einträgen Entwicklern zugewiesen werden können.
|
||||
Wenn z.B. einem Projekt viele Einträge zugeordnet sind, sollten diese idealerweise mit einer einzigen Configzeile
|
||||
einem Entwickler zugeordnet werden können.
|
||||
Das heisst, dass z.B. ganze Gruppen von Einträgen Entwickler*innen zugewiesen werden können.
|
||||
Wenn z.B. einem Projekt viele Einträge zugeordnet sind, sollten diese idealerweise mit einer einzigen Konfigurationszeile
|
||||
einem*r Entwickler*in zugeordnet werden können.
|
||||
Außerdem sollte eine Möglichkeit ausgearbeitet werden, um \ac{1P}-Einträge in Ansible auszulesen,
|
||||
damit keine Secrets mehr in den beiliegenden Konfigurationsdateien stehen, die das Freigeben
|
||||
dieser zu einem Sicherheitsproblem machen.
|
||||
|
||||
30
chapters/evaluation-fazit.tex
Normal file
@@ -0,0 +1,30 @@
|
||||
%
|
||||
% Chapter: Evaluation
|
||||
%
|
||||
|
||||
\chapter{Evaluation und Fazit}
|
||||
Das abschließende Ergebnis des in dieser Ausarbeitung dokumentierten Projektes
|
||||
ist ein Python-Projekt, das in der Lage ist, anhand einer Berechtigungs-Konfigurationsdatei im Yaml-Format
|
||||
\ac{1P}-Einträge in Entwickler*innen-Vaults zu kopieren, zu löschen und deren Referenz zu den originalen Einträgen zu wahren.
|
||||
Diese Berechtigungs-Konfigurationsdatei unterstützt das Erfassen von Berechtigungen über Wildcard-Matching sowie über einzelne
|
||||
\ac{UUID}-Zuweisungen. Diese Einträge können Entwickler*innen anschließend in der \ac{1P}-GUI-Anwendung einsehen.\\
|
||||
Das Synchronisations-Werkzeug verweigert Anfragen, die zur Löschung von originalen Einträgen führen könnten.
|
||||
\\
|
||||
\\
|
||||
Ebenso ist Teil des Ergebnisses ein Ansible-Filtermodul, das in der Lage ist, unsensible \ac{1P}-Referenzen
|
||||
in Host-Konfigurationsdateien aus \ac{1P} zu dereferenzieren, sowohl als interne*r Entwickler*in ohne Entwickler*innen-Vault,
|
||||
als auch als externe*r Entwickler*in mit
|
||||
Entwickler*innen-Vault. Das geschiet in einer IT-sicherheitstechnich unbedenklichen
|
||||
und performanten Art- und Weise.
|
||||
\\
|
||||
\\
|
||||
Hiermit ist das in \fullref{tbl:lastenheft} definierte Lastenheft des Stakeholders in Gänze erfüllt.
|
||||
Nach Vorstellung der erarbeiteten Ergebnisse vor dem Stakeholder zeigt sich sich dieser zufrieden und bestätigt die
|
||||
pragmatische Korrektheit des Produktes.
|
||||
Die hier geschaffene Technologie bringt dem Partnerunternehmen zweierlei Mehrwert:
|
||||
Einerseits können \ac{1P}-Berechtigungen nun ohne weiteres beschränkt an Praktikant*innen, neu eingestellte und externe Entwickler*innen
|
||||
vergeben werden. Darüber hinaus bereitet diese Technologie den Weg für das Partnerunternehmen,
|
||||
ihr Docker-Ansible-Repository so anzupassen, dass es keine Klartext-Secrets mehr beinhaltet.
|
||||
Das erlaubt dem Partnerunternehmen diese Toolbox mit externen Entwickler*innen und Agenturen zu teilen
|
||||
und somit Arbeit auszulagern.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
%
|
||||
% Chapter: Evaluation
|
||||
%
|
||||
|
||||
\chapter{Evaluation}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
%
|
||||
% Chapter: Fazit
|
||||
%
|
||||
|
||||
\chapter{Fazit}
|
||||
\section{Ausblick}
|
||||
\section{Offene Problemstellungen}
|
||||
|
||||
@@ -19,6 +19,9 @@ Die Arbeitsumgebung des Partnerunternehmens besteht für diese Themenstellug nen
|
||||
\label{fig:relationsdiagramm-devenv}
|
||||
\end{nicepic}
|
||||
|
||||
Die lokalen Arbeitsumgebungen der Entwickler*innen liegen großteils außerhalb des Firmennetzwerkes, da diese Entwickler*innen
|
||||
oft oder ausschließlich im mobilen- bzw, Homeoffice arbeiten. Ein Firmen-VPN-Netz existiert nicht und ist auch nicht erwünscht.
|
||||
|
||||
\section{1Password}
|
||||
\ac{1P} ist der vom Partnerunternehmen verwendete Passwort-Manager.
|
||||
Bereits vor Beginn der Bearbeitung dieser Themenstellung wurde deutlich gemacht, dass es
|
||||
@@ -30,4 +33,3 @@ im behandelten System herzustellen. \cite{bib:ansible}
|
||||
Ein Administrator definiert also nicht die erforderlichen Schritte,
|
||||
um einen Zustand $z$ zu erreichen, sondern lediglich $z$ selbst.
|
||||
Ansible kann über speziell gefertigte Python-Module um Schnittstellen erweitert werden.
|
||||
|
||||
|
||||
@@ -4,5 +4,347 @@
|
||||
|
||||
\chapter{Technische Umsetzung}
|
||||
\section{Berechtigungsverwaltung}
|
||||
\section{Integration in Ansible}
|
||||
\subsection{Ausarbeitung der Herangehensweise}
|
||||
Zunächst wurde gebrainstormed, welche Herangehensweisen hier möglich sind.
|
||||
Ein Artefakt des Brainstormings ist eine Mind-Map, die unter \fullref{app:ideensammlung} zu finden ist.
|
||||
|
||||
\subsubsection{Ansatz 1}
|
||||
Der aus dieser Mindmap, nach individueller Meinung des Autors, vielversprechenste Ansatz ist es,
|
||||
die \ac{1P}-Restful-API zu verwenden.
|
||||
Bei diesem Ansatz würden Administratoren*innen und Entwicklern*innen API-Keys für \ac{1P} erhalten.
|
||||
Entwickler*innen hätten mit ihren Keys bestimmte Leseberechtigungen $r$ und Administratoren*innen
|
||||
die Berechtigung $r$ zu verändern.
|
||||
|
||||
\begin{nicepic}
|
||||
\includegraphics[width=0.75\textwidth]{images/dev-stuff-via-api-keys.png}
|
||||
\captionof{figure}{Relationsdiagramm: Ansatz 1 | 1Password-API}
|
||||
\caption*{Quelle: Eigene Darstellung}
|
||||
\label{fig:ansatz-1-mit-api-keys}
|
||||
\end{nicepic}
|
||||
|
||||
Dieser Ansatz wurde zeitnah als unumsetzbar erkannt und verworfen, da \ac{1P} das nachträgliche Verändern
|
||||
von API-Key-Berechtigungen nicht erlaubt.
|
||||
|
||||
\subsubsection{Ansatz 2}
|
||||
Der nächste Lösungsansatz befasst sich mit einer Abstraktionsebene: Der \ac{MASA}.
|
||||
Hier ist die grundlegende Idee, dass es eine serverseitige Anwendung gibt, die sich \ac{MASA} nennt.
|
||||
Diese Anwendung übernimmt die Aufgabe anhand eines hinterlegten \ac{1P}-API-Keys Secrets
|
||||
aus dem \ac{1P}-Vault des Partnerunternehmens abzufragen und an Entwickler*innen weiterzureichen.
|
||||
Die \ac{MASA} provisioniert eigene API-Keys an Entwickler*innen und vermerkt serverseitig,
|
||||
welcher API-Key berechtigt ist, welche \ac{1P}-Einträge abzufragen.
|
||||
Der API-Key könnte grundlegende Informationen wie zum Beispiel Entwickler*innennamen und Ablaufzeitpunkte des
|
||||
Keys einbetten. Dieser Ansatz trägt viel Sicherheitsverantwortung, da eine mögliche Ausnutzung einer
|
||||
Sicherheitslücke der \ac{MASA} direkt in den Firmen-Passwortmanager führen würden.
|
||||
Um diesem Risikofaktor entgegenzuwirken würde der \ac{1P}-Key der \ac{MASA} verschlüsselt werden und die
|
||||
\ac{MASA} würde nur einen Teil des Entschlüsselungs-Keys vorrätig halten. Der andere Teil wäre in jedem Entwickler*innen-Key
|
||||
eingebettet. Dadurch wäre gewährleistet, dass ein*e Angreifer*in, selbst bei sehr weitreichendem Zugriff
|
||||
in die \ac{MASA}, nicht auf das Innere des Passwortmanagers zugreifen könne, da die \ac{MASA} dazu selbstständig
|
||||
gar nicht im Stande wäre. Da Entwickler*innen lediglich ein Schlüsselfragment des Verschlüsselungs-Schlüssels
|
||||
in ihrem Key eingebettet hätten, der einen serverseitigen Schlüssel der \ac{MASA} zum Auslesen benötigt,
|
||||
bestünde auch keine Gefahr, dass ein*e Entwickler*in anhand seines bzw. ihres Keys ungeschützten Zugang zum Passwortmanager
|
||||
erhalten würde. Dieser Ansatz erlaubt weitreichende Flexibilität, da sämtliche Logik, die sich mit Berechtigungen
|
||||
beschäftigt, anwendungsfallspezifisch geplant und umgesetzt wäre.
|
||||
|
||||
\begin{nicepic}
|
||||
\includegraphics[width=0.75\textwidth]{images/masa-diagram.png}
|
||||
\captionof{figure}{Relationsdiagramm: Ansatz 2 | MASA}
|
||||
\caption*{Quelle: Eigene Darstellung}
|
||||
\label{fig:ansatz-2-mit-masa}
|
||||
\end{nicepic}
|
||||
|
||||
|
||||
\clearpage
|
||||
Letztendlich entschied sich der Stakeholder gegen die Umsetzung der \ac{MASA}, da dieser Ansatz als zu
|
||||
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 $d$.
|
||||
Hierbei existiert eine Python-Toolbox, die anhand einer Yaml-Datei Referenzen auf die 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}
|
||||
\includegraphics[width=0.75\textwidth]{images/dev-stuff-python.png}
|
||||
\captionof{figure}{Relationsdiagramm: Ansatz 3 | Python-Toolbox}
|
||||
\caption*{Quelle: Eigene Darstellung}
|
||||
\label{fig:ansatz-3-mit-python}
|
||||
\end{nicepic}
|
||||
|
||||
Nach Betrachtung der diversen Ansätze entschied sich der Stakeholder für Ansatz 3, da er ihm kostengünstig und ausreichend erschien.
|
||||
|
||||
\subsection{Kodierung}
|
||||
Um den vom Stakeholder ausgewählten Ansatz 3 wie geplant umzusetzen, wurden zunächst
|
||||
die Dokumentationen diverser \ac{1P}-Schnittstellen konsultiert. Schnell offenbarte sich eine Alternative
|
||||
zu API-Keys: Die \ac{1P}-Desktop-Anwendung stellt eine CLI-API bereit.
|
||||
Die CLI-API der Desktop-Anwendung zu verwenden, würde drei Probleme lösen:
|
||||
\begin{description}
|
||||
\item [Kosten und hedonische Qualität] \hfill \\
|
||||
Einen API-Key zu erstellen, zu übermitteln und als Nutzer zu verorten ist kostspielig und umständlich.
|
||||
Ein \ac{1P}-Konto haben dem gegenüber viele externe Partner*innen des Partnerunternehmens bereits.
|
||||
\item [Authentifizierung und Sicherheit] \hfill \\
|
||||
Anstatt einen API-Key unsicher zu speichern und in relevante Programme (=Ansible) zu laden, wird die Authentifizierung zu \ac{1P} ausgelagert.
|
||||
\item [Manuelle Einsicht] \hfill \\
|
||||
Da über die CLI-Methode der Zugriff auf die Entwickler*innen-Vaults direkt über die \ac{1P}-Desktop-App geschieht, kann diese den Vault-Inhalt auch dem Nutzer in ihrem GUI offenbaren.
|
||||
\item [Integrationsaufwand] \hfill \\
|
||||
Die Verwendung der \ac{1P}-Restful-API erscheint dem Autor nach ihrer Dokumentation sehr aufwändig und kompliziert. Eine CLI-API zu verwenden würde somit in der Umsetzung Projektressourcen sparen.
|
||||
\end{description}
|
||||
|
||||
So begründet fällt die Wahl der Schnittstelle zu \ac{1P} auf ihre CLI-API.
|
||||
Um schnelle Softwareentwicklung mit minimalem Overhead zu gewährleisten und um für eine spätere Einbindung in Ansible
|
||||
bereits in Vorleistung zu treten, fällt die Wahl der Programmiersprache auf Python. Ansible-Module können mit Python geschrieben werden. \cite{bib:ansible-docs-python-module}
|
||||
Es wurde eine rudimentäre Architektur entworfen, die beschreibt, welche Komponente des Werkzeuges aus welchen kleineren Komponenten besteht.
|
||||
Am unteren Ende dieses Aggregatbaumes stehen atomare Operationen. Im Kontext dieses Werkzeuges sind atomare Operationen Operationen,
|
||||
die vom \ac{1P}-CLI ausgeführt werden. Diese Operationen implementiert also \ac{1P} selbst.
|
||||
Hierbei handelt es sich nur um Lese, Erstell- und Löschvorgänge. Das Erfassen, auf welchen Eintrag welche*r Entwickler*in Zugriff hat,
|
||||
und auf welche nicht, übernimmt \textit{sync-dev-vault.py}. Die Funktionen der anderen Skripte ergeben sich in Gänze aus ihren Dateinamen.
|
||||
|
||||
\begin{nicepic}
|
||||
\includegraphics[width=1\textwidth]{images/config-file.png}
|
||||
\captionof{figure}{Struktur der Zugriffs-config.yml}
|
||||
\caption*{Quelle: Eigene Darstellung}
|
||||
\label{fig:config-file}
|
||||
\end{nicepic}
|
||||
|
||||
\begin{nicepic}
|
||||
\includegraphics[width=0.75\textwidth]{images/program-structure.png}
|
||||
\captionof{figure}{Diagramm: Programmstruktur Secret-Synchronizer}
|
||||
\caption*{Quelle: Eigene Darstellung}
|
||||
\label{fig:programmstruktur-secret-synchronizer}
|
||||
\end{nicepic}
|
||||
|
||||
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 $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}
|
||||
|
||||
|
||||
\subsubsection{Performanzprobleme und Optimierung}
|
||||
Eine Schwierigkeit, die sich im Rahmen der Umsetzung offenbarte, 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 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 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.
|
||||
\\
|
||||
\\
|
||||
In der naiven Herangehensweise, um einen Eintrag einer bestimmten originalen \ac{UUID} zu finden,
|
||||
wird jeder Eintrag auf dessen originale \ac{UUID} geprüft, bis der passende Eintrag gefunden wurde.
|
||||
Dieser Lösungsweg hat für \emph{einen} Eintrag eine Zeitkomplexität von $O(n)$.
|
||||
Eine spätere Ergänzung, um das programmatische Auslesen \emph{eines} Eintrages einer bestimmten originalen \ac{UUID} in $O(1)$ anstatt $O(n)$ zu gewährleisten,
|
||||
ist die Unterhaltung von Mapping-Objekten in Entwickler*innen-Vaults.
|
||||
Je Entwickler*innen-Vault wird abschließend zur 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.
|
||||
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(2) = O(1)$.
|
||||
Desweiteren kann \ac{1P} Eintragsdaten lokal zwischenspeichern.
|
||||
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 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}
|
||||
Um das zu verhindern, wurde eine Liste mit wichtigen Vault-IDs fest einkodiert.
|
||||
Alle Erstell- oder Löschfunktionen müssen einen Vault-ID-Parameter erhalten, selbst wenn dieser technisch nicht notwendig ist.
|
||||
Wenn diese Vault-ID nun in der Liste der fest kodierten Nutzvault-IDs vorkommt, meldet die Funktion einen deskriptiven Fehler und beendet die Programmausführung.
|
||||
Somit ist gewährleistet, dass selbst bei einer fatalen Fehlkonfiguration kein Datenverlust entseht.
|
||||
|
||||
\section{Integration in Ansible}
|
||||
Eine Anfordergung beschreibt, dass \ac{1P}-Einträge von Entwicklern*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.
|
||||
Diese Technik nennt sich \enquote{\ac{1PSA}}.
|
||||
Diese Technologie ist jedoch nicht für die hier vorliegende Aufgabenstellung verwertbar, da die dem zugrunde liegende
|
||||
Berechtigungsverwaltung auf Vaults basiert. Entweder hat ein*e Entwickler*in Zugriff auf einen gesamten Vault, oder er*sie hat keinen Zugriff auf den gesamten Vault.
|
||||
Eine feinere Steuerung ist hier nicht möglich, jedoch für die hier gegebenen Anforderungen nötig. \cite{bib:1password-secrets-automation}
|
||||
\ac{1PSA} erfasst \acp{UUID} und ist daher mit dem Konzept von Entwickler*innen-Vaults inkompatibel, da
|
||||
Entwickler*innen hierbei eigene Kopien der originalen Einträge führen, die jeweils eigene \acp{UUID} haben.
|
||||
Externe Entwickler*innen haben somit keinen Zugriff auf die originalen, öffentlichen \acp{UUID} und die privaten \acp{UUID}, die im Entwickler*innen-Vault
|
||||
vorhanden sind, existieren jeweils nur für eine*n Entwickler*in. Das erfordert eine maßgeschneiderte, programmatische Lösung:
|
||||
|
||||
\begin{nicepic}
|
||||
\includegraphics[width=0.75\textwidth]{images/docker-ansible-structure.png}
|
||||
\captionof{figure}{Relationsdiagramm: Docker-Ansible-Struktur, um \ac{1P}-Einträge zu dereferenzieren}
|
||||
\caption*{Quelle: Eigene Darstellung}
|
||||
\label{fig:docker-ansible-structure}
|
||||
\end{nicepic}
|
||||
|
||||
Die hierfür angedachte Architektur erfordert, dass öffentliche \acp{UUID} in Host-Konfigurationen in Docker-Ansible aufgeführt sind.
|
||||
Also eine UUID, die für alle Entwickler*innen greifbar ist.
|
||||
|
||||
Ab hier wird die Nutzergruppe \enquote{Entwickler*innen} in zwei Untergruppen strukturiert:
|
||||
\begin{description}
|
||||
\item [Interne Entwickler*innen] \hfill \\
|
||||
Interne, festangestellte Entwickler*innen haben Vollzugriff auf \ac{1P} und somit auch Zugriff auf die
|
||||
in den Host-Konfigurationen vermerkte, öffentliche \ac{UUID} eines Eintrages.
|
||||
Da diese Entwickler*innen keinen Entwickler*innen-Vault haben, müssen sie direkt auf diese notierte, öffentliche \ac{UUID} zugreifen.
|
||||
\end{description}
|
||||
\clearpage
|
||||
\begin{description}
|
||||
\item [Externe Entwickler*innen] \hfill \\
|
||||
Externe Entwickler*innen verfügen über einen Entwickler*innen-Vault, nicht jedoch über direkten Zugriff auf die vermerkte, öffentliche \ac{UUID}.
|
||||
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-Vault.
|
||||
Diese Kopie hat eine andere \ac{UUID} als die, die in der Host-Konfiguration steht. Sie ist 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.
|
||||
\end{description}
|
||||
|
||||
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.
|
||||
Ein Beispiel mit dem im Rahmen dieser Ausarbeitung bereitgestellten Filtermodul würde so aussehen:
|
||||
\\
|
||||
\\
|
||||
\texttt{\{\{ smtp.password | resolve\_1p\_secret \}\}}.
|
||||
|
||||
\begin{nicepic}
|
||||
\includegraphics[width=1\textwidth]{images/flowchart-resolve-1p-secret.png}
|
||||
\captionof{figure}{Flussdiagramm: Businesslogik des 1P-Resolver-Filtermoduls}
|
||||
\caption*{Quelle: Eigene Darstellung}
|
||||
\label{fig:flowchart-filtermodule-resolve-1p-secret}
|
||||
\end{nicepic}
|
||||
|
||||
\subsection{Akzeptierte Formate}
|
||||
Das Filtermodul akzeptiert mehrere, verschiedene Eingabeformate und ist rückwärtskompatibel.
|
||||
|
||||
\subsubsection*{Kein erkanntes Format}
|
||||
Wird kein bekanntes Format erkannt, wird der Wert unverändert zurückgegeben.
|
||||
Das ermöglicht Rückwärtskompatibilität,
|
||||
sodass nach-wie-vor hardgecodede Secrets funktionieren, und nicht versehentlich als \ac{UUID} interpretiert werden.
|
||||
Das gewährleistet eine flüssigere Migration der Host-Konfigurationen, da somit bestehende Dateien weiterhin valide sind.
|
||||
|
||||
\subsubsection*{1P:<...>}
|
||||
Beginnt der Wert mit \enquote{1P:}, so wird alles Nachfolgende als \ac{UUID} interpretiert.
|
||||
Es wird versucht, das Feld \enquote{password} aus diesem Eintrag zu dereferenzieren.
|
||||
|
||||
\subsubsection*{Objektformat}
|
||||
Wird ein Yaml-Objekt übergeben, so werden die Keys \enquote{1P\_secret\_uuid} und \enquote{1P\_field\_id} erwartet.
|
||||
Diese definieren die Werte der Eintrags-\ac{UUID} und der Feld-ID in der ein Secret steht. Das ermöglicht z.B. auch den Benutzernamen (\textit{1P\_field\_id: username}) eines
|
||||
Eintrages abzufragen, anstelle des Passworts. Ist keine Feld-ID gegeben, so wird auf das Standardfeld \enquote{password} zurückgefallen.
|
||||
|
||||
|
||||
\subsection{Übersetzung der UUIDs}
|
||||
Um die private \ac{UUID} zu ermitteln, die zu der öffentlichen \ac{UUID} gehört, die in der Host-Konfiguration steht,
|
||||
frägt das Filtermodul den Mapping-Eintrag aus dem jeweiligen Entwickler*innen-Vault an und schlägt die öffentliche \ac{UUID} darin nach.
|
||||
Die daraus resultierende \ac{UUID} kann von einem*r externen Entwickler*in angefragt werden.
|
||||
|
||||
\subsection{Unterscheidung zwischen internen und externen Entwickler*innen}
|
||||
Ist in der Docker-Ansible-Konfigurationsdatei eine Entwickler*innen-Vault-\ac{UUID} definiert, so wird von einem*r externe*n Entwickler*in ausgegangen.
|
||||
Ist stattdessen definiert, dass die in den Host-Konfigurationen angegebenen, öffentlichen \acp{UUID} direkt angefragt werden sollen, wird
|
||||
von einem*r interne*n Entwickler*in ausgegangen. Sind beide Konfigurationen zugleich gegeben, wird ein Inkompatibilitätsfehler erhoben.
|
||||
Ist ein*e interne*r Entwickler*in angenommen, so wird der Mapping-Schritt übersprungen. Der verbleibende Prozess bleibt unberührt.
|
||||
|
||||
\subsection{Kommunikation mit 1Password}
|
||||
Ist eine \ac{UUID} ermittelt, auf die der*die Nutzer*in Zugriff hat, wird diese über das \ac{1P}-CLI angefragt.
|
||||
Dieser Aufruf ist: \textit{op item get <UUID>} mit dem Zusatz \textit{--format json}, um die Ausgabe programmatisch auswerten zu können.
|
||||
|
||||
\subsection{Performanz und Benchmarks}
|
||||
Um die Implementation zu testen, werden in einem Testszenario fünf Werte aus \ac{1P} ausgelesen:
|
||||
\begin{itemize}
|
||||
\item Datenbank-Host
|
||||
\item Datenbank-Port
|
||||
\item Datenbank-Benutzername
|
||||
\item Datenbank-Passwort
|
||||
\item Datenbank-Name
|
||||
\end{itemize}
|
||||
Diese Einträge abzufragen dauert durch das imperformante \ac{1P}-CLI 17 Sekunden.
|
||||
|
||||
\subsection{Optimierung}
|
||||
Es bieten sich zwei Möglichkeiten an, den in \fullref{fig:flowchart-filtermodule-resolve-1p-secret} abgebildeten Prozess zu beschleunigen.
|
||||
Diese beschäftigen sich damit, zu limitieren, wie oft das \ac{1P}-CLI angefragt wird:
|
||||
|
||||
\begin{description}
|
||||
\item [Das Mapping-Objekt zwischenspeichern] \hfill \\
|
||||
Anstatt das Mapping-Objekt für jedes angefragte Secret erneut abzufragen, kann es zwischengespeichert werden.
|
||||
\item [Ganze Einträge zwischenspeichern] \hfill \\
|
||||
Für den Fall, dass ein Eintrag mehrfach angefragt wird, könnte ein einmal angefragter Eintrag zwischengespeichert werden.
|
||||
Würden mehrere Felder desselben Eintrages angefragt werden (z.B. \textit{=Host, Port, Benutzername, Passwort, Name}), so müsste der gesamte Eintrag nur ein mal angefragt werden.
|
||||
\end{description}
|
||||
|
||||
All diese Ansätze erfordern es Daten zwischenzuspeichern. Filtermodule haben allerdings keinen persistenten Arbeitsspeicher über verschiedene Aufrufe hinaus.
|
||||
Also nach jedem angefragten Secret verliert das Filtermodul seinen Zustand.
|
||||
Daher muss der Zwischenspeicher eine Datei sein. Hierfür wird eine Tempdatei über Pythons \textit{tempfile.gettempdir()}-Funktion ermittelt.
|
||||
Diese Zwischenspeicher beinhalten die vom \ac{1P}-CLI zurückgegebenen Informationen.
|
||||
|
||||
\begin{nicepic}
|
||||
\includegraphics[width=1\textwidth]{images/flowchart-resolve-1p-secret-with-caching.png}
|
||||
\captionof{figure}{Flussdiagramm: Businesslogik des 1P-Resolver-Filtermoduls, mit Zwischenspeicher}
|
||||
\caption*{Quelle: Eigene Darstellung}
|
||||
\label{fig:flowchart-filtermodule-resolve-1p-secret-with-caching}
|
||||
\end{nicepic}
|
||||
|
||||
\subsubsection{Mapping-Zwischenspeicher}
|
||||
Wenn das Mapping-Objekt angefragt wird, so wird zunächst geprüft, ob es eine lokal zwischengespeicherte Version gibt.
|
||||
Falls ja, wird diese geladen und verwendet.
|
||||
Falls nein, wird es via dem \ac{1P}-CLI angefragt und lokal gespeichert.
|
||||
Sollte der Mapping-Zwischenspeicher verwendet werden und das gesuchte Objekt nicht darin gefunden werden, so wird der Zwischenspeicher gelöscht und das Mapping-Objekt neu angefragt.
|
||||
Das deckt folgenden Problemfall ab:
|
||||
|
||||
\begin{enumerate}
|
||||
\item Zwischenspeicher wird erstellt
|
||||
\item Entwickler*in erhält mehr Berechtigungen
|
||||
\item Entwickler*in will diese Berechtungen nutzen
|
||||
\item Der Zwischenspeicher wird verwendet, spiegelt diese neuen Berechtigungen aber nicht wider
|
||||
\item Der Prozess schlägt zu Unrecht fehl
|
||||
\end{enumerate}
|
||||
|
||||
Dieser Prozess würde durch diese Vorkehrung so aussehen:
|
||||
\begin{enumerate}
|
||||
\item Zwischenspeicher wird erstellt
|
||||
\item Entwickler*in erhält mehr Berechtigungen
|
||||
\item Entwickler*in will diese Berechtungen nutzen
|
||||
\item Der Zwischenspeicher wird verwendet, spiegelt diese neuen Berechtigungen aber nicht wider
|
||||
\item Das System erneuert den Zwischenspeicher
|
||||
\item Der Zwischenspeicher spiegelt nun die neuen Berechtiungen wider
|
||||
\item Der Prozess ist erfolgreich
|
||||
\end{enumerate}
|
||||
|
||||
Durch die Implementation des Mapping-Zwischenspeichers wird die Ausführzeit von 17 Sekunden auf acht Sekunden reduziert.
|
||||
|
||||
\subsubsection{Eintrags-Zwischenspeicher}
|
||||
Wird ein Eintrag von \ac{1P} angefragt, so soll das Filtermodul diesen lokal zwischenspeichern.
|
||||
Das stellt ein Problem dar, sobald der Eintrag
|
||||
im Entwickler*innen-Vault manuell verändert wird. Das ist jedoch nicht angedacht.
|
||||
Die Entwickler*innen sollten keine Schreibberechtigung auf ihren Vault haben.
|
||||
Werden originale Einträge verändert, werden die Referenzeinträge vom Synchronisierungswerkzeug gelöscht
|
||||
und neu erstellt. Damit erhalten diese eine neue \ac{UUID} und sind somit im Zwischenspeicher nicht mehr repräsentiert.
|
||||
Durch das Implementieren des Eintrags-Zwischenspeichers wird die Ausführzeit von acht Sekunden auf zwei Sekunden reduziert.
|
||||
|
||||
\begin{table}[!htbp] % !htbp
|
||||
\centering
|
||||
\begin{tabular}{|l|l|r|}
|
||||
\hline
|
||||
\textbf{Aktiviertes Caching-Level} & \textbf{Ausführzeit (Sekunden)}\\
|
||||
\hline
|
||||
Ohne Cache & 17\\
|
||||
\hline
|
||||
UUID-Mapping-Cache & 8\\
|
||||
\hline
|
||||
Mapping+Item-Cache & 2\\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\caption{Ausführzeiten des Test-Playbooks mit Testdaten (Fünf Secrets aus einem 1P-Eintrag)}
|
||||
\label{tbl:ausführzeiten-versch-caches}
|
||||
\end{table}
|
||||
|
||||
\subsubsection{Sicherheit}
|
||||
Um zu vermeiden, dass sensible Daten, wie zum Beispiel die Secrets in den Eintragsdaten des Passwortmanagers im Klartext im Zwischenspeicher, für viele Prozesse lesbar, gespeichert werden,
|
||||
werden diese in der Schreib- und Lesefunktion mit AES-256 verschlüsselt.
|
||||
Die Wahl fällt auf AES-256, weil es keine bekannten Angriffe gegen AES-256 gibt, die wesentlich effektiver als generische Angriffe gegen Blockchiffren sind. \cite{bib:BSI-TR-02102-1-2024}
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
\newcommand{\cfgDocClassification}{Projektbericht}
|
||||
|
||||
% Document version
|
||||
\newcommand{\cfgDocVersion}{1.0}
|
||||
\newcommand{\cfgDocVersion}{1.4}
|
||||
|
||||
% Last modification date
|
||||
\newcommand{\cfgDateLastModification}{21. Februar 2025}
|
||||
\newcommand{\cfgDateLastModification}{26. Februar 2025}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
\newcommand{\cfgUniversityDepartment}{Fachbereich Informatik}
|
||||
|
||||
% University degree course
|
||||
\newcommand{\cfgUniversityDegreeCourse}{Angewandte Informatik - dual (M.Sc)}
|
||||
\newcommand{\cfgUniversityDegreeCourse}{Angewandte Informatik - dual (M.Sc.)}
|
||||
|
||||
% University supervisor name
|
||||
\newcommand{\cfgUniversitySupervisorName}{Professor Dr. Heinemann}
|
||||
@@ -56,3 +56,4 @@
|
||||
|
||||
% University course name
|
||||
\newcommand{\cfgCourseName}{Deep Dive}
|
||||
|
||||
|
||||
@@ -8,9 +8,16 @@
|
||||
\begin{acronym}
|
||||
%
|
||||
%
|
||||
\acro{1PSA}[1PSA]{1Password Secrets Automation}
|
||||
\acro{1P}[1P]{1Password}
|
||||
%\acroplural{CMS}[CMSe]{Content Management Systeme}
|
||||
\acro{API}[API]{Application Programmer Interface}
|
||||
\acro{CLI}[CLI]{Command Line Interface}
|
||||
\acro{GAU}[GAU]{Größter Anzunehmender Unfall}
|
||||
\acro{GUI}[GUI]{Graphical User Interface}
|
||||
\acro{MASA}[MASA]{Medienagenten Secret Authority}
|
||||
\acro{UUID}[UUID]{Universally Unique Identifier}
|
||||
\acroplural{UUID}[UUIDs]{Universally Unique Identifiers}
|
||||
\acro{YAML}[YAML]{Yet Another Markup Language}
|
||||
%
|
||||
%
|
||||
\end{acronym}
|
||||
|
||||
|
||||
@@ -5,9 +5,41 @@
|
||||
\chapter{Glossar}
|
||||
|
||||
\begin{description}
|
||||
\item [Docker] \hfill \\
|
||||
Eine arrivierte Container-Engine für Anwendungsentwicklung.
|
||||
\item [(1P-)Eintrag/Secret] \hfill \\
|
||||
Eine Gruppierung an Daten, die einen Login ermöglichen. Z.B. $(\text{Nutzername},\text{Passwort})$. Eine solche Struktur kann bei \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 [Ansible-Playbook/s] \hfill \\
|
||||
Ansible-Playbooks sind Skripte, mit dem Ziel einen deklarierten Zustand herzustellen. \cite{bib:ansible}
|
||||
\item [Ansible-Role] \hfill \\
|
||||
Eine Abfolge von definierten Schritten, die von Ansible-Playbooks ausgeführt werden. Eine solche Role könnte z.B. einen Server buchen, konfigurieren und verwendungsfertig bereitstellen.
|
||||
\item [Detailansicht / Detailaufruf] \hfill \\
|
||||
Eine Anfrage, die \emph{ein} Objekt oder \emph{einen} Eintrag zurückgibt oder manipuliert.
|
||||
\item [Docker] \hfill \\
|
||||
Eine arrivierte Container-Engine für Anwendungsentwicklung.
|
||||
\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.
|
||||
\end{description}
|
||||
\clearpage
|
||||
\begin{description}
|
||||
\item [Jinja-Templating-Engine] \hfill \\
|
||||
Eine Templating Engine, die das Jinja-Format verwendet. Ansible verwendet eine Jinja-Templating-Engine.
|
||||
\item [Listenansicht / Listenaufruf] \hfill \\
|
||||
Eine Anfrage, die eine Liste von Objekten oder Einträgen zurückgibt.
|
||||
\item [Nutzvault] \hfill \\
|
||||
Ein 1P-Vault, in dem die originalen Einträge des Partnerunternehmens verortet sind. Hier liegen keine Kopien, sondern Originale!
|
||||
\item [Öffentliche 1P-UUID] \hfill \\
|
||||
Die 1P-UUID, die zu einem originalen Eintrag gehört und nicht zu einer Referenz.
|
||||
Externe Entwickler*innen haben also keinen direkten Zugriff auf einen solchen Eintrag, sondern müssen stattdessen eine Referenz auf diesen Eintrag verwenden.
|
||||
Eine solche UUID kann beispielsweise in Ansible-Konfigurationdateien stehen
|
||||
und von jedem*r Entwickler*in verwendet werden.
|
||||
\item [Private 1P-UUID] \hfill \\
|
||||
Die 1P-UUID, die zu einem Referenz-Eintrag gehört, und nicht zu einem originalen Eintrag. Diese Einträge sind emphemerisch und existieren ausschließlich
|
||||
in den einzelnen Developer-Vaults und sind Entwickler*innen-spezifisch.
|
||||
\item [Secret] \hfill \\
|
||||
Eine vertrauliche Information, wie zum Beispiel ein Passwort.
|
||||
\item [Toolbox] \hfill \\
|
||||
Eine Ansammlung an Werkzeugen, wie zum Beispiel Skripte.
|
||||
\end{description}
|
||||
|
||||
|
||||
@@ -2,29 +2,6 @@
|
||||
# Note that authors are "and"-seperated. The comma is part of the name. Like in "Etienne, Leon".
|
||||
# So if you have multiple authors, use "Peter and Werner and Mario and Johann"...
|
||||
|
||||
@article{bib:leossfc,
|
||||
author = {Maral, Gérard and de Ridder, Jean-Jacques and Evans, Barry G. and Richharia, Madhavendra},
|
||||
title = {Low earth orbit satellite systems for communications},
|
||||
journal = {International Journal of Satellite Communications},
|
||||
volume = {9},
|
||||
number = {4},
|
||||
pages = {209-225},
|
||||
publisher = {Wiley Online Library},
|
||||
doi = {https://doi.org/10.1002/sat.4600090403},
|
||||
url = {https://onlinelibrary.wiley.com/doi/abs/10.1002/sat.4600090403},
|
||||
eprint = {https://onlinelibrary.wiley.com/doi/pdf/10.1002/sat.4600090403},
|
||||
abstract = {Abstract It may be that we are now entering the era of LEO constellation satellite communications after thirty years of domination by the GEO systems. This paper heralds the coming of the new era with a tutorial approach to the system design and trade-offs of LEO constellation system design. It discusses orbital configurations, network topologies and routeing considerations, multiple access schemes and link performance design. In so doing it brings out the major design parameters and how they interact with each other. Also considered are the service applications for the LEO constellation systems, and the important difference between real-time and delayed communication systems is highlighted. Examples of single and multi-beam (cellular) coverage system link designs are presented for L-Ka frequency bands. Future papers will consider aspects of the LEO spacecraft and launchers.},
|
||||
year = {1991}
|
||||
}
|
||||
|
||||
# Example Website
|
||||
@misc{bib:typo3-frontpage,
|
||||
author = {{TYPO3 Association}},
|
||||
howpublished = "\url{https://typo3.org/}",
|
||||
title = {{ TYPO3 — the Professional, Flexible Content Management System }},
|
||||
year = {2024},
|
||||
note = {Zugriff: Mai 2024}
|
||||
}
|
||||
|
||||
@misc{bib:ansible,
|
||||
author = {{Red Hat, Inc.}},
|
||||
@@ -33,3 +10,47 @@
|
||||
year = {2025},
|
||||
note = {Zugriff: Januar 2025}
|
||||
}
|
||||
|
||||
@misc{bib:ansible-docs-python-module,
|
||||
author = {{Red Hat, Inc.}},
|
||||
howpublished = "\url{https://cn-ansibledoc.readthedocs.io/zh-cn/latest/dev_guide/developing_modules_general.html}",
|
||||
title = {{ Ansible module development: getting started }},
|
||||
year = {2019},
|
||||
note = {Zugriff: Januar 2025}
|
||||
}
|
||||
|
||||
@misc{bib:1password-cli-caching,
|
||||
author = {{1Password}},
|
||||
howpublished = "\url{https://developer.1password.com/docs/cli/reference/#cache-item-and-vault-information}",
|
||||
title = {{ Cache item and vault information }},
|
||||
year = {2025},
|
||||
note = {Zugriff: Februar 2025}
|
||||
}
|
||||
|
||||
@misc{bib:1password-secrets-automation,
|
||||
author = {{1Password}},
|
||||
howpublished = "\url{https://developer.1password.com/docs/secrets-automation/}",
|
||||
title = {{ 1Password Secrets Automation }},
|
||||
year = {2025},
|
||||
note = {Zugriff: Februar 2025}
|
||||
}
|
||||
|
||||
@misc{bib:ansible-filter-plugins,
|
||||
author = {{Red Hat, Inc.}},
|
||||
howpublished = "\url{https://docs.ansible.com/ansible/latest/plugins/filter.html}",
|
||||
title = {{ Filter plugins }},
|
||||
year = {2025},
|
||||
note = {Zugriff: Februar 2025}
|
||||
}
|
||||
|
||||
@techreport{bib:BSI-TR-02102-1-2024,
|
||||
author = {{ BSI }},
|
||||
title = {Cryptographic Mechanisms: Recommendations and Key Lengths},
|
||||
institution = {Federal Office for Information Security (BSI)},
|
||||
type = {Technical Guideline TR-02102},
|
||||
version = {2024-1},
|
||||
number = {TR-02102-1},
|
||||
date = {2024-02-02},
|
||||
year = {2024},
|
||||
note = {Provides an assessment of the security and long-term orientation for selected cryptographic mechanisms.},
|
||||
}
|
||||
|
||||
@@ -92,6 +92,11 @@ hidelinks, % avoid weird ref highlighting
|
||||
|
||||
\usepackage{float}
|
||||
|
||||
% Reduce excessive line height in lists
|
||||
\usepackage{enumitem,setspace,lipsum,etoolbox}
|
||||
\AtBeginEnvironment{itemize}{\par\medskip\setstretch{0.5}}
|
||||
\AtBeginEnvironment{enumerate}{\par\medskip\setstretch{0.5}}
|
||||
|
||||
% Metadaten
|
||||
\usepackage[pdftex,
|
||||
pdfauthor={\cfgAuthorName},
|
||||
@@ -105,3 +110,4 @@ hidelinks, % avoid weird ref highlighting
|
||||
|
||||
% Load custom environments
|
||||
\input{environments}
|
||||
|
||||
|
||||
BIN
images/.DS_Store
vendored
BIN
images/config-file.png
Normal file
|
After Width: | Height: | Size: 123 KiB |
BIN
images/dev-stuff-python.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
images/dev-stuff-via-api-keys.png
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
images/docker-ansible-structure.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
images/flowchart-resolve-1p-secret-with-caching.png
Normal file
|
After Width: | Height: | Size: 135 KiB |
BIN
images/flowchart-resolve-1p-secret.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
images/ideensammlung.jpg
Normal file
|
After Width: | Height: | Size: 257 KiB |
BIN
images/masa-diagram.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
images/old-usage-diagram.jpg
Normal file
|
After Width: | Height: | Size: 207 KiB |
BIN
images/program-structure.png
Normal file
|
After Width: | Height: | Size: 40 KiB |