<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>nunogrl.com - security</title><link href="https://nunogrl.com/" rel="alternate"></link><link href="https://nunogrl.com/categories/security/atom.xml" rel="self"></link><id>https://nunogrl.com/</id><updated>2024-08-01T00:00:00+01:00</updated><entry><title>Homelab Network Overview</title><link href="https://nunogrl.com/articles/homelab-network-overview/" rel="alternate"></link><published>2024-08-01T00:00:00+01:00</published><updated>2024-08-01T00:00:00+01:00</updated><author><name>Nuno Leitao</name></author><id>tag:nunogrl.com,2024-08-01:/articles/homelab-network-overview/</id><summary type="html">&lt;p class="first last"&gt;A comprehensive guide to building a secure homelab network with VLANs, DNS, monitoring, and automation&lt;/p&gt;
</summary><content type="html">&lt;p&gt;My homelab network is designed to provide a &lt;strong&gt;secure, efficient, and self-hosted environment&lt;/strong&gt;
for various automation, development, and personal infrastructure needs.
This setup prioritizes &lt;strong&gt;network segmentation, security, and performance optimization&lt;/strong&gt;,
while being flexible enough to scale or adapt for experimentation.&lt;/p&gt;
&lt;div class="section" id="problem-solution"&gt;
&lt;h2&gt;Problem &amp;amp; Solution&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; I needed a reliable and secure environment for automation, CI/CD testing, Git hosting, and local infrastructure—
&lt;strong&gt;without relying on cloud platforms or exposing services to the internet&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Additionally, the solution had to run on &lt;strong&gt;low-powered, repurposed hardware&lt;/strong&gt; with minimal overhead
and support &lt;strong&gt;remote access&lt;/strong&gt;, &lt;strong&gt;internal DNS resolution&lt;/strong&gt;, and &lt;strong&gt;segmented security domains&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; I architected a network centered around an OpenWRT-based router with VLAN segmentation,
isolated zones for each function, and layered services:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;Tailscale&lt;/strong&gt; provides secure access to internal services, even when offsite.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare Tunnel&lt;/strong&gt; allows for secure access to internal services from the internet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AdGuard Home&lt;/strong&gt; filters DNS-based ads and trackers at the router level.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TinyDNS + BIND&lt;/strong&gt; handle authoritative DNS within the homelab.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Traefik&lt;/strong&gt; serves as the reverse proxy using a wildcard cert via DNS verification.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prometheus + Grafana&lt;/strong&gt; provide observability for all infrastructure nodes.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;D-Link 3782 router&lt;/strong&gt; is used as a wireless bridge to isolate the IoT network.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The OpenWRT router also provides wireless access to mobile and personal devices,
which are segmented into their own VLAN. These include laptops, phones, and tablets
used for managing or testing infrastructure services.&lt;/p&gt;
&lt;p&gt;For mobile devices, &lt;strong&gt;Syncthing&lt;/strong&gt; is used to selectively back up content to the NAS.
While backups are not fully automated, this gives more control over what is stored.
I am considering adding a backup option to &lt;strong&gt;Dropbox&lt;/strong&gt; for external redundancy.&lt;/p&gt;
&lt;p&gt;The entire infrastructure is &lt;strong&gt;provisioned via Ansible playbooks&lt;/strong&gt;, which manage deployment
and configuration across the environment. These playbooks live on an internal Git server
and may be shared publicly in the future.&lt;/p&gt;
&lt;p&gt;The system emphasizes &lt;strong&gt;modularity&lt;/strong&gt;, &lt;strong&gt;resilience&lt;/strong&gt;, and &lt;strong&gt;observability&lt;/strong&gt;, ensuring that
each component is isolated but observable.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="full-network-topology-combined"&gt;
&lt;h2&gt;Full Network Topology (Combined)&lt;/h2&gt;
&lt;div class="mermaid" id="mermaid-diagram-9078242182121851762"&gt;
flowchart TD
    %% ingress egress
    Internet --&gt; Router
    Router --&gt;|VPN: Site2Site| VPNCloudflare
    Router --&gt;|VPN: host| VPNTailscale

    %% DNS
    Router -.-&gt; AdGuard
    AdGuard -.-&gt; BIND
    BIND -.-&gt; TinyDNS


    %%        Traefik --&gt; Router
    %%        Traefik --&gt; IoT_Bridge

    %%        Prometheus --&gt; NAS
    %%        Prometheus --&gt; Server1
    %%        Prometheus --&gt; CIService
    %%        Prometheus --&gt; Router
    %%        Grafana --&gt; Prometheus

    Router ==&gt;|VLAN: NAS| NAS
    Router ==&gt;|VLAN: Dev| Server1
    Router ==&gt;|VLAN: CI| Zeus
    Router ==&gt;|VLAN: IoT| IoT_Bridge
    Router ==&gt;|VLAN: WiFi| Wireless_Clients
    IoT_Bridge --&gt;|Wireless| IoT_Devices

    %%subgraph rproxy [reverse proxy]
    %%            Traefik --&gt; GitServer
    %%            Traefik --&gt; CIService
    %%            Traefik --&gt; Grafana
    %%            Traefik --&gt; Syncthing
    %%            Traefik --&gt; Portainer
    %%            Traefik --&gt; Prometheus
    %%            Traefik --&gt; NASUI
    %%            Traefik --&gt; binrepo
    %%        end




    %% description
    VPNCloudflare((VPN fa:fa-lock
                cloudflared
                tunnel))
    VPNTailscale((VPN fa:fa-lock
                tailscale
                server
                ))
    Router{{Router}}
    IoT_Bridge{{IoT Bridge}}
    Internet(((Internet
            fa:fa-cloud)))
    %% NASUI([homepage fab:fa-docker])
    %% GitServer([git fab:fa-docker])

    %% CIService([CIService fab:fa-docker])
    %% Grafana([grafana fab:fa-docker])
    %% Portainer([Portainer fab:fa-docker])
    %% Traefik([traefik fab:fa-docker])
    %% Syncthing([Syncthing fab:fa-docker])
    %% Prometheus([Prometheus fab:fa-docker])
    %% binrepo([Binary Repo fab:fa-docker])
    Server1[Raspberry Pi]


    %% styles
    classDef default fill:#f9f,stroke:#333,stroke-width:1px;
    classDef net fill:#fff;
    classDef hardware fill:#f96;
    classDef dns fill:#AFF;
    classDef container fill:#EF0;
    classDef vpn fill:#EF0;
    classDef network fill:#CCCCCC;

    Internet:::net

    VPNCloudflare:::vpn
    VPNTailscale:::vpn

    AdGuard:::dns
    BIND:::dns
    TinyDNS:::dns

    Router:::network
    IoT_Bridge:::network
    NAS:::hardware
    Server1:::hardware
    Zeus:::hardware

    Wireless_Clients:::hardware
    IoT_Devices:::hardware

    %% NASUI:::container
    %% GitServer:::container
    %% CIService:::container
    %% binrepo:::container
    %% Grafana:::container
    %% Portainer:::container
    %% Traefik:::container
    %% Syncthing:::container
    %% Prometheus:::container&lt;/div&gt;&lt;p&gt;This shows how DNS resolution, secure access, proxy routing, and monitoring interconnect.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="layered-views-progressive-breakdown"&gt;
