Várias contas no Claude Code no mesmo Mac: CLAUDE_CONFIG_DIR é oficial — e o isolamento ainda vaza

Published on: 2026-08-29
Post image
pt claude-code anthropic claude-config-dir cli macos autenticacao multi-conta vscode terminal

Quem vive de cliente, empresa e projeto pessoal no mesmo Mac acaba pedindo a mesma coisa ao Claude Code: uma conta para o Paulo, outra para o trabalho, outra para o cliente A. Sem misturar histórico, plugin, fatura e — no limite — o contexto que o modelo lê. A solução que a internet inventou durante um tempo foi criar vários usuários do macOS. Não precisa. A própria Anthropic documenta o caminho oficial.

A variável é CLAUDE_CONFIG_DIR. Na página de environment variables, o texto é direto: ela troca o diretório de configuração (o padrão é ~/.claude), guarda settings, histórico de sessão e plugins nesse caminho, e é “useful for running multiple accounts side by side”. O exemplo oficial é este:

alias claude-work='CLAUDE_CONFIG_DIR=~/.claude-work claude'

Isso resolve o uso normal de 2, 5 ou 20 contas no terminal. Não resolve isolamento jurídico perfeito entre empresas. Existem bugs abertos no repositório oficial em que CLAUDE.md, o host da extensão do VS Code e alguns caminhos de configuração ainda encostam no ~/.claude default. Este artigo separa o que a documentação garante, o que você monta no zsh, e o que ainda vaza.

O que a Anthropic realmente move

Sem a variável, o Claude Code trata ~/.claude como casa. Settings do usuário, sessões, plugins, skills pessoais e o .claude.json (login, MCP, trust de projeto, chaves que o /config grava) moram ali. A documentação de settings diz a mesma coisa com outras palavras: se você setar CLAUDE_CONFIG_DIR, settings, session history e plugins passam a viver nesse diretório.

Credencial é o ponto em que o macOS diverge do resto:

  • Linux e Windows: o arquivo .credentials.json (modo 0600 no Linux) vai para dentro do CLAUDE_CONFIG_DIR. Sem a variável, fica em ~/.claude/.credentials.json.
  • macOS: a documentação de autenticação diz que as credenciais ficam no Keychain criptografado do sistema. Mesmo assim a Anthropic afirma que a variável existe para rodar várias contas lado a lado. Em versões recentes do CLI, o Keychain passou a namespacing por diretório (hash do path). Não assuma que “Keychain = uma conta só para sempre” — e também não assuma isolamento perfeito só porque o Keychain é da Apple.

A variável precisa estar no ambiente que sobe o claude. A Anthropic tirou do env do .claude/settings.json do projeto a capacidade de setar CLAUDE_CONFIG_DIR. Changelog oficial: isso agora mora no shell, no setting de usuário ou no managed setting. Quem pôs a variável só no settings.json do repositório e achou que a conta mudou está olhando o lugar errado.

O que não muda com a variável: o .claude/ do repositório. Settings de time, hooks do projeto, CLAUDE.md da pasta. Isolar conta não isola o Git. Se você abre o repo do cliente com a conta pessoal, o projeto continua mandando instrução. Conta é identidade. Repo é política.

Login oficial: /login e claude auth

Há dois jeitos oficiais de autenticar, e os dois valem.

Dentro da sessão interativa, /login e /logout são o fluxo clássico. A documentação de autenticação descreve o browser, o código que você cola no terminal (WSL2, SSH, container) e o /status para ver método, organização e e-mail. Logout também zera o estado de first-launch: a próxima subida pede login de novo.

No CLI, a referência oficial lista três subcomandos:

claude auth login
claude auth logout
claude auth status

claude auth login entra na conta Anthropic. Aceita --email para pré-preencher, --sso para forçar SSO e --console para faturar via Claude Console em vez da assinatura. claude auth status imprime JSON; --text deixa legível. Exit 0 se estiver logado, 1 se não. Use isso num script de “estou na conta certa?” antes de mandar o agente no repo do cliente.

Precedência importa. Se ANTHROPIC_API_KEY estiver no ambiente e você aprovou a chave, ela ganha da assinatura do /login. Dá para achar que trocou de conta pelo CLAUDE_CONFIG_DIR e continuar pagando (ou vazando) pela key antiga. /status mostra a linha API key quando isso acontece. unset ANTHROPIC_API_KEY devolve a sessão para o OAuth daquele diretório.

O mínimo que funciona: um alias por conta

O exemplo da documentação escala sem drama. No ~/.zshrc:

alias claude1='CLAUDE_CONFIG_DIR=$HOME/.claude-account-1 claude'
alias claude2='CLAUDE_CONFIG_DIR=$HOME/.claude-account-2 claude'
alias claude3='CLAUDE_CONFIG_DIR=$HOME/.claude-account-3 claude'

Autentica cada uma com a variável já setada. Sem isso, o login cai no ~/.claude default e você acha que isolou:

CLAUDE_CONFIG_DIR="$HOME/.claude-account-1" claude auth login
CLAUDE_CONFIG_DIR="$HOME/.claude-account-2" claude auth login
CLAUDE_CONFIG_DIR="$HOME/.claude-account-3" claude auth login

