Using a personal and a work GitHub account side by side
A new job arrives with a company GitHub account, and the Mac that already holds a personal one now has to serve both. The first day goes fine. The trouble starts a week later: a commit lands under the wrong email, a push to a company repository is rejected because the cached credential belongs to the other account, and a pull request review link opened from Slack shows a 404 because the browser was signed in as the wrong person. None of these are hard problems individually. Together they eat an afternoon a month.
The split has to hold in three separate places, and most guides only cover one of them.
What GitHub's terms actually allow
This is worth settling before building anything, because the rest of the setup depends on it. GitHub's Terms of Service state that one person or legal entity may maintain no more than one free Account, with an explicit carve-out that controlling a machine account as well is fine, as long as that account is only used for running a machine.
In practice this pushes toward one of two arrangements. The first is a single personal account that joins the employer's organization, which is the arrangement GitHub's own documentation treats as normal: the account is the person, the organization membership is the job, and leaving the company removes the membership rather than the account. The second is two accounts where at least one sits on a paid plan, which is common when an employer provisions a managed user account through Enterprise Managed Users.
Anyone who has already created a second free account has a documented exit. GitHub provides a path for merging multiple personal accounts, which transfers repositories and then deletes the account that is no longer wanted. Contributions made under the deleted account do not follow it, which is the main reason people hesitate. That trade-off is easier to weigh before years of history accumulate than after.
Three layers that each need their own answer
The phrase "signed in to GitHub" hides three independent sessions, and a setup that only fixes one keeps failing in the other two.
The first is the web session in the browser. This is what decides which account sees a repository, approves a pull request, or installs an app. The second is the Git credential used when pushing from a terminal, which is a token or an SSH key and has no connection to the browser session at all. The third is the commit identity, the name and email recorded in each commit, which is just configuration text and is happily wrong without any error message until a commit shows up attributed to the wrong person.
Debugging gets much faster once these are treated as three separate switches rather than one.
The Git credential layer
GitHub's documentation on managing multiple accounts describes three supported routes, and the right one depends on how the repositories are already cloned.
| Route | How it separates accounts | Best for |
|---|---|---|
| HTTPS with per-repository tokens | Credential helper caches a token per full remote URL | Machines already using HTTPS remotes |
SSH with GIT_SSH_COMMAND |
A specific key is named on each command or per repository | Occasional access to a second account |
| SSH with multiple keys and host aliases | Each account gets its own key and its own SSH host entry | A permanent two-account setup |
The HTTPS route hinges on one setting that is easy to miss. By default a credential helper stores one credential for github.com, which is exactly why the second account fails. Telling Git to key credentials by the full path makes per-repository tokens possible.
git config --global credential.https://github.com.useHttpPath true
Before that takes effect, the existing cached credential has to be cleared, and on macOS that means the keychain helper rather than the keychain app. GitHub documents git credential-osxkeychain erase for this, reading host=github.com and protocol=https from standard input. After that, each account gets its own personal access token, either a classic token with repository scope or a fine-grained token limited to the repositories it should reach, and Git caches them separately.
The SSH route avoids tokens entirely. Each account gets its own key pair, and an entry in the SSH config gives the second account a host alias so that remotes point at the alias instead of github.com. Cloning with that alias means the right key is offered automatically, with nothing to remember at push time.
Commit identity, and the commits that arrive under the wrong name
Credentials decide whether a push is allowed. The commit email decides whose face appears next to the commit afterwards, and the two are configured in completely different places.
Git's conditional includes solve this cleanly. A includeIf block in the global configuration loads a different configuration file depending on the directory a repository sits in, which means a repository under a work directory picks up the work email and everything else picks up the personal one.
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work
This only works if the directory layout is disciplined enough to carry the meaning, which is the real reason to keep work repositories under a single parent directory rather than scattered across the desktop. It is also worth turning on the GitHub setting that blocks command line pushes exposing a personal email address, since that turns a silent mistake into a rejected push.
For anyone who lives in the GitHub CLI, gh auth status lists the authenticated accounts and gh auth switch changes the active one, prompting when more than two exist. That covers scripted work, but note that it switches the CLI only. The browser and the Git credential cache are untouched by it, which brings the third layer into view.
The browser half that nobody configures
GitHub does support holding several web sessions at once. The account switcher lets a person sign in to more than one account and move between them without reauthenticating each time, and it is designed for the personal-plus-machine-account and personal-plus-managed-user cases.
Two details in GitHub's documentation matter for daily use. Those sessions live on one computer and one browser, so a second machine starts from nothing. And when several accounts are signed in and a link to GitHub is followed from an external source, such as a request to install or approve a GitHub App, GitHub first asks which account should be used. That prompt is the polite version of the problem; the impolite version is a private repository link from a colleague returning a 404 because the current session belongs to the other account.
The structural fix is to stop sharing one cookie jar. A browser profile per account gives each session its own cookies, and so does a macOS app that keeps each web app in its own container, with workspaces grouping everything that belongs to one context. Under that arrangement the company GitHub, the company issue tracker and the company mail live in one space while the personal ones live in another, and a link opened inside a space resolves against the session that space owns. Signing out is never part of the routine.
Where the terminal sits
Developers hit one more seam. The repository being reviewed in the browser is usually the repository checked out in a terminal, and moving between them means moving between two applications with different notions of which account is current. Keeping a shell beside the app, which is what the built-in terminal in this category of browser provides, at least removes the window hunt, though the credential configuration described above is still what makes the push land correctly.
The tools that quietly hold a fourth login
Beyond the browser, the credential cache and the commit identity, a working Mac usually carries a few more places where a GitHub session is stored, and each of them can drift out of step with the rest.
Editors are the most common. An editor signed in to GitHub for extension sync, pull request review or an AI assistant holds its own token, granted once and then forgotten. When that token belongs to the personal account and the repository open in the window belongs to the employer, the review panel shows nothing and the cause is invisible from inside the editor. The fix is to check the editor's account settings whenever the credential layer changes, not months later.
Container and virtual machine setups are the second. A development container mounts the host SSH agent or copies a credential in at build time, which means it inherits whichever identity was current when it was created. Rebuilding after a credential change is often faster than diagnosing why a push from inside the container behaves differently from the same push on the host.
Third-party services that authenticate through GitHub are the third. Continuous integration providers, deployment platforms and package registries each store an authorization granted by a specific account. If that account later loses access to the organization, the integration stops working for reasons that have nothing to do with the repository itself. Listing those authorizations once, in the applications section of each account's settings, makes the dependency visible before it breaks a deploy.
The pattern across all three is the same: an account grant made in passing, stored somewhere that is not consulted during everyday work, and surfacing only as a confusing failure. Any setup that separates accounts cleanly still needs a short inventory of where each login lives.
A layout that holds up after six months
Directory structure first. One parent directory for work repositories, one for personal, with conditional includes keyed to those paths. Anything that lands outside them inherits the personal identity, which is the safer default.
Naming second. If the SSH host alias, the directory name, the browser space and the GitHub organization all use the same word for the same client or employer, then a glance confirms context before a command is typed. Mixed vocabulary is what turns a fast check into a slow one.
Verification third. Three checks answer the question of which account is active in each layer: git config user.email for the commit identity, ssh -T [email protected] or gh auth status for the credential, and the avatar in the top right for the browser. Running the first two inside a fresh clone is the cheapest way to catch a misconfigured conditional include before it writes history.
Cleanup last. When a contract ends or a job changes, remove the organization membership, delete the SSH key from the account that no longer needs it, revoke the token, and remove the account from the switcher. Stale access is the one part of this setup that gets worse with time rather than better.
What to change first
Check which of the three layers is actually causing the pain. If commits are landing under the wrong email, conditional includes fix it in ten minutes. If pushes are rejected, the credential cache is the culprit. If links keep opening as the wrong person, the browser session is the problem, and giving each account its own permanently signed-in container, the approach SpaceDeck is built around, removes the sign-out cycle for good.
Frequently asked questions
Is having two GitHub accounts against the rules?
GitHub's Terms of Service say one person or legal entity may maintain no more than one free Account, with an exception for a machine account used only to run a machine. A paid account alongside a free one, or a managed user account provisioned by an employer, is a different situation. The arrangement GitHub's documentation treats as standard is one personal account that joins the employer's organization.
Why does Git keep pushing with the wrong account after signing out in the browser?
Because the browser session and the Git credential are unrelated. Git uses a cached token or an SSH key from the credential helper, and signing out of github.com in a browser does not clear either. Clearing the cached credential and configuring Git to store credentials per repository path, or using a separate SSH key per account, is what actually changes which account a push uses.
How can commits be kept under the right email automatically?
Use Git's conditional includes to load a different configuration file for repositories under a given directory, so work repositories get the work email and everything else gets the personal one. Pair it with GitHub's setting that blocks command line pushes which expose a personal email address, so a misconfiguration is rejected at push time rather than discovered in the commit history later.
Does the GitHub account switcher work across two computers?
No. GitHub documents that the accounts added to the switcher remain on the computer and browser where they were added, so another machine or another browser starts with nothing. Each device needs its own sign-in, which is one reason people prefer a per-account container arrangement that can be reproduced quickly on a new machine.
Is a separate browser profile enough for two GitHub accounts?
For two accounts it usually is, since profiles keep cookies fully separate. The friction shows up when each account brings its own mail, issue tracker and chat, because those all need the same separation and each profile is a separate window with a near-identical icon. At that point grouping the apps of one context into a single isolated space is less work to operate than four lookalike windows.