&lt;h2&gt;Layered Views (Progressive Breakdown)&lt;/h2&gt;
&lt;div class="section" id="vpn"&gt;
&lt;h3&gt;VPN&lt;/h3&gt;
&lt;div class="mermaid" id="mermaid-diagram-7797067824243999538"&gt;
%% styles
classDef default fill:#f9f,stroke:#333,stroke-width:1px;
classDef net fill:#fff;
classDef vpn fill:#EF0;
classDef network fill:#CCCCCC;


flowchart TD
    Internet --&gt;|VPN: Cloudflare| VPNCloudflare
    Internet --&gt;|VPN: Tailscale| VPNTailscale

subgraph cf [cloudflare VPN tunnels]
        InternetCF -.-&gt; |https
                         ingress|cloudflare
        cloudflare -.-&gt; |http|vaultvpn
        cloudflare{{cloudflare
                   pulsingminds}}
        cloudflare --- Londonvpn
        cloudflare --- hetznervpn
        cloudflare --- vaultvpn
end
Londonvpn((VPN fa:fa-lock
            London Tunnel))
hetznervpn((VPN fa:fa-lock
            Hetzner Tunnel))
vaultvpn((VPN fa:fa-lock
            vault Tunnell))
InternetCF(((Internet
                fa:fa-cloud)))