Primeira subida de cada alias abre o browser. Daí para frente, claude2 sobe com settings, sessões e plugins da pasta 2. Não copie ~/.claude para a pasta nova: você copia credencial, histórico e plugin que não revisou. Comece vazio. Deixe o login oficial criar o que precisa.

Isso é suficiente para duas ou três contas. Em cinco, dez, vinte, alias vira lista. Aí vale uma função.

O esquema que escala: claude-account paulo

Uma função, um diretório-raiz, um nome por conta:

claude-account() {
    local account="$1"
    shift

    if [[ -z "$account" ]]; then
        echo "uso: claude-account <conta> [args do claude]" >&2
        return 2
    fi

    CLAUDE_CONFIG_DIR="$HOME/.claude-accounts/$account" \
        command claude "$@"
}

command claude evita recursão se você mais tarde encapsular o próprio claude. O shift deixa passar qualquer subcomando:

claude-account paulo
claude-account trabalho
claude-account cliente1

claude-account paulo auth login
claude-account trabalho auth login
claude-account cliente1 auth login

claude-account paulo auth status --text

Na primeira vez, o diretório pode não existir. O CLI cria. Se quiser ser explícito:

mkdir -p "$HOME/.claude-accounts/paulo"
mkdir -p "$HOME/.claude-accounts/trabalho"
mkdir -p "$HOME/.claude-accounts/cliente1"

Permissão: 0700 no raiz ~/.claude-accounts e nas pastas. É o mesmo princípio do 0600 do .credentials.json no Linux — outro usuário da máquina não precisa ler sessão de cliente.

O atalho que você realmente quer: claude paulo

Dá para ir um passo além e não escrever CLAUDE_CONFIG_DIR nem claude-account. Se o primeiro argumento for o nome de uma pasta em ~/.claude-accounts, a função usa essa conta. Qualquer outra coisa — flag, auth, caminho — cai no claude default.

