<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://pascal-nehlsen.de/de/blog</id>
    <title>Pascal Nehlsen, Beiträge</title>
    <updated>2026-04-28T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://pascal-nehlsen.de/de/blog"/>
    <subtitle>Notizen aus der Arbeit an Platform- und Security-Engineering.</subtitle>
    <icon>https://pascal-nehlsen.de/de/img/favicon.svg</icon>
    <rights>© 2026 Pascal Nehlsen</rights>
    <entry>
        <title type="html"><![CDATA[Ephemere AWS-Sandboxes: 80+ isolierte Umgebungen zum halben Preis]]></title>
        <id>https://pascal-nehlsen.de/de/blog/ephemeral-aws-sandboxes-cost</id>
        <link href="https://pascal-nehlsen.de/de/blog/ephemeral-aws-sandboxes-cost"/>
        <updated>2026-04-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[n8n-Sandboxes pro Person auf burstable EC2, dimensioniert nach dem Median statt nach der Spitze, mit Lifecycle-Automatisierung, die untätige Instanzen einsammelt: 80+ echte Umgebungen zur Hälfte der Compute-Kosten.]]></summary>
        <content type="html"><![CDATA[<p>Allen Lernenden eine gemeinsame Umgebung zu geben ist billig und elend. Eine Person zerlegt sie,
und alle stehen. Allen eine feste, immer laufende Instanz zu geben ist sauber und teuer. Dieser
Beitrag handelt von einer dritten Möglichkeit: produktionsnahen Sandboxes pro Person auf AWS, die
auf Abruf hochkommen, sich selbst aufräumen und etwa die Hälfte dessen kosten, was fest
dimensionierte Instanzen kosten würden.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="warum-isolation-mehr-zählt-als-sie-aussieht">Warum Isolation mehr zählt, als sie aussieht<a href="https://pascal-nehlsen.de/de/blog/ephemeral-aws-sandboxes-cost#warum-isolation-mehr-z%C3%A4hlt-als-sie-aussieht" class="hash-link" aria-label="Direkter Link zur Warum Isolation mehr zählt, als sie aussieht" title="Direkter Link zur Warum Isolation mehr zählt, als sie aussieht" translate="no">​</a></h2>
<p>Bei praktischer Automatisierungsarbeit, hier n8n-Sandboxes für Trainees, ist gemeinsamer State
Gift. Ein falsch konfigurierter Workflow, eine Endlosschleife, ein gelöschtes Credential: in
einer gemeinsamen Kiste ist das das Problem aller. Isolation bedeutet, dass der Fehler einer
Person ein Lernmoment ist und kein Ausfall für die ganze Kohorte.</p>
<p>Die Anforderung also: <strong>80+ unabhängige, produktionsnahe Umgebungen</strong>, jede wegwerfbar.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="burstable-instanzen-passen-zur-nutzungsform">Burstable Instanzen passen zur Nutzungsform<a href="https://pascal-nehlsen.de/de/blog/ephemeral-aws-sandboxes-cost#burstable-instanzen-passen-zur-nutzungsform" class="hash-link" aria-label="Direkter Link zur Burstable Instanzen passen zur Nutzungsform" title="Direkter Link zur Burstable Instanzen passen zur Nutzungsform" translate="no">​</a></h2>
<p>Das Nutzungsmuster ist stoßweise: intensive Aktivität während einer Session, den Rest der Zeit
fast Leerlauf. Genau dafür sind burstable Instanzen von AWS (<code>t3</code> / <code>t4g</code>) gebaut. Du zahlst
einen Grundwert und sammelst im Leerlauf CPU-Credits, die du in den Spitzen ausgibst.</p>
<p>Zwei Entscheidungen haben die Kosten am stärksten gedrückt:</p>
<ul>
<li class=""><strong><code>t4g</code> (Graviton/ARM)</strong> dort, wo die Workload architekturunabhängig ist, für das bessere Preis-Leistungs-Verhältnis.</li>
<li class=""><strong>Dimensionieren auf den Burst</strong>, nicht auf die Spitze der Spitzen, weil Credits kurze Ausschläge auffangen.</li>
</ul>
<p>Gegenüber fest dimensionierten, dauerhaft laufenden Instanzen auf Spitzenniveau lagen die
Compute-Kosten damit rund <strong>50 % niedriger</strong>.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="auf-die-lifecycle-automatisierung-kommt-alles-an">Auf die Lifecycle-Automatisierung kommt alles an<a href="https://pascal-nehlsen.de/de/blog/ephemeral-aws-sandboxes-cost#auf-die-lifecycle-automatisierung-kommt-alles-an" class="hash-link" aria-label="Direkter Link zur Auf die Lifecycle-Automatisierung kommt alles an" title="Direkter Link zur Auf die Lifecycle-Automatisierung kommt alles an" translate="no">​</a></h2>
<p>Ephemer spart nur Geld, wenn die Umgebungen tatsächlich verschwinden. Der Lebenszyklus ist
durchgehend automatisiert:</p>
<ol>
<li class=""><strong>Bereitstellen</strong> auf Abruf aus einem Terraform-definierten Template: Instanz, Security Group,
vorbereitetes n8n, getaggt mit <code>owner</code> und <code>expires-at</code>.</li>
<li class=""><strong>Laufen</strong> für die Session; isoliertes Netzwerk pro Sandbox.</li>
<li class=""><strong>Einsammeln</strong> automatisch: ein geplanter Job terminiert Instanzen nach ihrem <code>expires-at</code>,
damit eine vergessene Sandbox nicht still eine Woche lang abrechnet.</li>
</ol>
<div class="language-hcl codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-hcl codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token property" style="color:rgb(128, 203, 196)">tags</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">owner</span><span class="token plain">       </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> var.trainee_id</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">purpose</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"n8n-sandbox"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">expires-at</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> var.session_end   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># consumed by the reaper</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Das <code>expires-at</code>-Tag ist der Angelpunkt: es macht aus "bitte daran denken, sie abzuschalten"
einen garantierten, automatischen Abbau.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="guardrails-damit-eine-sandbox-eine-sandbox-bleibt">Guardrails, damit eine Sandbox eine Sandbox bleibt<a href="https://pascal-nehlsen.de/de/blog/ephemeral-aws-sandboxes-cost#guardrails-damit-eine-sandbox-eine-sandbox-bleibt" class="hash-link" aria-label="Direkter Link zur Guardrails, damit eine Sandbox eine Sandbox bleibt" title="Direkter Link zur Guardrails, damit eine Sandbox eine Sandbox bleibt" translate="no">​</a></h2>
<p>Isolation und Kostenkontrolle brauchen dieselbe Durchsetzungsdisziplin wie jede andere Umgebung:</p>
<ul>
<li class=""><strong>Eng geschnittenes IAM</strong> pro Sandbox, keine gemeinsame, überprivilegierte Rolle.</li>
<li class=""><strong>Egress-Grenzen</strong>, damit aus einer Sandbox keine Krypto-Mining-Überraschung wird.</li>
<li class=""><strong>Hartes Ablaufdatum</strong>, damit Kosten von vornherein begrenzt sind und nicht von Wachsamkeit abhängen.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="das-ergebnis">Das Ergebnis<a href="https://pascal-nehlsen.de/de/blog/ephemeral-aws-sandboxes-cost#das-ergebnis" class="hash-link" aria-label="Direkter Link zur Das Ergebnis" title="Direkter Link zur Das Ergebnis" translate="no">​</a></h2>
<p>Am Ende standen <strong>80+ Trainees, jede und jeder mit einer isolierten, produktionsnahen
Umgebung</strong>, auf Abruf bereitgestellt und automatisch eingesammelt, bei etwa <strong>der Hälfte der
Compute-Kosten</strong> fest dimensionierter Instanzen. Isolation war kein Luxus mehr, sondern der
billige Standard.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="mitnehmen">Mitnehmen<a href="https://pascal-nehlsen.de/de/blog/ephemeral-aws-sandboxes-cost#mitnehmen" class="hash-link" aria-label="Direkter Link zur Mitnehmen" title="Direkter Link zur Mitnehmen" translate="no">​</a></h2>
<ul>
<li class="">Passe den Instanztyp an die <strong>Nutzungsform</strong> an; stoßweise Arbeit liebt burstable Instanzen.</li>
<li class="">Zieh <strong>Graviton (<code>t4g</code>)</strong> für architekturunabhängige Workloads in Betracht.</li>
<li class="">Mach den Abbau <strong>automatisch und tag-getrieben</strong>. Ephemer, das nie abläuft, ist einfach teuer.</li>
<li class="">Begrenze Kosten <strong>von vornherein</strong> (hartes Ablaufdatum), nicht dadurch, dass Menschen daran denken.</li>
</ul>]]></content>
        <author>
            <name>Pascal Nehlsen</name>
            <email>mail@pascal-nehlsen.de</email>
            <uri>https://github.com/PascalNehlsen</uri>
        </author>
        <category label="AWS" term="AWS"/>
        <category label="Kosten" term="Kosten"/>
        <category label="Terraform" term="Terraform"/>
        <category label="Platform Engineering" term="Platform Engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[SLO-gesteuertes automatisches Rollback: die Metrik zieht die Reißleine]]></title>
        <id>https://pascal-nehlsen.de/de/blog/slo-driven-automated-rollback</id>
        <link href="https://pascal-nehlsen.de/de/blog/slo-driven-automated-rollback"/>
        <updated>2026-03-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Prometheus, Grafana und strukturiertes Logging so in eine Deployment-Pipeline verdrahten, dass eine SLO-Verletzung das Rollback automatisch auslöst, und warum ein Rollback ohne SLO dahinter ein Knopf ist, dem niemand traut.]]></summary>
        <content type="html"><![CDATA[<p>Ein Deploy, der um 02:00 die Produktion zerlegt, sollte nicht darauf warten, dass ein Mensch
aufwacht, ein Dashboard liest und sich für ein Rollback entscheidet. Wenn du <em>definieren</em>
kannst, was "kaputt" bedeutet, und zwar so, dass dein Monitoring es messen kann, dann kann die Pipeline
die Reißleine selbst ziehen. Dieser Beitrag zeigt Schritt für Schritt, wie Observability so in das Deployment
verdrahtet wird, dass eine SLO-Verletzung ein automatisches Rollback auslöst.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="fang-mit-einem-slo-an-das-du-wirklich-messen-kannst">Fang mit einem SLO an, das du wirklich messen kannst<a href="https://pascal-nehlsen.de/de/blog/slo-driven-automated-rollback#fang-mit-einem-slo-an-das-du-wirklich-messen-kannst" class="hash-link" aria-label="Direkter Link zur Fang mit einem SLO an, das du wirklich messen kannst" title="Direkter Link zur Fang mit einem SLO an, das du wirklich messen kannst" translate="no">​</a></h2>
<p>Ein automatisches Rollback ist nur so vertrauenswürdig wie das Signal, das es auslöst. Vage
Ziele ("die App soll schnell sein") funktionieren nicht. Konkrete, messbare SLOs schon:</p>
<ul>
<li class=""><strong>Verfügbarkeit</strong>: <code>&gt;= 99,9 %</code> der Anfragen liefern kein 5xx, über ein 5-Minuten-Fenster.</li>
<li class=""><strong>Latenz</strong>: <code>p95 &lt; 300 ms</code> über ein 5-Minuten-Fenster.</li>
<li class=""><strong>Error Budget</strong>: ein Burn-Rate-Schwellwert, der einen Ausschlag von einer Regression unterscheidet.</li>
</ul>
<p>Daraus werden PromQL-Ausdrücke, keine Foliensätze:</p>
<div class="language-promql codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-promql codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token plain"># 5xx rate over the last 5 minutes, per service</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">sum(rate(http_requests_total{status=~"5..", service="appointments-api"}[5m]))</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">sum(rate(http_requests_total{service="appointments-api"}[5m]))</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="das-observability-rückgrat">Das Observability-Rückgrat<a href="https://pascal-nehlsen.de/de/blog/slo-driven-automated-rollback#das-observability-r%C3%BCckgrat" class="hash-link" aria-label="Direkter Link zur Das Observability-Rückgrat" title="Direkter Link zur Das Observability-Rückgrat" translate="no">​</a></h2>
<p>Drei Signale speisen die Entscheidung:</p>
<ul>
<li class=""><strong>Prometheus</strong> scrapt Request-Rate, Fehlerrate und Latenz-Histogramme.</li>
<li class=""><strong>Grafana</strong> stellt sie dar und beherbergt die Alerting-Regeln, über die Menschen nachdenken.</li>
<li class=""><strong>Strukturiertes Logging</strong> (JSON, mit <code>trace_id</code>) macht das <em>Warum</em> auffindbar, sobald das <em>Was</em> feuert.</li>
</ul>
<p>Die entscheidende Disziplin: dieselbe Query, die die Linie im Dashboard zeichnet, ist die, die
den Deploy absichert. Keine separate, wegdriftende "Rollback-Logik".</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="das-rollback-gate">Das Rollback-Gate<a href="https://pascal-nehlsen.de/de/blog/slo-driven-automated-rollback#das-rollback-gate" class="hash-link" aria-label="Direkter Link zur Das Rollback-Gate" title="Direkter Link zur Das Rollback-Gate" translate="no">​</a></h2>
<p>Nachdem ein Deploy eine neue Revision promoted hat, geht die Pipeline in ein <strong>Bake-Fenster</strong>,
sagen wir fünf Minuten, in dem sie die SLO-Queries beobachtet:</p>
<ol>
<li class="">Neue Revision promoten, Traffic umlegen.</li>
<li class="">Die SLO-Ausdrücke über das Bake-Fenster hinweg pollen.</li>
<li class="">Verletzt ein SLO seinen Schwellwert (mit Burn-Rate-Schutz gegen Flattern), <strong>Rollback
auslösen</strong> auf die letzte gute Revision.</li>
<li class="">Ein strukturiertes Event schreiben: Revision, verletztes SLO, beobachteter Wert, Zeitstempel.</li>
</ol>
<p>Weil ein Rollback nichts anderes ist als "Traffic zurück auf die letzte als gut bekannte
Revision leiten", ist es schnell und langweilig, und genau das willst du um 02:00.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="gegen-fehlalarme-absichern">Gegen Fehlalarme absichern<a href="https://pascal-nehlsen.de/de/blog/slo-driven-automated-rollback#gegen-fehlalarme-absichern" class="hash-link" aria-label="Direkter Link zur Gegen Fehlalarme absichern" title="Direkter Link zur Gegen Fehlalarme absichern" translate="no">​</a></h2>
<p>Automatisierung, die auf Rauschen zurückrollt, ist schlimmer als keine Automatisierung. Sie
zerstört Vertrauen. Zwei Absicherungen:</p>
<ul>
<li class=""><strong>Burn-Rate statt Momentanwert</strong>: ein einzelner Ausschlag soll nicht auslösen, anhaltender Verbrauch schon.</li>
<li class=""><strong>Mindest-Traffic-Schwelle</strong>: rechne keine Fehler<em>rate</em> auf drei Anfragen.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="das-ergebnis">Das Ergebnis<a href="https://pascal-nehlsen.de/de/blog/slo-driven-automated-rollback#das-ergebnis" class="hash-link" aria-label="Direkter Link zur Das Ergebnis" title="Direkter Link zur Das Ergebnis" translate="no">​</a></h2>
<p>Mit SLOs als messbare Queries und einem Rollback-Gate im Bake-Fenster blieb die
Deployment-Fehlerrate <strong>unter 2 %</strong>, und die mittlere Zeit bis zur Erkennung kritischer Fehler
fiel auf <strong>unter fünf Minuten</strong>, weil Erkennung und Behebung derselbe automatisierte Schritt
waren.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="mitnehmen">Mitnehmen<a href="https://pascal-nehlsen.de/de/blog/slo-driven-automated-rollback#mitnehmen" class="hash-link" aria-label="Direkter Link zur Mitnehmen" title="Direkter Link zur Mitnehmen" translate="no">​</a></h2>
<ul>
<li class="">Definiere SLOs als <strong>Queries, die dein Monitoring schon auswertet</strong>, nicht als Prosa.</li>
<li class="">Nutze <strong>denselben Ausdruck</strong> für das Dashboard und für das Rollback-Gate.</li>
<li class="">Bau ein <strong>Bake-Fenster</strong> und <strong>Burn-Rate-Schutz</strong> ein, damit du auf Regressionen zurückrollst und nicht auf Rauschen.</li>
<li class="">Ein gutes Rollback ist <strong>schnell und langweilig</strong>: Traffic auf die letzte gute Revision leiten.</li>
</ul>]]></content>
        <author>
            <name>Pascal Nehlsen</name>
            <email>mail@pascal-nehlsen.de</email>
            <uri>https://github.com/PascalNehlsen</uri>
        </author>
        <category label="Observability" term="Observability"/>
        <category label="CI/CD" term="CI/CD"/>
        <category label="DevSecOps" term="DevSecOps"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Agentische DevOps-Runbooks mit menschlicher Freigabe]]></title>
        <id>https://pascal-nehlsen.de/de/blog/agentic-runbooks-mcp-human-approval</id>
        <link href="https://pascal-nehlsen.de/de/blog/agentic-runbooks-mcp-human-approval"/>
        <updated>2026-02-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Ein MCP-Server, der Incident-Kontext zusammenträgt, eine Behebung vorschlägt und dann stehen bleibt. Jede zustandsändernde Aktion braucht eine menschliche Freigabe, wird mit ihrer Begründung protokolliert und ist umkehrbar.]]></summary>
        <content type="html"><![CDATA[<p>"Lass die KI das reparieren" ist ein guter Weg, aus einem kleinen Vorfall einen großen zu
machen. Der <em>Aufwand</em> in der Incident-Bearbeitung liegt aber meist nicht in der Behebung. Er
liegt im Zusammentragen: Logs ziehen, Deploy-Historie prüfen, Metriken korrelieren,
rekonstruieren, was sich geändert hat. Dieser Teil lässt sich gefahrlos automatisieren. Dieser
Beitrag beschreibt einen Runbook-Executor, der das Zusammentragen und das <em>Vorschlagen</em>
automatisiert und bei allem Destruktiven einen Menschen davorstellt.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="das-entwurfsprinzip-vorschlagen-nicht-ausführen">Das Entwurfsprinzip: vorschlagen, nicht ausführen<a href="https://pascal-nehlsen.de/de/blog/agentic-runbooks-mcp-human-approval#das-entwurfsprinzip-vorschlagen-nicht-ausf%C3%BChren" class="hash-link" aria-label="Direkter Link zur Das Entwurfsprinzip: vorschlagen, nicht ausführen" title="Direkter Link zur Das Entwurfsprinzip: vorschlagen, nicht ausführen" translate="no">​</a></h2>
<p>Das System teilt jeden Runbook-Schritt in zwei Kategorien:</p>
<ul>
<li class=""><strong>Lesende Aktionen</strong>: Logs holen, Terraform-State lesen, letzte Deployments auflisten,
Metriken abfragen. Diese laufen automatisch.</li>
<li class=""><strong>Schreibende Aktionen</strong>: einen Service neu starten, ein Release zurückrollen, eine Ressource
skalieren, ein IAM-Binding ändern. Diese werden <em>vorgeschlagen</em> und brauchen eine
ausdrückliche Freigabe, bevor sie ausgeführt werden.</li>
</ul>
<p>Das LLM lebt in der lesenden Hälfte und an der Grenze zum Vorschlag. Es hält nie die Schlüssel
für einen Schreibvorgang.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="mcp-als-integrationsfläche">MCP als Integrationsfläche<a href="https://pascal-nehlsen.de/de/blog/agentic-runbooks-mcp-human-approval#mcp-als-integrationsfl%C3%A4che" class="hash-link" aria-label="Direkter Link zur MCP als Integrationsfläche" title="Direkter Link zur MCP als Integrationsfläche" translate="no">​</a></h2>
<p>Der Executor ist ein <a href="https://modelcontextprotocol.io/" target="_blank" rel="noopener noreferrer" class="">MCP</a>-Server in Go, der dem Agenten
eine kleine Auswahl an Tools anbietet:</p>
<div class="language-text codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-text codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token plain">get_recent_deployments(service)      # read</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">get_logs(service, since, severity)   # read</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">get_terraform_state(module)          # read</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">propose_rollback(service, revision)  # write → queued for approval</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">propose_restart(service)             # write → queued for approval</span><br></div></code></pre></div></div>
<p>Lesende Tools liefern Kontext. Schreibende Tools handeln nicht. Sie stellen einen <strong>Vorschlag</strong>
in die Warteschlange, mit einem für Menschen lesbaren Diff dessen, was passieren <em>würde</em>, und
geben eine Ticket-ID zurück. Es passiert nichts, bis ein Mensch dieses Ticket
freigibt.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="jede-kritische-aktion-ist-prüfbar-und-umkehrbar">Jede kritische Aktion ist prüfbar und umkehrbar<a href="https://pascal-nehlsen.de/de/blog/agentic-runbooks-mcp-human-approval#jede-kritische-aktion-ist-pr%C3%BCfbar-und-umkehrbar" class="hash-link" aria-label="Direkter Link zur Jede kritische Aktion ist prüfbar und umkehrbar" title="Direkter Link zur Jede kritische Aktion ist prüfbar und umkehrbar" translate="no">​</a></h2>
<p>Drei Eigenschaften sind bei einer schreibenden Aktion nicht verhandelbar:</p>
<ol>
<li class=""><strong>Prüfbar</strong>: wer sie vorgeschlagen hat (welches Runbook, welcher Agent-Lauf), wer sie
freigegeben hat, wann, und mit exakt welchen Parametern. Das wird vor der Ausführung
dauerhaft protokolliert.</li>
<li class=""><strong>Umkehrbar</strong>: ein Rollback hat eine Vorwärts- und eine Rückwärtsrichtung; der Executor
speichert genug State, um ihn rückgängig zu machen.</li>
<li class=""><strong>Ausdrücklich freigegeben</strong>: die Freigabe ist eine bewusste Handlung eines namentlich
bekannten Menschen, kein Default und kein Timeout.</li>
</ol>
<p>Der Freigabeschritt ist die Stelle, an der Automatisierung und Verantwortung
zusammenkommen. Der Agent kann falsch liegen; das Guardrail geht davon aus, dass er es wird.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="was-das-tatsächlich-bringt">Was das tatsächlich bringt<a href="https://pascal-nehlsen.de/de/blog/agentic-runbooks-mcp-human-approval#was-das-tats%C3%A4chlich-bringt" class="hash-link" aria-label="Direkter Link zur Was das tatsächlich bringt" title="Direkter Link zur Was das tatsächlich bringt" translate="no">​</a></h2>
<p>Bei bekannten Fehlerklassen (ein schlechter Deploy, ein festgefahrener Worker, eine
Config-Regression) kürzt der Executor den langsamen Teil der Reaktion weg. Statt zehn Minuten
Kontextsammeln unter Druck öffnet die Person im Bereitschaftsdienst einen Vorschlag, der die
Logs, das Diff, die vermutete Ursache und eine vorbereitete Behebung schon enthält und auf ein
Ja oder Nein wartet.</p>
<p>In der Praxis hat das die Reaktionszeit bei bekannten Fehlerklassen um rund <strong>60 %</strong> verkürzt,
und zwar nicht, weil etwas schneller handelt als ein Mensch, sondern weil das Zusammentragen
wegfällt, das ein Mensch ohnehin gemacht hätte.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="mitnehmen">Mitnehmen<a href="https://pascal-nehlsen.de/de/blog/agentic-runbooks-mcp-human-approval#mitnehmen" class="hash-link" aria-label="Direkter Link zur Mitnehmen" title="Direkter Link zur Mitnehmen" translate="no">​</a></h2>
<ul>
<li class="">Automatisiere das <strong>Zusammentragen und den Vorschlag</strong>; setze vor die <strong>Aktion</strong> einen Menschen.</li>
<li class="">Modelliere Schreiboperationen als <strong>umkehrbare Vorschläge mit Diff</strong>, nie als Fire-and-Forget-Aufruf.</li>
<li class="">Mach <strong>Prüfbarkeit zur Vorbedingung</strong> der Ausführung, nicht zum Nachgedanken.</li>
<li class="">Das Ziel ist nicht Autonomie. Es ist eine schnellere, ruhigere menschliche Entscheidung.</li>
</ul>]]></content>
        <author>
            <name>Pascal Nehlsen</name>
            <email>mail@pascal-nehlsen.de</email>
            <uri>https://github.com/PascalNehlsen</uri>
        </author>
        <category label="Agents & MCP" term="Agents & MCP"/>
        <category label="DevSecOps" term="DevSecOps"/>
        <category label="Platform Engineering" term="Platform Engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Golden Paths auf GCP: 80 % weniger Provisioning-Zeit mit Terraform]]></title>
        <id>https://pascal-nehlsen.de/de/blog/terraform-golden-paths-gcp</id>
        <link href="https://pascal-nehlsen.de/de/blog/terraform-golden-paths-gcp"/>
        <updated>2026-01-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Wie das Modularisieren einer Google-Cloud-Umgebung entlang der Absicht der Teams statt entlang des Ressourcenkatalogs aus vier Stunden Handarbeit einen Self-Service-Pfad unter 45 Minuten gemacht hat.]]></summary>
        <content type="html"><![CDATA[<p>Am schnellsten bremst man ein Team aus, indem man es auf Infrastruktur warten lässt. Wenn jeder
neue Service vier Stunden Handarbeit in der GCP-Konsole bedeutet, sammeln Engineers ihre
Anfragen, wechseln währenddessen den Kontext und bauen still und leise Sonderfälle. Dieser
Beitrag handelt davon, dieses Ritual durch einen Golden Path zu ersetzen: einen geebneten,
meinungsstarken Weg, der eine produktionsnahe Umgebung in unter 45 Minuten bereitstellt, im
Self-Service.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="was-an-klick-es-einfach-in-der-konsole-nicht-funktioniert">Was an "klick es einfach in der Konsole" nicht funktioniert<a href="https://pascal-nehlsen.de/de/blog/terraform-golden-paths-gcp#was-an-klick-es-einfach-in-der-konsole-nicht-funktioniert" class="hash-link" aria-label="Direkter Link zur Was an &quot;klick es einfach in der Konsole&quot; nicht funktioniert" title="Direkter Link zur Was an &quot;klick es einfach in der Konsole&quot; nicht funktioniert" translate="no">​</a></h2>
<p>Manuelles Provisioning scheitert auf drei vorhersehbare Arten:</p>
<ul>
<li class=""><strong>Es ist langsam.</strong> Vier Stunden pro Umgebung, davon das meiste Warten und Klicken.</li>
<li class=""><strong>Es driftet.</strong> Keine zwei Umgebungen werden identisch, und damit bedeutet "läuft in Staging" nichts mehr.</li>
<li class=""><strong>Es ist undurchsichtig.</strong> Kein Review, keine Historie, keine Antwort auf "wer hat dieses IAM-Binding geändert und warum".</li>
</ul>
<p>Infrastructure as Code behebt alle drei auf einmal, aber nur, wenn die Module so geschnitten
sind, dass die korrekte Verwendung der Weg des geringsten Widerstands ist.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="modularisieren-entlang-der-absicht-nicht-entlang-der-ressourcen">Modularisieren entlang der Absicht, nicht entlang der Ressourcen<a href="https://pascal-nehlsen.de/de/blog/terraform-golden-paths-gcp#modularisieren-entlang-der-absicht-nicht-entlang-der-ressourcen" class="hash-link" aria-label="Direkter Link zur Modularisieren entlang der Absicht, nicht entlang der Ressourcen" title="Direkter Link zur Modularisieren entlang der Absicht, nicht entlang der Ressourcen" translate="no">​</a></h2>
<p>Der Fehler, den ich am häufigsten sehe, ist ein Terraform-Layout, das die GCP-API abbildet: ein
Modul pro Ressourcentyp. Das ist auf das Platform-Team optimiert und bestraft alle anderen.</p>
<p>Modularisiere stattdessen danach, was Teams tatsächlich anfragen:</p>
<div class="language-hcl codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-hcl codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">module</span><span class="token keyword type variable" style="color:rgb(214, 222, 235)"> "service" </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">source</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"./modules/cloud-run-service"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">name</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"appointments-api"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">team</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"scheduling"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">image</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> var.image</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># sensible, secure defaults baked in:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># - private IP Cloud SQL connection</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># - least-privilege service account</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># - structured logging + trace export</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Ein einziger <code>module "service"</code>-Block richtet Cloud Run ein, verdrahtet einen
Service-Account mit minimalen Rechten, verbindet Cloud SQL über eine private IP und exportiert
Logs und Traces. Der Aufrufer beschreibt <em>Absicht</em>, einen Service für ein Team, nicht dreißig
einzelne Ressourcen.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="guardrails-gehören-ins-modul">Guardrails gehören ins Modul<a href="https://pascal-nehlsen.de/de/blog/terraform-golden-paths-gcp#guardrails-geh%C3%B6ren-ins-modul" class="hash-link" aria-label="Direkter Link zur Guardrails gehören ins Modul" title="Direkter Link zur Guardrails gehören ins Modul" translate="no">​</a></h2>
<p>Ein Golden Path ist nur dann golden, wenn die sichere Wahl die Standardwahl ist:</p>
<ul>
<li class=""><strong>IAM</strong>: Module erzeugen eng geschnittene Service Accounts; niemand editiert Bindings auf Projektebene von Hand.</li>
<li class=""><strong>Netzwerk</strong>: private IP als Standard, öffentlicher Egress nur auf ausdrücklichen Wunsch und mit Review.</li>
<li class=""><strong>Labels</strong>: <code>team</code>, <code>cost-center</code> und <code>environment</code> sind Pflichtvariablen. Kein Label, kein Plan.</li>
</ul>
<p>Weil das im Code erzwungen wird, ist eine Fehlkonfiguration ein fehlgeschlagenes
<code>terraform plan</code> und kein Produktionsvorfall, der drei Wochen später auffällt.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="ausrollen-über-gitops">Ausrollen über GitOps<a href="https://pascal-nehlsen.de/de/blog/terraform-golden-paths-gcp#ausrollen-%C3%BCber-gitops" class="hash-link" aria-label="Direkter Link zur Ausrollen über GitOps" title="Direkter Link zur Ausrollen über GitOps" translate="no">​</a></h2>
<p>Die Module sind nur die halbe Geschichte, das Ausrollen ist die andere. Jede Änderung läuft
durch einen Pull Request:</p>
<ol>
<li class=""><code>terraform plan</code> läuft in CI und hängt das Diff an den PR.</li>
<li class="">Ein Reviewer genehmigt den <em>Plan</em>, nicht eine vage Beschreibung davon.</li>
<li class="">Der Merge nach <code>main</code> löst <code>terraform apply</code> über GitHub Actions aus (oder Argo CD für die
Kubernetes-artigen Teile).</li>
</ol>
<p>Der Audit-Trail ist die Git-Historie. "Wer hat das geändert und warum" beantwortet
<code>git blame</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="das-ergebnis">Das Ergebnis<a href="https://pascal-nehlsen.de/de/blog/terraform-golden-paths-gcp#das-ergebnis" class="hash-link" aria-label="Direkter Link zur Das Ergebnis" title="Direkter Link zur Das Ergebnis" translate="no">​</a></h2>
<p>Die Umgebung in Module entlang der Absicht mit Guardrails und GitOps-Auslieferung zu
konsolidieren hat das Provisioning von <strong>rund 4 Stunden Handarbeit auf unter 45 Minuten</strong>
gebracht, vollautomatisch: 80 % weniger. Genauso wichtig: die Support-Tickets für
Infrastruktur sind deutlich zurückgegangen, weil die häufigen Anfragen Self-Service wurden.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="mitnehmen">Mitnehmen<a href="https://pascal-nehlsen.de/de/blog/terraform-golden-paths-gcp#mitnehmen" class="hash-link" aria-label="Direkter Link zur Mitnehmen" title="Direkter Link zur Mitnehmen" translate="no">​</a></h2>
<ul>
<li class="">Schneide Module entlang der <strong>Absicht der Teams</strong>, nicht entlang des Ressourcenkatalogs des Cloud-Anbieters.</li>
<li class="">Leg die Security-Defaults <strong>ins</strong> Modul, damit der sichere Pfad der einfache ist.</li>
<li class="">Liefere über <strong>Pull Requests</strong> aus, damit der Plan geprüft wird und die Historie das Audit-Log ist.</li>
<li class="">Miss das, worauf es ankommt: <strong>Zeit bis zur Umgebung</strong>, nicht Zeilen HCL.</li>
</ul>]]></content>
        <author>
            <name>Pascal Nehlsen</name>
            <email>mail@pascal-nehlsen.de</email>
            <uri>https://github.com/PascalNehlsen</uri>
        </author>
        <category label="Terraform" term="Terraform"/>
        <category label="GCP" term="GCP"/>
        <category label="Platform Engineering" term="Platform Engineering"/>
        <category label="CI/CD" term="CI/CD"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Git-Security - Quellcode und Commits absichern]]></title>
        <id>https://pascal-nehlsen.de/de/blog/git-security-practices</id>
        <link href="https://pascal-nehlsen.de/de/blog/git-security-practices"/>
        <updated>2024-05-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Signierte Commits, Secret-Scanning vor dem Push, geschützte Branches, und was tatsächlich zu tun ist, wenn ein Key doch in die Historie gelangt.]]></summary>
        <content type="html"><![CDATA[<p>Dein Git-Repository ist mehr als Code. Es enthält Credentials, API-Keys, geistiges Eigentum und die Kronjuwelen deines Unternehmens. Sichern wir es richtig ab.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="der-vorfall-mit-dem-github-token">Der Vorfall mit dem GitHub-Token<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#der-vorfall-mit-dem-github-token" class="hash-link" aria-label="Direkter Link zur Der Vorfall mit dem GitHub-Token" title="Direkter Link zur Der Vorfall mit dem GitHub-Token" translate="no">​</a></h2>
<p>Letzte Woche hat ein Praktikant einen Commit mit einem GitHub Personal Access Token samt vollem Repo-Zugriff gepusht. Innerhalb von <strong>Minuten</strong> hat ein automatisierter Bot ihn gefunden und:</p>
<ol>
<li class="">alle unsere privaten Repositories geklont</li>
<li class="">Secrets aus der Commit-Historie gesammelt</li>
<li class="">Backdoor-Accounts angelegt</li>
</ol>
<p>Dieser Beitrag handelt davon, das zu verhindern.</p>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="1-commits-mit-gpg-signieren">1. Commits mit GPG signieren<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#1-commits-mit-gpg-signieren" class="hash-link" aria-label="Direkter Link zur 1. Commits mit GPG signieren" title="Direkter Link zur 1. Commits mit GPG signieren" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="warum-commits-signieren">Warum Commits signieren?<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#warum-commits-signieren" class="hash-link" aria-label="Direkter Link zur Warum Commits signieren?" title="Direkter Link zur Warum Commits signieren?" translate="no">​</a></h3>
<p>Jeder kann sich mit <code>git config user.name "Dein Name"</code> als du ausgeben. Signierte Commits belegen die Echtheit.</p>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="gpg-key-einrichten">GPG-Key einrichten<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#gpg-key-einrichten" class="hash-link" aria-label="Direkter Link zur GPG-Key einrichten" title="Direkter Link zur GPG-Key einrichten" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Generate GPG key</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">gpg --full-generate-key</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Choose: RSA and RSA, 4096 bits, no expiration</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># List keys</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">gpg --list-secret-keys --keyid-format</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">long</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Export public key</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">gpg </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--armor</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--export</span><span class="token plain"> YOUR_KEY_ID</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Add to GitHub: Settings &gt; SSH and GPG keys &gt; New GPG key</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="git-konfigurieren">Git konfigurieren<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#git-konfigurieren" class="hash-link" aria-label="Direkter Link zur Git konfigurieren" title="Direkter Link zur Git konfigurieren" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Set signing key</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--global</span><span class="token plain"> user.signingkey YOUR_KEY_ID</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Sign all commits by default</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--global</span><span class="token plain"> commit.gpgsign </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Sign tags</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--global</span><span class="token plain"> tag.gpgSign </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="signierte-commits-prüfen">Signierte Commits prüfen<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#signierte-commits-pr%C3%BCfen" class="hash-link" aria-label="Direkter Link zur Signierte Commits prüfen" title="Direkter Link zur Signierte Commits prüfen" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Verify last commit</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> verify-commit HEAD</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Show signature</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> log --show-signature</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Verify tag</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> verify-tag v1.0.0</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="2-branch-protection-regeln">2. Branch-Protection-Regeln<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#2-branch-protection-regeln" class="hash-link" aria-label="Direkter Link zur 2. Branch-Protection-Regeln" title="Direkter Link zur 2. Branch-Protection-Regeln" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="branch-protection-bei-github">Branch Protection bei GitHub<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#branch-protection-bei-github" class="hash-link" aria-label="Direkter Link zur Branch Protection bei GitHub" title="Direkter Link zur Branch Protection bei GitHub" translate="no">​</a></h3>
<div class="language-yaml codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-yaml codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># .github/branch-protection.yml</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule">protection</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">required_status_checks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule">strict</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule">contexts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"security/sast"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"security/secrets-scan"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"tests/unit"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"tests/integration"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">required_pull_request_reviews</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule">required_approving_review_count</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule">dismiss_stale_reviews</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule">require_code_owner_reviews</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">restrictions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule">users</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule">teams</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"security-team"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">enforce_admins</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">required_linear_history</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">allow_force_pushes</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">false</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">allow_deletions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">false</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="protected-branches-bei-gitlab">Protected Branches bei GitLab<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#protected-branches-bei-gitlab" class="hash-link" aria-label="Direkter Link zur Protected Branches bei GitLab" title="Direkter Link zur Protected Branches bei GitLab" translate="no">​</a></h3>
<div class="language-ruby codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-ruby codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token plain"># Via GitLab UI or API</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">POST /projects/:id/protected_branches</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">{</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  "name": "main",</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  "push_access_level": 0,  # No one</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  "merge_access_level": 30, # Developers</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  "unprotect_access_level": 40, # Maintainers</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  "allow_force_push": false,</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  "code_owner_approval_required": true</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="3-pre-commit-hooks-zur-secret-erkennung">3. Pre-commit-Hooks zur Secret-Erkennung<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#3-pre-commit-hooks-zur-secret-erkennung" class="hash-link" aria-label="Direkter Link zur 3. Pre-commit-Hooks zur Secret-Erkennung" title="Direkter Link zur 3. Pre-commit-Hooks zur Secret-Erkennung" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="pre-commit-framework-einrichten">pre-commit-Framework einrichten<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#pre-commit-framework-einrichten" class="hash-link" aria-label="Direkter Link zur pre-commit-Framework einrichten" title="Direkter Link zur pre-commit-Framework einrichten" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Install</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">pip </span><span class="token function" style="color:rgb(130, 170, 255)">install</span><span class="token plain"> pre-commit</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Create .pre-commit-config.yaml</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">cat</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token plain"> .pre-commit-config.yaml </span><span class="token operator" style="color:rgb(127, 219, 202)">&lt;&lt;</span><span class="token string" style="color:rgb(173, 219, 103)">EOF</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">repos:</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">  # Detect secrets</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">  - repo: https://github.com/Yelp/detect-secrets</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    rev: v1.4.0</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    hooks:</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      - id: detect-secrets</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">        args: ['--baseline', '.secrets.baseline']</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">  # Git-secrets</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">  - repo: https://github.com/awslabs/git-secrets</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    rev: master</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    hooks:</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      - id: git-secrets</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">  # Check for large files</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">  - repo: https://github.com/pre-commit/pre-commit-hooks</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    rev: v4.5.0</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    hooks:</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      - id: check-added-large-files</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">        args: ['--maxkb=500']</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      - id: check-merge-conflict</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      - id: check-yaml</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      - id: check-json</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      - id: trailing-whitespace</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      - id: end-of-file-fixer</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">  # Gitleaks for secret scanning</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">  - repo: https://github.com/gitleaks/gitleaks</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    rev: v8.18.0</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    hooks:</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      - id: gitleaks</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">EOF</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Install hooks</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">pre-commit </span><span class="token function" style="color:rgb(130, 170, 255)">install</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Run on all files</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">pre-commit run --all-files</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="eigener-pre-commit-hook">Eigener Pre-commit-Hook<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#eigener-pre-commit-hook" class="hash-link" aria-label="Direkter Link zur Eigener Pre-commit-Hook" title="Direkter Link zur Eigener Pre-commit-Hook" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token shebang important">#!/bin/bash</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># .git/hooks/pre-commit</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"Running security checks..."</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Check for AWS credentials</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">grep</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-r</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"AKIA[0-9A-Z]{16}"</span><span class="token plain"> --exclude-dir</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">.git </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">then</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"ERROR: AWS Access Key detected!"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">exit</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">fi</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Check for private keys</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">grep</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-r</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"BEGIN.*PRIVATE KEY"</span><span class="token plain"> --exclude-dir</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">.git </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">then</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"ERROR: Private key detected!"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">exit</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">fi</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Check for common password patterns</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">grep</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-ri</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"password\s*=\s*['</span><span class="token string entity" style="color:rgb(173, 219, 103)">\"</span><span class="token string" style="color:rgb(173, 219, 103)">]\w"</span><span class="token plain"> --exclude-dir</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">.git </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">then</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"ERROR: Hardcoded password detected!"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">exit</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">fi</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Check for Stripe keys</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">grep</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-r</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"sk_live_[0-9a-zA-Z]{24}"</span><span class="token plain"> --exclude-dir</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">.git </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">then</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"ERROR: Stripe secret key detected!"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">exit</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">fi</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"All security checks passed"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">exit</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="4-git-historie-aufräumen">4. Git-Historie aufräumen<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#4-git-historie-aufr%C3%A4umen" class="hash-link" aria-label="Direkter Link zur 4. Git-Historie aufräumen" title="Direkter Link zur 4. Git-Historie aufräumen" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="sensible-datei-aus-der-historie-entfernen">Sensible Datei aus der Historie entfernen<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#sensible-datei-aus-der-historie-entfernen" class="hash-link" aria-label="Direkter Link zur Sensible Datei aus der Historie entfernen" title="Direkter Link zur Sensible Datei aus der Historie entfernen" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Using BFG Repo-Cleaner (faster than git filter-branch)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">wget</span><span class="token plain"> https://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Remove file</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">java</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-jar</span><span class="token plain"> bfg-1.14.0.jar --delete-files secrets.env</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Remove passwords from all files</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">java</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-jar</span><span class="token plain"> bfg-1.14.0.jar --replace-text passwords.txt</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Clean up</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> reflog expire </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--expire</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">now </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--all</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> gc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--prune</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">now </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--aggressive</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Force push (coordinate with team!)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> push </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--force</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="mit-git-filter-repo">Mit git-filter-repo<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#mit-git-filter-repo" class="hash-link" aria-label="Direkter Link zur Mit git-filter-repo" title="Direkter Link zur Mit git-filter-repo" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Install</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">pip </span><span class="token function" style="color:rgb(130, 170, 255)">install</span><span class="token plain"> git-filter-repo</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Remove specific file</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> filter-repo </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--path</span><span class="token plain"> secrets.env --invert-paths</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Remove by pattern</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> filter-repo --path-glob </span><span class="token string" style="color:rgb(173, 219, 103)">'*.key'</span><span class="token plain"> --invert-paths</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Replace text</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'password123==&gt;***REMOVED***'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token plain"> replacements.txt</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> filter-repo --replace-text replacements.txt</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="5-repository-scannen">5. Repository scannen<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#5-repository-scannen" class="hash-link" aria-label="Direkter Link zur 5. Repository scannen" title="Direkter Link zur 5. Repository scannen" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="mit-gitleaks">Mit Gitleaks<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#mit-gitleaks" class="hash-link" aria-label="Direkter Link zur Mit Gitleaks" title="Direkter Link zur Mit Gitleaks" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Install</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">brew </span><span class="token function" style="color:rgb(130, 170, 255)">install</span><span class="token plain"> gitleaks  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># macOS</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># or</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">wget</span><span class="token plain"> https://github.com/gitleaks/gitleaks/releases/download/v8.18.0/gitleaks_8.18.0_linux_x64.tar.gz</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Scan current repository</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">gitleaks detect </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--verbose</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Scan specific commit range</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">gitleaks detect --log-opts</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">"HEAD^..HEAD"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Generate report</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">gitleaks detect --report-path gitleaks-report.json --report-format json</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="mit-trufflehog">Mit TruffleHog<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#mit-trufflehog" class="hash-link" aria-label="Direkter Link zur Mit TruffleHog" title="Direkter Link zur Mit TruffleHog" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Install</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">pip </span><span class="token function" style="color:rgb(130, 170, 255)">install</span><span class="token plain"> truffleHog</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Scan repository</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">trufflehog </span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> https://github.com/your-org/your-repo</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Scan local repo</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">trufflehog filesystem /path/to/repo</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Scan since specific commit</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">trufflehog </span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> file:///path/to/repo --since-commit abcd1234</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="einbindung-in-cicd">Einbindung in CI/CD<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#einbindung-in-cicd" class="hash-link" aria-label="Direkter Link zur Einbindung in CI/CD" title="Direkter Link zur Einbindung in CI/CD" translate="no">​</a></h3>
<div class="language-yaml codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-yaml codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># .gitlab-ci.yml</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule">security:gitleaks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">stage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> security</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> zricethezav/gitleaks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">latest</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">script</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> gitleaks detect </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">verbose </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">report</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">path gitleaks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">report.json</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">artifacts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule">reports</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token key atrule">secret_detection</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> gitleaks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">report.json</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule">paths</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> gitleaks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">report.json</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">allow_failure</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">false</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule">security:trufflehog</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">stage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> security</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> python</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token number" style="color:rgb(247, 140, 108)">3.11</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">script</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> pip install truffleHog</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> trufflehog filesystem . </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">json </span><span class="token punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain"> trufflehog</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">report.json</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">artifacts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule">paths</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> trufflehog</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">report.json</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="6-sichere-git-workflows">6. Sichere Git-Workflows<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#6-sichere-git-workflows" class="hash-link" aria-label="Direkter Link zur 6. Sichere Git-Workflows" title="Direkter Link zur 6. Sichere Git-Workflows" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="gitflow-mit-security-gates">Gitflow mit Security-Gates<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#gitflow-mit-security-gates" class="hash-link" aria-label="Direkter Link zur Gitflow mit Security-Gates" title="Direkter Link zur Gitflow mit Security-Gates" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-text codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token plain">main (protected)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  ├── develop (protected)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  │   ├── feature/user-auth (requires: SAST, secrets scan)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  │   ├── feature/payment (requires: SAST, DAST, security review)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  │   └── bugfix/login-issue</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  ├── release/v1.2.0 (requires: full security scan)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  └── hotfix/critical-vuln (emergency process)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="security-prüfungen-je-branch-typ">Security-Prüfungen je Branch-Typ<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#security-pr%C3%BCfungen-je-branch-typ" class="hash-link" aria-label="Direkter Link zur Security-Prüfungen je Branch-Typ" title="Direkter Link zur Security-Prüfungen je Branch-Typ" translate="no">​</a></h3>
<div class="language-yaml codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-yaml codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># .gitlab-ci.yml</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule">workflow</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">rules</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">if</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$CI_COMMIT_BRANCH =~ /^feature\/.*$/'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token key atrule">variables</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule">SECURITY_LEVEL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"standard"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">if</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$CI_COMMIT_BRANCH =~ /^release\/.*$/'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token key atrule">variables</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule">SECURITY_LEVEL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"full"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">if</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$CI_COMMIT_BRANCH == "main"'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token key atrule">variables</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule">SECURITY_LEVEL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"full"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule">security:scan</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule">script</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">|</span><span class="token scalar string" style="color:rgb(173, 219, 103)"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">      if [ "$SECURITY_LEVEL" == "full" ]; then</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">        echo "Running full security scan"</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">        gitleaks detect</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">        trivy fs . --severity HIGH,CRITICAL</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">        snyk test</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">      else</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">        echo "Running standard security scan"</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">        gitleaks detect</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">      fi</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="7-zugriffskontrolle-und-berechtigungen">7. Zugriffskontrolle und Berechtigungen<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#7-zugriffskontrolle-und-berechtigungen" class="hash-link" aria-label="Direkter Link zur 7. Zugriffskontrolle und Berechtigungen" title="Direkter Link zur 7. Zugriffskontrolle und Berechtigungen" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="team-struktur-bei-github">Team-Struktur bei GitHub<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#team-struktur-bei-github" class="hash-link" aria-label="Direkter Link zur Team-Struktur bei GitHub" title="Direkter Link zur Team-Struktur bei GitHub" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-text codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token plain">Organization</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">├── Admins (full access)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">├── Security Team (all repos, branch protection)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">├── Developers</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">│   ├── Backend Team (backend repos, write access)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">│   ├── Frontend Team (frontend repos, write access)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">│   └── DevOps Team (infra repos, write access)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">└── External Contributors (read-only, can fork)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="codeowners-datei">CODEOWNERS-Datei<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#codeowners-datei" class="hash-link" aria-label="Direkter Link zur CODEOWNERS-Datei" title="Direkter Link zur CODEOWNERS-Datei" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># .github/CODEOWNERS</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Default owners for everything</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">* @org/developers</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Security-sensitive files require security team review</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/security/ @org/security-team</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/.github/ @org/security-team @org/devops</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/Dockerfile @org/security-team @org/devops</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/docker-compose.yml @org/security-team @org/devops</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Infrastructure code requires DevOps review</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/terraform/ @org/devops @org/security-team</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/kubernetes/ @org/devops @org/security-team</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/.gitlab-ci.yml @org/devops</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Backend requires backend team</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/backend/ @org/backend-team</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/api/ @org/backend-team</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Frontend requires frontend team</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/frontend/ @org/frontend-team</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/web/ @org/frontend-team</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Database migrations require multiple approvals</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">/migrations/ @org/backend-team @org/database-admins</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Critical security files require admin approval</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">secrets.yml @org/admins @org/security-team</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">.env.* @org/admins @org/security-team</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="8-audit-logging-für-git">8. Audit-Logging für Git<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#8-audit-logging-f%C3%BCr-git" class="hash-link" aria-label="Direkter Link zur 8. Audit-Logging für Git" title="Direkter Link zur 8. Audit-Logging für Git" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="git-operationen-überwachen">Git-Operationen überwachen<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#git-operationen-%C3%BCberwachen" class="hash-link" aria-label="Direkter Link zur Git-Operationen überwachen" title="Direkter Link zur Git-Operationen überwachen" translate="no">​</a></h3>
<div class="language-python codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-python codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># git_audit_logger.py</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">import</span><span class="token plain"> git</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">import</span><span class="token plain"> json</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">import</span><span class="token plain"> logging</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">from</span><span class="token plain"> datetime </span><span class="token keyword" style="color:rgb(127, 219, 202)">import</span><span class="token plain"> datetime</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 139)">GitAuditLogger</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">__init__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> repo_path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">repo </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> git</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Repo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">repo_path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">setup_logging</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">setup_logging</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        logging</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">basicConfig</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            filename</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">'git-audit.log'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            level</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">logging</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">INFO</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token builtin" style="color:rgb(130, 170, 255)">format</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">'%(asctime)s - %(message)s'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">log_commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(173, 219, 103)">"""Log commit details"""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        log_entry </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token string" style="color:rgb(173, 219, 103)">'action'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'commit'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token string" style="color:rgb(173, 219, 103)">'sha'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">hexsha</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token string" style="color:rgb(173, 219, 103)">'author'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">author</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token string" style="color:rgb(173, 219, 103)">'email'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">author</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">email</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token string" style="color:rgb(173, 219, 103)">'message'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token string" style="color:rgb(173, 219, 103)">'timestamp'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">committed_datetime</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">isoformat</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token string" style="color:rgb(173, 219, 103)">'files_changed'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">len</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">stats</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token string" style="color:rgb(173, 219, 103)">'insertions'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">stats</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">total</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">'insertions'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token string" style="color:rgb(173, 219, 103)">'deletions'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">stats</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">total</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">'deletions'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        logging</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">info</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">json</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">dumps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">log_entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">audit_recent_commits</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> days</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">7</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(173, 219, 103)">"""Audit commits from last N days"""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        since </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> datetime</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">now</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">-</span><span class="token plain"> timedelta</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">days</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">days</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> commit </span><span class="token keyword" style="color:rgb(127, 219, 202)">in</span><span class="token plain"> self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">repo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">iter_commits</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">since</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">since</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">log_commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">detect_suspicious_activity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token triple-quoted-string string" style="color:rgb(173, 219, 103)">"""Detect suspicious patterns"""</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        alerts </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> commit </span><span class="token keyword" style="color:rgb(127, 219, 202)">in</span><span class="token plain"> self</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">repo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">iter_commits</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">max_count</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">100</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Large deletions (potential data destruction)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">stats</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">total</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">'deletions'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1000</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                alerts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">append</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                    </span><span class="token string" style="color:rgb(173, 219, 103)">'severity'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'high'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                    </span><span class="token string" style="color:rgb(173, 219, 103)">'type'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'large_deletion'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                    </span><span class="token string" style="color:rgb(173, 219, 103)">'commit'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">hexsha</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                    </span><span class="token string" style="color:rgb(173, 219, 103)">'author'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">author</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">email</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Commits at unusual hours (potential compromise)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            hour </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">committed_datetime</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">hour</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            </span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> hour </span><span class="token operator" style="color:rgb(127, 219, 202)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">6</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">or</span><span class="token plain"> hour </span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">22</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                alerts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">append</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                    </span><span class="token string" style="color:rgb(173, 219, 103)">'severity'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'medium'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                    </span><span class="token string" style="color:rgb(173, 219, 103)">'type'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'unusual_hour'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                    </span><span class="token string" style="color:rgb(173, 219, 103)">'commit'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">hexsha</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                    </span><span class="token string" style="color:rgb(173, 219, 103)">'time'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">committed_datetime</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">isoformat</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">return</span><span class="token plain"> alerts</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Usage</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">audit </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> GitAuditLogger</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">'/path/to/repo'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">audit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">audit_recent_commits</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">days</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">30</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">alerts </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> audit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">detect_suspicious_activity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> alert </span><span class="token keyword" style="color:rgb(127, 219, 202)">in</span><span class="token plain"> alerts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"WARNING: </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">alert</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string-interpolation interpolation string" style="color:rgb(173, 219, 103)">'severity'</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token string-interpolation interpolation">upper</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">: </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">alert</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string-interpolation interpolation string" style="color:rgb(173, 219, 103)">'type'</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> - </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">alert</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string-interpolation interpolation string" style="color:rgb(173, 219, 103)">'commit'</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="9-sichere-git-konfiguration">9. Sichere Git-Konfiguration<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#9-sichere-git-konfiguration" class="hash-link" aria-label="Direkter Link zur 9. Sichere Git-Konfiguration" title="Direkter Link zur 9. Sichere Git-Konfiguration" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="globale-security-einstellungen">Globale Security-Einstellungen<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#globale-security-einstellungen" class="hash-link" aria-label="Direkter Link zur Globale Security-Einstellungen" title="Direkter Link zur Globale Security-Einstellungen" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Prevent accidental pushes to wrong remote</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--global</span><span class="token plain"> push.default simple</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Always use SSH instead of HTTPS</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--global</span><span class="token plain"> url.</span><span class="token string" style="color:rgb(173, 219, 103)">"git@github.com:"</span><span class="token plain">.insteadOf </span><span class="token string" style="color:rgb(173, 219, 103)">"https://github.com/"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Enable credential helper (cached credentials)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--global</span><span class="token plain"> credential.helper </span><span class="token string" style="color:rgb(173, 219, 103)">'cache --timeout=3600'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Auto-fetch with prune</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--global</span><span class="token plain"> fetch.prune </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Show status in short format</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--global</span><span class="token plain"> status.short </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Use rebase instead of merge for pulls</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--global</span><span class="token plain"> pull.rebase </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Sign all tags by default</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--global</span><span class="token plain"> tag.gpgSign </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_hDQi" id="einstellungen-pro-repository">Einstellungen pro Repository<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#einstellungen-pro-repository" class="hash-link" aria-label="Direkter Link zur Einstellungen pro Repository" title="Direkter Link zur Einstellungen pro Repository" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Inside repository</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">cd</span><span class="token plain"> your-repo</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Require signed commits</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config commit.gpgsign </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Set up hooks directory</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config core.hooksPath .githooks</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Enable fsck on receive</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> config receive.fsckObjects </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="security-checkliste">Security-Checkliste<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#security-checkliste" class="hash-link" aria-label="Direkter Link zur Security-Checkliste" title="Direkter Link zur Security-Checkliste" translate="no">​</a></h2>
<ul class="contains-task-list containsTaskList_ZWYu">
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->GPG-Commit-Signierung aktivieren</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Branch-Protection-Regeln konfigurieren</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Pre-commit-Hooks zur Secret-Erkennung einrichten</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->CODEOWNERS-Datei anlegen</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->2FA für alle Teammitglieder aktivieren</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Repository regelmäßig scannen (gitleaks, trufflehog)</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Git-Zugriffslogs monatlich prüfen</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Force-Push-Rechte einschränken</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->SSH-Keys jährlich prüfen und rotieren</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Team zu Git-Security schulen</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Incident Response für geleakte Credentials dokumentieren</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->SSH-Keys statt Passwörter verwenden</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Security-Gates in CI/CD einbauen</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_hDQi" id="notfall-geleakte-credentials">Notfall: geleakte Credentials<a href="https://pascal-nehlsen.de/de/blog/git-security-practices#notfall-geleakte-credentials" class="hash-link" aria-label="Direkter Link zur Notfall: geleakte Credentials" title="Direkter Link zur Notfall: geleakte Credentials" translate="no">​</a></h2>
<div class="language-bash codeBlockContainer_NY4W theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_FRkK"><pre tabindex="0" class="prism-code language-bash codeBlock_ecQm thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_Xp1x"><div class="token-line" style="color:#d6deeb"><span class="token shebang important">#!/bin/bash</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># emergency-git-cleanup.sh</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"EMERGENCY: Credential Leak Response"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># 1. Revoke compromised credentials immediately</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"[1/5] Revoking credentials..."</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Call your secrets management API</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># 2. Scan entire git history</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"[2/5] Scanning git history..."</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">gitleaks detect </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--verbose</span><span class="token plain"> --log-opts</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">"--all"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># 3. Remove secrets from history</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"[3/5] Cleaning git history..."</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">java</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-jar</span><span class="token plain"> bfg.jar --replace-text passwords.txt</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> reflog expire </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--expire</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">now </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--all</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> gc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--prune</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">now </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--aggressive</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># 4. Notify team</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"[4/5] Notifying team..."</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">gh api /repos/:owner/:repo/issues </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-X</span><span class="token plain"> POST </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-f</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">title</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">"Security Incident: Credentials Leaked"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-f</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">body</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">"Immediate action required. Check Slack for details."</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># 5. Force push (DANGEROUS - coordinate first!)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"[5/5] Force pushing clean history..."</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">read</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-p</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"Are you sure you want to force push? (yes/no): "</span><span class="token plain"> confirm</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token string variable" style="color:rgb(214, 222, 235)">$confirm</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">==</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"yes"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">then</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> push </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--force</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--all</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> push </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--force</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">fi</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"Emergency response complete"</span><br></div></code></pre></div></div>
<hr>
<p><em>Sicherst du deine Git-Workflows ab? Teile deine Tipps auf <a href="https://github.com/PascalNehlsen" target="_blank" rel="noopener noreferrer" class="">GitHub</a>!</em></p>]]></content>
        <author>
            <name>Pascal Nehlsen</name>
            <email>mail@pascal-nehlsen.de</email>
            <uri>https://github.com/PascalNehlsen</uri>
        </author>
        <category label="Git" term="Git"/>
        <category label="DevSecOps" term="DevSecOps"/>
        <category label="Secrets" term="Secrets"/>
    </entry>
</feed>