InternetCF:::net
cloudflare:::network
Londonvpn:::vpn
hetznervpn:::vpn
vaultvpn:::vpn
        InternetTS --- tailscale
        tailscale{{Tailscale}}
        tailscale --- Londonts
        tailscale --- magits
        tailscale --- capricets
        tailscale --- mobilets
end
Londonts((VPN fa:fa-lock
            London Tunnel
            _route propagation_))
magits((VPN fa:fa-lock
            Hetzner Tunnel))
capricets((VPN fa:fa-lock
            laptop Tunnell))
mobilets(((VPN fa:fa-lock
           mobile Tunnel)))
InternetTS(((Internet
                fa:fa-cloud)))
tailscale:::network
Londonts:::vpn
magits:::vpn
capricets:::vpn
mobilets:::vpn&lt;/div&gt;&lt;/div&gt;
&lt;div class="section" id="dns-resolution-flow"&gt;
&lt;h3&gt;DNS Resolution Flow&lt;/h3&gt;
&lt;div class="mermaid" id="mermaid-diagram--5116182746477425768"&gt;
flowchart TD
    Client --&gt; AdGuard
    AdGuard --&gt; BIND
    BIND -.-&gt; I
    BIND -.-&gt; L
    BIND --&gt; TinyDNS
    BIND -.-&gt; LXC

L((Local network))
I((Internet))
LXC((LXC_Containers))&lt;/div&gt;&lt;/div&gt;
&lt;div class="section" id="traefik-reverse-proxy-flow"&gt;
&lt;h3&gt;Traefik Reverse Proxy Flow&lt;/h3&gt;
&lt;div class="mermaid" id="mermaid-diagram--2508032663135504021"&gt;
flowchart TD
    Internet --&gt;|DNS Challenge| Traefik
    Traefik --&gt; GitServer
    Traefik --&gt; Grafana
    Traefik --&gt; CIService
    Traefik --&gt; binRepo
    Traefik --&gt; Syncthing
    Traefik --&gt; Portainer
    Traefik --&gt; RouterUI
    Traefik --&gt; NASUI
    Traefik --&gt; IoT_Bridge&lt;/div&gt;&lt;/div&gt;
&lt;div class="section" id="prometheus-monitoring-flow"&gt;
&lt;h3&gt;Prometheus Monitoring Flow&lt;/h3&gt;
&lt;div class="mermaid" id="mermaid-diagram--3288697517812673026"&gt;
flowchart TD
    Prometheus --&gt; NAS
    Prometheus --&gt; Server1
    Prometheus --&gt; CIService
    Prometheus --&gt; Router
    Prometheus --&gt; IoT_Bridge
    Grafana --&gt; Prometheus&lt;/div&gt;&lt;p&gt;Each layer can be inspected individually or in combination via Grafana dashboards and log collectors.
This &lt;strong&gt;layered view mirrors how the infrastructure is designed, monitored, and interacted with.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="Infrastructure Automation"></category><category term="homelab"></category><category term="networking"></category><category term="infrastructure"></category><category term="openwrt"></category><category term="dns"></category><category term="monitoring"></category><category term="vlans"></category><category term="security"></category></entry><entry><title>Enforcing GPG-Signed Commits in Git</title><link href="https://nunogrl.com/articles/enforcing-gpg-signed-commits-git/" rel="alternate"></link><published>2024-03-21T00:00:00+00:00</published><updated>2024-03-21T00:00:00+00:00</updated><author><name>Nuno Leitao</name></author><id>tag:nunogrl.com,2024-03-21:/articles/enforcing-gpg-signed-commits-git/</id><summary type="html">&lt;p class="first last"&gt;Learn how to enforce GPG-signed commits in Git to prevent commit impersonation and ensure code authenticity&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="problem-solution"&gt;
&lt;h2&gt;🚀 Problem &amp;amp; Solution&lt;/h2&gt;
&lt;div class="section" id="context-backstory"&gt;
&lt;h3&gt;📌 &lt;strong&gt;Context / Backstory&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;In our collaborative development environment, we discovered that Git's flexibility allows commits under any name and email. This became a security concern when we realized that GitHub identifies users by email, not SSH keys.&lt;/p&gt;
&lt;div class="mermaid" id="mermaid-diagram--1710153734321077480"&gt;
sequenceDiagram
  participant Alice
  participant Bob
  participant GitHub

  Alice-&gt;&gt;GitHub: Commit signed with alice@example.com (GPG signed)
  GitHub-&gt;&gt;GitHub: Shows "Verified" commit from Alice

  Bob-&gt;&gt;GitHub: Commit using alice@example.com (no signature)
  GitHub-&gt;&gt;GitHub: Shows commit as from "Alice" (Unverified)

  Note over GitHub: GitHub matches commits by email, not by SSH or true identity.&lt;/div&gt;&lt;/div&gt;