# ~/.zshrc
claude() {
    local accounts="$HOME/.claude-accounts"
    local bin
    bin="$(whence -p claude)" || bin="claude"

    if [[ $# -ge 1 && "$1" != -* && -d "$accounts/$1" ]]; then
        local account="$1"
        shift
        CLAUDE_CONFIG_DIR="$accounts/$account" "$bin" "$@"
        return
    fi

    "$bin" "$@"
}

Uso:

claude paulo
claude empresa
claude cliente1
claude cliente1 auth login
claude cliente1 auth status --text

# conta default (~/.claude), sem nome:
claude
claude auth status --text

Regra que evita tiro no pé: não dê à conta o nome de um subcomando ou de uma pasta do projeto. Se existir ~/.claude-accounts/auth, claude auth status vira “suba a conta auth”. Nomes de pessoa, empresa e cliente não colidem com auth, --resume, mcp. O teste -d "$accounts/$1" só dispara quando a pasta já existe, então a primeira autenticação ainda precisa de mkdir ou da função claude-account.

Quem quiser o default também nomeado: crie ~/.claude-accounts/paulo e esqueça o ~/.claude para trabalho diário. Deixe o diretório antigo só como legado.

O que ainda vaza — e por isso não é isolamento de compliance

O que CLAUDE_CONFIG_DIR isola de verdade (settings, sessões, plugins) e o que ainda pode vazar (CLAUDE.md ancestral e extensão do VS Code)

A documentação vende o recurso para várias contas. O tracker oficial mostra onde a parede é mais baixa.

CLAUDE.md ancestral. Issues como a #80580 e a #58815 descrevem o mesmo gosto: você sobe com CLAUDE_CONFIG_DIR=~/.claude-personal e o modelo ainda lê instrução que só existe em ~/.claude/CLAUDE.md. Parte disso é lookup de memória de usuário que, em algumas versões, ficou hardcoded no path default. Outra parte é o discovery de pasta-pai: o Claude Code carrega CLAUDE.md / .claude/CLAUDE.md em cada diretório acima do cwd. Se o projeto mora em ~/cliente/app, ~/.claude/CLAUDE.md casa com o padrão ancestral <home>/.claude/CLAUDE.md — independente do profile. A própria discussão da issue confirma: projeto fora do home não puxa esse arquivo; projeto dentro do home puxa. Não é sofisma. É o loader de memória fazendo o trabalho dele, em cima da pasta errada para quem queria duas vidas no mesmo $HOME.

VS Code / Cursor. A extensão oficial não trata CLAUDE_CONFIG_DIR como o CLI. Issues como a #30538 e a #34888 repetem o diagnóstico: claudeCode.environmentVariables chega no processo spawnado do CLI, não no extension host. O agente pode autenticar na conta certa. O host continua listando sessão, plugin, MCP e às vezes auth em ~/.claude. Resultado clássico: picker de histórico vazio ou cheio da conta errada; login do sidebar diferente do claude auth status do terminal. Workaround honesto hoje: trabalhar a conta multi-profile no terminal (incluindo “Open in Terminal” da extensão), ou lançar o editor já com a variável no ambiente do processo pai. Não confie no setting de workspace sozinho.

Keychain no Mac. A #20553 documentou um período em que todas as contas compartilhavam o mesmo serviço Claude Code-credentials. O namespacing por hash do path chegou em versões 2.1.x. Relatos seguintes falam de ACL do Keychain que, depois do reboot, só o binário da Apple lia — e o CLI pedia /login de novo. Se você autentica de manhã e à tarde a conta “some”, olhe o Keychain e a versão do CLI antes de culpar o alias.

Traduzindo sem marketing:

  • Várias contas no terminal: oficialmente suportado.
  • Settings, sessões e plugins separados por diretório: é a finalidade do CLAUDE_CONFIG_DIR.
  • Isolamento absoluto entre empresas/clientes (memória, IDE, credencial em todo reboot): ainda há bugs conhecidos.

Para uso diário — não misturar Max pessoal com Team da empresa, não retomar o chat do cliente no sábado — a variável basta. Para contrato que proíbe dado da empresa A no contexto da empresa B, você ainda precisa de disciplina extra: projetos fora de $HOME se o ~/.claude/CLAUDE.md default existir, não reutilizar plugin sem revisar, não colar token de um lado no MCP do outro, e tratar o VS Code como superfície à parte até o host honrar a variável.

Não crie cinco usuários no macOS

Usuário de sistema isola de verdade: home, Keychain, ~/.claude, extensão, tudo. Também isola Safari, SSH, 1Password e a vontade de viver. Para 5, 10 ou 20 contas do Claude Code, o custo operacional é desproporcional. Comece por CLAUDE_CONFIG_DIR. Reserve Fast User Switching para o caso em que o cliente exige máquina (ou pelo menos home) separada, não para o freelancer que tem três CNPJs e um teclado.

Se a conta é Team/Enterprise com forceLoginOrgUUID, a organização já trava o login em um UUID. Isso não substitui diretórios separados: trava para qual org aquele binário pode autenticar, não onde a sessão pessoal grava histórico.

Checklist para não se enganar

1. Crie pastas vazias em ~/.claude-accounts/<nome>. Não clone ~/.claude.

2. Autentique com a variável ligada. claude-account trabalho auth login ou o equivalente. Confira com auth status --text e, dentro da sessão, /status.

3. Tire ANTHROPIC_API_KEY do perfil se a idéia é viver de assinatura por conta. Key no ambiente fura o isolamento do diretório.

4. Decida o default. Ou você continua com claude~/.claude, ou move o dia a dia para claude paulo e deixa o default só para emergência.

5. Trate o repo como zona compartilhada. CLAUDE.md e settings do projeto valem para qualquer conta que abrir aquela pasta. Isso é feature para o time, não bug.

6. Se o projeto vive sob o home e você tem um ~/.claude/CLAUDE.md gordo da conta antiga, saiba que ele pode entrar como ancestral. Mova memória global para dentro de cada CLAUDE_CONFIG_DIR, ou trabalhe o cliente fora de $HOME.

7. Multi-conta séria no editor: terminal, não só o painel da extensão, até o host passar a ler a variável.

Eu já percorri o resto da ferramenta — skills, hooks, MCP, plugins — no curso de Claude Code. Conta é a camada de baixo: se ela estiver errada, o resto do harness trabalha para o CNPJ errado.

Para levar

CLAUDE_CONFIG_DIR é o jeito oficial de ter várias contas Claude Code no mesmo usuário. A Anthropic escreveu isso na referência de variáveis, com o alias claude-work de exemplo. Settings, sessões e plugins acompanham o diretório. No Mac, a credencial vai para o Keychain; no Linux e no Windows, para o .credentials.json da pasta. claude auth login, logout e status são comandos oficiais do CLI.

O wrapper claude paulo / claude empresa / claude cliente1 é só açúcar em volta dessa variável. Não inventa protocolo. Não copia token. Não precisa de usuário extra no macOS.

O que a documentação ainda não pode prometer é parede cega. CLAUDE.md ancestral, host do VS Code e arestas de Keychain são bugs reais, não lenda de forum. Use o recurso. Confira auth status toda vez que a fatura ou o cliente mudar. E não chame isso de isolamento forense enquanto o loader de memória ainda souber o caminho da casa antiga.

Referências

  • Anthropic — Environment variables (CLAUDE_CONFIG_DIR, exemplo claude-work, “multiple accounts side by side”)
  • Anthropic — Claude Code settings
  • Anthropic — Authentication (Keychain no macOS, .credentials.json no Linux/Windows, /login, precedência)
  • Anthropic — CLI reference (claude auth login, logout, status)
  • Anthropic — Manage sessions
  • Anthropic — Use Claude Code in VS Code
  • GitHub anthropics/claude-code — #80580 (discovery de CLAUDE.md ancestral)
  • GitHub anthropics/claude-code — #58815 (User Memory em ~/.claude/CLAUDE.md)
  • GitHub anthropics/claude-code — #30538 (extensão VS Code ignora a variável no host)
  • GitHub anthropics/claude-code — #20553 (Keychain compartilhado / namespacing)