<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>thde.io</title>
    <link rel="self" type="application/atom+xml" href="https://thde.io/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://thde.io"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-11-02T00:00:00+00:00</updated>
    <id>https://thde.io/atom.xml</id>
    <entry xml:lang="en">
        <title>git-credential-oauth: OAuth for Git</title>
        <published>2026-11-02T00:00:00+00:00</published>
        <updated>2026-11-02T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://thde.io/blog/git-credential-oauth/"/>
        <id>https://thde.io/blog/git-credential-oauth/</id>
        
        <content type="html" xml:base="https://thde.io/blog/git-credential-oauth/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/hickford/git-credential-oauth&quot;&gt;git-credential-oauth&lt;/a&gt; is a Git credential helper that authenticates to GitHub, GitLab, Bitbucket, and other forges using OAuth. On your first push or pull, it opens a browser tab to authenticate, then a storage helper caches the token for subsequent commands, so you don’t need to create, rotate, or paste personal access tokens.&lt;/p&gt;
&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;brew&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; install&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; git-credential-oauth&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;configuration&quot;&gt;Configuration&lt;/h2&gt;
&lt;p&gt;Git supports chaining credential helpers, evaluating them in order until one provides valid credentials. In this setup, &lt;code&gt;git-credential-oauth&lt;/code&gt; acquires OAuth tokens, while a storage helper like &lt;code&gt;osxkeychain&lt;/code&gt; caches them locally.&lt;/p&gt;
&lt;p&gt;The order matters: the storage helper must come first so Git checks stored credentials before starting a new OAuth flow. On macOS, Homebrew’s Git already configures &lt;code&gt;osxkeychain&lt;/code&gt; in its system config (&lt;code&gt;/opt/homebrew/etc/gitconfig&lt;/code&gt;), and Git reads the system config before &lt;code&gt;~/.gitconfig&lt;/code&gt;. So adding &lt;code&gt;oauth&lt;/code&gt; to your global config is enough:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; config&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-global&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-add&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; credential.helper&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; oauth&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Verify the order with:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; config&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-show-scope&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-get-all&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; credential.helper&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;system  osxkeychain&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;global  oauth&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If &lt;code&gt;osxkeychain&lt;/code&gt; is missing, add it to &lt;code&gt;~/.gitconfig&lt;/code&gt; before &lt;code&gt;oauth&lt;/code&gt;. On Linux, use &lt;a rel=&quot;external&quot; href=&quot;https://git-scm.com/docs/git-credential-cache&quot;&gt;&lt;code&gt;cache&lt;/code&gt;&lt;/a&gt; or &lt;code&gt;libsecret&lt;/code&gt; as the storage helper.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://thde.io/blog/git-credential-oauth/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&quot;https-remotes&quot;&gt;HTTPS remotes&lt;/h2&gt;
&lt;p&gt;Credential helpers only apply to HTTPS. Remotes cloned over SSH (&lt;code&gt;git@github.com:…&lt;/code&gt;) keep using SSH keys. To switch an existing repository:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; remote&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; set-url&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; origin&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; https://github.com/OWNER/REPO.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or rewrite all GitHub SSH URLs to HTTPS globally:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;git&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; config&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-8&quot;&gt;-global&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; url.&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;https://github.com/&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;.insteadOf&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; git@github.com:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/hickford/git-credential-oauth&quot;&gt;git-credential-oauth README&lt;/a&gt; &lt;a href=&quot;https://thde.io/blog/git-credential-oauth/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Secure Enclave SSH Keys on macOS 26</title>
        <published>2026-06-12T00:00:00+00:00</published>
        <updated>2026-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://thde.io/blog/secure-enclave-ssh/"/>
        <id>https://thde.io/blog/secure-enclave-ssh/</id>
        
        <content type="html" xml:base="https://thde.io/blog/secure-enclave-ssh/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/maxgoedjen/secretive&quot;&gt;Secretive&lt;/a&gt; was long the standard tool for generating and storing SSH keys in the Secure Enclave, keeping the private key isolated on hardware and requiring Touch ID for each signing operation. In macOS 26, this capability is built directly into the operating system through &lt;code&gt;sc_auth&lt;/code&gt; and &lt;code&gt;/usr/lib/ssh-keychain.dylib&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For detailed setup instructions, see &lt;a rel=&quot;external&quot; href=&quot;https://algustionesa.com/native-secure-enclave-ssh-keys-the-macos-guide/&quot;&gt;Native Secure Enclave SSH Keys (the macOS guide)&lt;/a&gt; or this &lt;a rel=&quot;external&quot; href=&quot;https://gist.github.com/arianvp/5f59f1783e3eaf1a2d4cd8e952bb4acf&quot;&gt;quick gist&lt;/a&gt;. Apple also details the underlying CryptoTokenKit APIs in &lt;a rel=&quot;external&quot; href=&quot;https://developer.apple.com/documentation/security/protecting-keys-with-the-secure-enclave&quot;&gt;Protecting keys with the Secure Enclave&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Enable Touch ID for sudo on macOS</title>
        <published>2026-06-07T00:00:00+00:00</published>
        <updated>2026-06-07T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://thde.io/blog/touchid-sudo/"/>
        <id>https://thde.io/blog/touchid-sudo/</id>
        
        <content type="html" xml:base="https://thde.io/blog/touchid-sudo/">&lt;p&gt;Starting in macOS Sonoma, Apple introduced &lt;code&gt;/etc/pam.d/sudo_local&lt;/code&gt;, allowing Touch ID configuration for &lt;code&gt;sudo&lt;/code&gt; to persist across operating system updates.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://thde.io/blog/touchid-sudo/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;To enable it, generate the configuration file from Apple’s template:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt;sed&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;s/^#auth/auth/&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /etc/pam.d/sudo_local.template&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-5&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-1&quot;&gt; sudo&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; tee&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-2&quot;&gt; /etc/pam.d/sudo_local&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates &lt;code&gt;/etc/pam.d/sudo_local&lt;/code&gt; with &lt;code&gt;pam_tid.so&lt;/code&gt; enabled:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sudo_local: local config file which survives system update and is included for sudo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# uncomment following line to enable Touch ID for sudo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;auth       sufficient     pam_tid.so&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Open a new terminal session to test it. Running &lt;code&gt;sudo&lt;/code&gt; will now prompt for fingerprint authentication before falling back to a password prompt.&lt;/p&gt;
&lt;img src=&quot;touchid-sudo.png&quot; alt=&quot;Touch ID sudo prompt&quot; width=&quot;320&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://support.apple.com/kb/HT213893&quot;&gt;Apple Support HT213893&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://apple.stackexchange.com/a/466029&quot;&gt;Stack Exchange&lt;/a&gt; &lt;a href=&quot;https://thde.io/blog/touchid-sudo/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
    </entry>
</feed>