&lt;div class="section" id="the-problem"&gt;
&lt;h3&gt;⚠️ &lt;strong&gt;The Problem&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Anyone with repository access can spoof another contributor's identity&lt;/li&gt;
&lt;li&gt;Commit history could be manipulated without detection&lt;/li&gt;
&lt;li&gt;No cryptographic proof of commit authenticity&lt;/li&gt;
&lt;li&gt;GitHub's user identification relies solely on email addresses&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="the-solution"&gt;
&lt;h3&gt;💡 &lt;strong&gt;The Solution&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;We implemented mandatory GPG-signed commits, which:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Cryptographically verify commit authenticity&lt;/li&gt;
&lt;li&gt;Prevent identity spoofing&lt;/li&gt;
&lt;li&gt;Create traceable commit history&lt;/li&gt;
&lt;li&gt;Integrate with GitHub's verification system&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="who-this-helps"&gt;
&lt;h3&gt;👥 &lt;strong&gt;Who This Helps&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Security-conscious development teams&lt;/li&gt;
&lt;li&gt;Open-source project maintainers&lt;/li&gt;
&lt;li&gt;Regulated environments requiring audit trails&lt;/li&gt;
&lt;li&gt;Organizations needing verified commit history&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="technical-implementation"&gt;
&lt;h2&gt;⚙️ Technical Implementation&lt;/h2&gt;
&lt;p&gt;Let's visualize the GPG signing workflow:&lt;/p&gt;
&lt;div class="mermaid" id="mermaid-diagram-1440076246032696055"&gt;
flowchart LR
   C[Commit] --&gt;|Sign| G[GPG Key]
   G --&gt;|Verify| GH[GitHub]

   subgraph "Local System"
   C
   G
   end

   subgraph "Remote"
   GH
   end

   style GH fill:#f96,stroke:#333
   style G fill:#9f6,stroke:#333&lt;/div&gt;&lt;div class="section" id="setting-up-gpg-keys"&gt;
&lt;h3&gt;1️⃣ Setting Up GPG Keys&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Generate a new GPG key&lt;/span&gt;
gpg&lt;span class="w"&gt; &lt;/span&gt;--full-generate-key

