<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Zhao Liu</title>
    <description>The latest articles on DEV Community by Zhao Liu (@liuzhao1225).</description>
    <link>https://dev.to/liuzhao1225</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4094981%2F06dafe6e-ec97-457c-8e29-d26c8390ab28.png</url>
      <title>DEV Community: Zhao Liu</title>
      <link>https://dev.to/liuzhao1225</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/liuzhao1225"/>
    <language>en</language>
    <item>
      <title>How I built a native macOS Codex account switcher without a proxy</title>
      <dc:creator>Zhao Liu</dc:creator>
      <pubDate>Wed, 26 Aug 2026 03:55:24 +0000</pubDate>
      <link>https://dev.to/liuzhao1225/how-i-built-a-native-macos-codex-account-switcher-without-a-proxy-3m09</link>
      <guid>https://dev.to/liuzhao1225/how-i-built-a-native-macos-codex-account-switcher-without-a-proxy-3m09</guid>
      <description>&lt;p&gt;I use separate Codex accounts for personal work, company work, and client repositories. The recurring problem was simple: before opening a repository, I needed to know which account Codex Desktop was using and how much weekly usage that account had left.&lt;/p&gt;

&lt;p&gt;OpenAI provides account switching for ChatGPT on the web, while its current documentation says the feature is not yet supported in Codex desktop. I built &lt;strong&gt;Codex Account Switcher&lt;/strong&gt;, an open-source native macOS menu-bar app, to make that local desktop workflow explicit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fozxsshj8b34v8x19paem.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fozxsshj8b34v8x19paem.png" alt="Codex Account Switcher showing local profiles and weekly usage" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the app does
&lt;/h2&gt;

&lt;p&gt;The app keeps a small library of authorized local Codex profiles. From the menu bar, I can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;identify the active personal, work, or client profile;&lt;/li&gt;
&lt;li&gt;compare weekly usage and reset times;&lt;/li&gt;
&lt;li&gt;select a different profile and confirm the switch;&lt;/li&gt;
&lt;li&gt;reopen Codex Desktop with the selected authentication;&lt;/li&gt;
&lt;li&gt;start a new Codex CLI process that uses the same selected profile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The current release is free, MIT-licensed, and built for Apple Silicon Macs running macOS 14 or later.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture stays local
&lt;/h2&gt;

&lt;p&gt;Codex reads file-based authentication from the active &lt;code&gt;CODEX_HOME&lt;/code&gt;. OpenAI's public Codex source shows the file backend reading and writing &lt;code&gt;auth.json&lt;/code&gt; beneath that directory and applying user-only file permissions on Unix systems.&lt;/p&gt;

&lt;p&gt;The switcher stores each saved identity in an independent profile directory. A confirmed switch follows a short sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Save the current profile's latest credentials.&lt;/li&gt;
&lt;li&gt;Activate the selected profile.&lt;/li&gt;
&lt;li&gt;Verify the selected identity.&lt;/li&gt;
&lt;li&gt;Reopen Codex Desktop.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Existing CLI processes keep the state they already loaded. A newly started CLI process reads the selected authentication.&lt;/p&gt;

&lt;p&gt;There is no model-traffic proxy, cloud credential sync, automatic account rotation, account sharing, or usage-limit bypass. The app only manages local profiles for accounts the user owns or is authorized to access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I avoided a background routing service
&lt;/h2&gt;

&lt;p&gt;A proxy would add another trust boundary around credentials and model traffic. It would also make a straightforward local state transition much harder to inspect.&lt;/p&gt;

&lt;p&gt;The native implementation is deliberately small: SwiftUI for the interface, local profile directories for storage, and one visible confirmation before changing the active profile. The source is public, including the account store, switch service, tests, packaging scripts, and system design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shipping a DMG other Mac users can open
&lt;/h2&gt;

&lt;p&gt;The packaging work took longer than the account switch itself. The public v0.1.4 release now has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a native application and Finder icon;&lt;/li&gt;
&lt;li&gt;Developer ID signing for the app;&lt;/li&gt;
&lt;li&gt;Apple notarization and stapling before DMG creation;&lt;/li&gt;
&lt;li&gt;Developer ID signing, notarization, and stapling for the DMG;&lt;/li&gt;
&lt;li&gt;a SHA-256 checksum next to the download.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gives users the normal macOS installation flow: download the DMG, drag the app to Applications, and open it without disabling Gatekeeper.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;The most important product decision was to keep the active identity visible before the user opens the next repository. Speed matters, but avoiding work in the wrong personal, company, or client context matters more.&lt;/p&gt;

&lt;p&gt;The second lesson was that profile switching and session switching are different. Replacing a file on disk does not retroactively change authentication already loaded by a running process. The UI and documentation now state that existing CLI processes keep their state and new processes use the selected profile.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it or inspect the source
&lt;/h2&gt;

&lt;p&gt;I am Zhao Liu, GitHub username &lt;strong&gt;liuzhao1225&lt;/strong&gt;, and I created and maintain this project.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Official repository:&lt;/strong&gt; &lt;a href="https://github.com/liuzhao1225/codex-account-switcher" rel="noopener noreferrer"&gt;liuzhao1225/codex-account-switcher&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signed macOS release:&lt;/strong&gt; &lt;a href="https://github.com/liuzhao1225/codex-account-switcher/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verified project facts and primary sources:&lt;/strong&gt; &lt;a href="https://liuzhao1225.github.io/codex-account-switcher/about/" rel="noopener noreferrer"&gt;Official project identity&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source-backed guide:&lt;/strong&gt; &lt;a href="https://liuzhao1225.github.io/codex-account-switcher/guides/codex-account/" rel="noopener noreferrer"&gt;What is a Codex account?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI account-switching support boundary:&lt;/strong&gt; &lt;a href="https://help.openai.com/en/articles/20001068-use-multiple-accounts-with-account-switching" rel="noopener noreferrer"&gt;OpenAI Help Center&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upstream auth storage source:&lt;/strong&gt; &lt;a href="https://github.com/openai/codex/blob/main/codex-rs/login/src/auth/storage.rs" rel="noopener noreferrer"&gt;openai/codex auth storage&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feedback on the profile model, usage display, and Desktop/CLI handoff is welcome. Please keep real &lt;code&gt;auth.json&lt;/code&gt; files, tokens, email addresses, and private screenshots out of public issues.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>swift</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