&lt;span class="c1"&gt;# List your keys&lt;/span&gt;
gpg&lt;span class="w"&gt; &lt;/span&gt;--list-secret-keys&lt;span class="w"&gt; &lt;/span&gt;--keyid-format&lt;span class="o"&gt;=&lt;/span&gt;long
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="configuring-git"&gt;
&lt;h3&gt;2️⃣ Configuring Git&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;# &lt;/span&gt;Configure&lt;span class="w"&gt; &lt;/span&gt;Git&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;use&lt;span class="w"&gt; &lt;/span&gt;your&lt;span class="w"&gt; &lt;/span&gt;GPG&lt;span class="w"&gt; &lt;/span&gt;key
&lt;span class="gp"&gt;$ &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--global&lt;span class="w"&gt; &lt;/span&gt;user.signingkey&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;YOUR_KEY_ID&amp;gt;
&lt;span class="gp"&gt;$ &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--global&lt;span class="w"&gt; &lt;/span&gt;commit.gpgsign&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="gp"&gt;$ &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--global&lt;span class="w"&gt; &lt;/span&gt;gpg.program&lt;span class="w"&gt; &lt;/span&gt;gpg
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="github-integration"&gt;
&lt;h3&gt;3️⃣ GitHub Integration&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Export your public GPG key:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;gpg&lt;span class="w"&gt; &lt;/span&gt;--armor&lt;span class="w"&gt; &lt;/span&gt;--export&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;YOUR_KEY_ID&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;Add the key to your GitHub account settings&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="enforcing-signed-commits"&gt;
&lt;h3&gt;4️⃣ Enforcing Signed Commits&lt;/h3&gt;
&lt;p&gt;In GitHub repository settings:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Navigate to Settings &amp;gt; Branches&lt;/li&gt;
&lt;li&gt;Add branch protection rule&lt;/li&gt;
&lt;li&gt;Enable &amp;quot;Require signed commits&amp;quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="troubleshooting-debugging"&gt;
&lt;h2&gt;🛠️ Troubleshooting &amp;amp; Debugging&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;GPG signing fails&lt;/strong&gt;: Check &lt;cite&gt;gpg-agent&lt;/cite&gt; configuration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub doesn't show &amp;quot;Verified&amp;quot;&lt;/strong&gt;: Ensure GPG key is added to GitHub&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CD issues&lt;/strong&gt;: Set up proper &lt;cite&gt;GNUPGHOME&lt;/cite&gt; environment&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Smart card/YubiKey&lt;/strong&gt;: Verify proper card reader access&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="optimizations-best-practices"&gt;
&lt;h2&gt;🔁 Optimizations &amp;amp; Best Practices&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Use GPG subkeys instead of master keys&lt;/li&gt;
&lt;li&gt;Implement regular key rotation&lt;/li&gt;
&lt;li&gt;Set up separate signing keys for different contexts&lt;/li&gt;
&lt;li&gt;Use environment isolation in CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Consider hardware security keys (YubiKey) for key storage&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion-takeaways"&gt;
&lt;h2&gt;✅ Conclusion &amp;amp; Takeaways&lt;/h2&gt;
&lt;p&gt;GPG-signed commits provide a robust security layer for Git workflows, ensuring:
- Verified commit authenticity
- Protected repository history
- Clear accountability
- Compliance with security best practices&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="comments-next-steps"&gt;
&lt;h2&gt;💬 Comments &amp;amp; Next Steps&lt;/h2&gt;
&lt;p&gt;How do you handle commit verification in your organization? Share your experience or ask questions below!&lt;/p&gt;
&lt;/div&gt;
</content><category term="Infrastructure Security"></category><category term="git"></category><category term="gpg"></category><category term="security"></category><category term="devops"></category><category term="version-control"></category><category term="cryptography"></category><category term="authentication"></category></entry><entry><title>Password Store with GPG and Git</title><link href="https://nunogrl.com/articles/password-store-gpg-git/" rel="alternate"></link><published>2024-03-21T00:00:00+00:00</published><updated>2024-03-21T00:00:00+00:00</updated><author><name>Nuno Leitao</name></author><id>tag:nunogrl.com,2024-03-21:/articles/password-store-gpg-git/</id><summary type="html">&lt;p class="first last"&gt;Learn how to set up a secure, Git-based password management system using password-store and GPG encryption&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="problem-solution"&gt;
&lt;h2&gt;🚀 Problem &amp;amp; Solution&lt;/h2&gt;
&lt;div class="section" id="context-backstory"&gt;
&lt;h3&gt;📌 &lt;strong&gt;Context / Backstory&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;We needed a secure way to manage passwords and secrets across multiple servers and team members. Commercial password managers were either too complex, costly, or required external services we wanted to avoid.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-problem"&gt;
&lt;h3&gt;⚠️ &lt;strong&gt;The Problem&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Managing secrets across systems and teams presents several challenges:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Keeping passwords secure yet accessible&lt;/li&gt;
&lt;li&gt;Tracking changes and maintaining history&lt;/li&gt;
&lt;li&gt;Sharing secrets securely between team members&lt;/li&gt;
&lt;li&gt;Avoiding dependency on external services&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="the-solution"&gt;
&lt;h3&gt;💡 &lt;strong&gt;The Solution&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;We implemented &lt;cite&gt;password-store&lt;/cite&gt; with GPG encryption and Git integration, providing:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Secure GPG encryption for all secrets&lt;/li&gt;
&lt;li&gt;Git-based version control and distribution&lt;/li&gt;
&lt;li&gt;Fully local operation with no external dependencies&lt;/li&gt;
&lt;li&gt;Command-line interface for automation&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="who-this-helps"&gt;
&lt;h3&gt;👥 &lt;strong&gt;Who This Helps&lt;/strong&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;System administrators managing multiple servers&lt;/li&gt;
&lt;li&gt;DevOps teams handling shared credentials&lt;/li&gt;
&lt;li&gt;Security-conscious users wanting local password management&lt;/li&gt;
&lt;li&gt;Teams needing version-controlled secrets&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="technical-implementation"&gt;
&lt;h2&gt;⚙️ Technical Implementation&lt;/h2&gt;
&lt;p&gt;Let's visualize the password-store workflow:&lt;/p&gt;
&lt;div class="mermaid" id="mermaid-diagram--7232498932700614839"&gt;
flowchart LR
   P[Password] --&gt;|Encrypt| G[GPG]
   G --&gt;|Store| PS[password-store]
   PS --&gt;|Version| Git[Git Repository]
   Git --&gt;|Sync| T[Team Members]

   subgraph "Local System"
   P
   G
   PS
   end

   subgraph "Distribution"
   Git
   T
   end&lt;/div&gt;&lt;div class="section" id="generating-gpg-keys-in-batch-mode"&gt;
&lt;h3&gt;1️⃣ Generating GPG Keys in Batch Mode&lt;/h3&gt;
&lt;p&gt;For automated environments:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;gpg-server-key.conf&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt;EOF&lt;/span&gt;
&lt;span class="s"&gt;%no-protection&lt;/span&gt;
&lt;span class="s"&gt;Key-Type: default&lt;/span&gt;
&lt;span class="s"&gt;Subkey-Type: default&lt;/span&gt;
&lt;span class="s"&gt;Name-Real: Server Automation Key&lt;/span&gt;
&lt;span class="s"&gt;Name-Email: server@example.com&lt;/span&gt;
&lt;span class="s"&gt;Expire-Date: 0&lt;/span&gt;
&lt;span class="s"&gt;%commit&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;

gpg&lt;span class="w"&gt; &lt;/span&gt;--batch&lt;span class="w"&gt; &lt;/span&gt;--generate-key&lt;span class="w"&gt; &lt;/span&gt;gpg-server-key.conf
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="setting-up-the-environment"&gt;
&lt;h3&gt;2️⃣ Setting Up the Environment&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PASSWORD_STORE_GPG_OPTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;--armor&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;GNUPGHOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/password-store/.gnupg
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PASSWORD_STORE_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/password-store/store
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="initializing-the-password-store"&gt;
&lt;h3&gt;3️⃣ Initializing the Password Store&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$GNUPGHOME&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$PASSWORD_STORE_DIR&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
chmod&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$GNUPGHOME&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$PASSWORD_STORE_DIR&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
pass&lt;span class="w"&gt; &lt;/span&gt;init&lt;span class="w"&gt; &lt;/span&gt;server@example.com
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="git-integration"&gt;
&lt;h3&gt;4️⃣ Git Integration&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$PASSWORD_STORE_DIR&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;init
git&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;.
git&lt;span class="w"&gt; &lt;/span&gt;commit&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Initial password store&amp;quot;&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;remote&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;origin&lt;span class="w"&gt; &lt;/span&gt;git@example.com:secrets.git
git&lt;span class="w"&gt; &lt;/span&gt;push&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;origin&lt;span class="w"&gt; &lt;/span&gt;main
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="troubleshooting-debugging"&gt;
&lt;h2&gt;🛠️ Troubleshooting &amp;amp; Debugging&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Ensure proper GPG key permissions (700 for directories, 600 for files)&lt;/li&gt;
&lt;li&gt;Verify GPG recipient when encryption fails&lt;/li&gt;
&lt;li&gt;Check Git remote access rights for sync issues&lt;/li&gt;
&lt;li&gt;Monitor Git conflicts when multiple users update simultaneously&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="optimizations-alternatives"&gt;
&lt;h2&gt;🔁 Optimizations &amp;amp; Alternatives&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Consider using GPG agent for improved key handling&lt;/li&gt;
&lt;li&gt;Implement Git hooks for pre-commit validation&lt;/li&gt;
&lt;li&gt;Use Git branches for testing password updates&lt;/li&gt;
&lt;li&gt;Consider &lt;cite&gt;pass&lt;/cite&gt; extensions for additional features&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion-takeaways"&gt;
&lt;h2&gt;✅ Conclusion &amp;amp; Takeaways&lt;/h2&gt;
&lt;p&gt;Using GPG with password-store provides a &lt;strong&gt;flexible, secure, and lightweight&lt;/strong&gt; method for managing secrets across machines. With Git integration, you get version history, team sharing, and distributed backup—&lt;strong&gt;without compromising security&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="comments-next-steps"&gt;
&lt;h2&gt;💬 Comments &amp;amp; Next Steps&lt;/h2&gt;
&lt;p&gt;How do you manage shared secrets in your infrastructure? Share your experience or ask questions below!&lt;/p&gt;
&lt;/div&gt;
</content><category term="Infrastructure Security"></category><category term="gpg"></category><category term="git"></category><category term="password-management"></category><category term="security"></category><category term="encryption"></category><category term="devops"></category><category term="secrets-management"></category></entry><entry><title>Managing Multiple Git Configurations</title><link href="https://nunogrl.com/articles/git-config/" rel="alternate"></link><published>2020-08-31T10:00:00+01:00</published><updated>2020-08-31T10:00:00+01:00</updated><author><name>Nuno Leitao</name></author><id>tag:nunogrl.com,2020-08-31:/articles/git-config/</id><summary type="html">&lt;p class="first last"&gt;A guide to managing multiple Git configurations for different contexts (work, personal) using gitconfig&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;When working with Git across different contexts (personal projects, work repositories), it's crucial to maintain separate configurations to ensure commits are made with the correct identity and settings. This guide demonstrates how to set up and manage multiple Git configurations effectively.&lt;/p&gt;
&lt;object data="https://nunogrl.com/images/dotfiles/dotfiles.svg" style="width: 100%;" type="image/svg+xml"&gt;"My dotfiles"&lt;/object&gt;
&lt;div class="admonition warning"&gt;
&lt;p class="first admonition-title"&gt;Warning&lt;/p&gt;
&lt;p class="last"&gt;Using incorrect Git credentials can lead to commits being associated with the wrong identity,
which may expose personal email addresses in work repositories or vice versa.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="configuration-structure"&gt;
&lt;h2&gt;Configuration Structure&lt;/h2&gt;
&lt;div class="mermaid" id="mermaid-diagram-5689537300094488405"&gt;
flowchart TD
   A[~/.gitconfig] --&gt; B[~/.gitconfig-personal]
   A --&gt; C[~/.gitconfig-work]
   B --&gt; D[Personal Repos]
   C --&gt; E[Work Repos]&lt;/div&gt;&lt;/div&gt;
&lt;div class="section" id="primary-configuration"&gt;
&lt;h2&gt;Primary Configuration&lt;/h2&gt;
&lt;p&gt;The main &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.gitconfig&lt;/span&gt;&lt;/tt&gt; file serves as the entry point for Git's configuration:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;[includeIf &amp;quot;gitdir:~/src/*&amp;quot;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;~/.gitconfig-work&lt;/span&gt;

&lt;span class="k"&gt;[includeIf &amp;quot;gitdir:~/src/sandbox/*&amp;quot;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;~/.gitconfig-personal&lt;/span&gt;

&lt;span class="k"&gt;[includeIf &amp;quot;gitdir:~/Documents/*&amp;quot;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;~/.gitconfig-personal&lt;/span&gt;

&lt;span class="k"&gt;[includeIf &amp;quot;gitdir:~/src/&amp;quot;]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;~/Documents/git-work-precommit&lt;/span&gt;

&lt;span class="k"&gt;[commit]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;gpgsign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="k"&gt;[alias]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;lg1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;log &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--graph &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--abbrev-commit &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--decorate &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--format=format:&amp;#39;%C(bold blue)%h%C(reset) - &lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%C(bold green)(%ar)%C(reset) &lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%C(white)%s%C(reset) %C(dim white)- &lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%an%C(reset)%C(bold yellow)%d%C(reset)&amp;#39; &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--all&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;lg2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;log &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--graph &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--abbrev-commit &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--decorate &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--format=format:&amp;#39;%C(bold blue)%h%C(reset) - &lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%C(bold cyan)%aD%C(reset) &lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n&amp;#39;&amp;#39;&lt;/span&gt;\
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="s"&gt;%C(white)%s%C(reset) %C(dim white)- %an%C(reset)&amp;#39; &lt;/span&gt;\
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;--all&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;lg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;!&amp;quot;git lg1&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;diffc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;diff --color-words=.&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;meld&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;difftool --tool=meld -y&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;meldd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;difftool --dir-diff --tool=meld&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;meldbase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;!git meld $(git merge-base origin/master HEAD)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;review&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;!git fetch $1 $2 &amp;amp;&amp;amp; git checkout FETCH_HEAD &amp;amp;&amp;amp; git meldbase &amp;amp;&amp;amp; true&lt;/span&gt;

&lt;span class="k"&gt;[core]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;vim&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="personal-git-configuration"&gt;
&lt;h2&gt;Personal Git Configuration&lt;/h2&gt;
&lt;p&gt;Create &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.gitconfig-personal&lt;/span&gt;&lt;/tt&gt; for personal projects:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;[user]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;Nuno Leitao&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;example@example.com&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;signingkey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;1234ABCD&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="work-git-configuration"&gt;
&lt;h2&gt;Work Git Configuration&lt;/h2&gt;
&lt;p&gt;Create &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.gitconfig-work&lt;/span&gt;&lt;/tt&gt; for work-related projects:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;[user]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;Nuno Leitao&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;example@acme.com&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;signingkey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;1234ABCD&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="gpg-key-configuration"&gt;
&lt;h2&gt;GPG Key Configuration&lt;/h2&gt;
&lt;p&gt;The same GPG key can be used for both configurations:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt; $ &lt;/span&gt;gpg&lt;span class="w"&gt; &lt;/span&gt;-K
&lt;span class="go"&gt; /home/nuno/.gnupg/pubring.kbx&lt;/span&gt;
&lt;span class="go"&gt; -----------------------------&lt;/span&gt;
&lt;span class="go"&gt; sec   rsa4096 2018-05-09 [SC] [expires: 2022-05-09]&lt;/span&gt;
&lt;span class="hll"&gt;&lt;span class="go"&gt;       123456789ABCDEFG56780000123456781234ABCD&lt;/span&gt;
&lt;/span&gt;&lt;span class="go"&gt; uid           [ultimate] Nuno Leitao &amp;lt;example@example.com&amp;gt;&lt;/span&gt;
&lt;span class="go"&gt; uid           [ultimate] Nuno Leitao &amp;lt;example@acme.com&amp;gt;&lt;/span&gt;
&lt;span class="go"&gt; uid           [ultimate] [jpeg image of size 10099]&lt;/span&gt;
&lt;span class="go"&gt; ssb   rsa4096 2018-05-09 [E] [expires: 2022-05-09]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;The GPG key is associated with multiple email addresses, allowing it to sign
commits for both personal and work accounts.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="key-considerations"&gt;
&lt;h2&gt;Key Considerations&lt;/h2&gt;
&lt;div class="admonition tip"&gt;
&lt;p class="first admonition-title"&gt;Tip&lt;/p&gt;
&lt;ul class="last simple"&gt;
&lt;li&gt;Always verify the active Git configuration before starting work on a new repository&lt;/li&gt;
&lt;li&gt;Use &lt;tt class="docutils literal"&gt;git config &lt;span class="pre"&gt;--list&lt;/span&gt;&lt;/tt&gt; to check current settings&lt;/li&gt;
&lt;li&gt;Consider adding repository-specific configurations for special cases&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="common-issues"&gt;
&lt;h2&gt;Common Issues&lt;/h2&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;strong&gt;Wrong Email in Commits&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you notice commits with incorrect email:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;commit&lt;span class="w"&gt; &lt;/span&gt;--amend&lt;span class="w"&gt; &lt;/span&gt;--author&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Nuno Leitao &amp;lt;correct@email.com&amp;gt;&amp;quot;&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;push&lt;span class="w"&gt; &lt;/span&gt;--force&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Use with caution!&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;strong&gt;Verifying Configuration&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Check active configuration:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;--list&lt;span class="w"&gt; &lt;/span&gt;--show-origin
&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="further-reading"&gt;
&lt;h2&gt;Further Reading&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://git-scm.com/docs/git-config"&gt;Git Config Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://stackoverflow.com/questions/1057564/pretty-git-branch-graphs"&gt;Pretty Git Branch Graphs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://mikegerwitz.com/2012/05/a-git-horror-story-repository-integrity-with-signed-commits"&gt;A Git Horror Story: Repository Integrity with Signed Commits&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Shell Script &amp; Setup Symphony"></category><category term="dotfiles"></category><category term="git"></category><category term="configuration"></category><category term="security"></category></entry></feed>