Ik werk sinds maart voor een opdrachtgever met een eigen Claude-abonnement, terwijl mijn eigen abonnement op dezelfde Mac staat. Een half jaar lang deed ik het domme ding: uitloggen, inloggen, en aan het eind van de dag weer terug.
Dat kost elke keer de volledige browserflow met e-mailverificatie. En het is niet nodig.
Wat ik eerst probeerde, en waarom dat fout was
Claude Code kent claude setup-token. Dat levert een OAuth-token dat een jaar geldig is, bedoeld voor CI-pipelines waar geen browser is. Dat leek me de nette route: token in een bestand, variabele zetten, klaar.
Het werkte niet, en het werkte op een manier die me een uur kostte om te begrijpen.
De auth-volgorde van Claude Code is de sleutel. CLAUDE_CODE_OAUTH_TOKEN staat op plek 5 en de credential van /login op plek 7. De beperktere credential wint dus van de volledige. Staat er een onbruikbare token in je omgeving, dan wordt die eerst gepresenteerd.
Hij faalt. En jij krijgt de hele inlogflow voor je kiezen, terwijl er een prima login klaarstond.
Er zit nog een grens aan zo'n token. De documentatie zegt dat hij alleen modelaanvragen kan doen, dus geen Remote Control-sessies en geen claude.ai-connectors. Voor een headless worker maakt dat niets uit. Voor de sessie waar je zelf in zit wel.
Wat wel werkt
Eén variabele, en één keer inloggen:
mkdir -p ~/.claude-werk
CLAUDE_CONFIG_DIR=~/.claude-werk claude
# /login met je werk-account, één keer de flow doorDaarna is het klaar. Die login blijft staan, en je eigen login blijft er los naast.
Waarom ik dit zelf niet geloofde
De documentatie zei eind augustus iets anders. Over opslag van credentials stond er dat ze op macOS in de keychain zitten, en dat de verplaatsing naar je config-map gold "on Linux or Windows". Daaruit las ik dat macOS één gedeelde login heeft. Twee accounts naast elkaar zouden dus niet kunnen.
Dat klopt niet. De keychain wordt wel degelijk per config-map gescheiden. Toen stond dat nergens beschreven. Inmiddels staat het wel in de documentatie.
Kijk zelf, na je tweede login:
security dump-keychain | grep '"svce"' | grep -i claudeBij mij, gemeten op Claude Code 2.1.251:
"svce"<blob>="Claude Code-credentials"
"svce"<blob>="Claude Code-credentials-<hash>"Twee items. Die suffix is afgeleid van het pad van de config-map. Het acct-veld is bij allebei je macOS-gebruikersnaam, dus daar zie je het verschil niet aan; de servicenaam is wat telt.
Twee items betekent dat de scheiding bestaat. Het zegt nog niet dat er twee verschillende accounts in zitten, en dat onderscheid heeft me later die week een halve dag gekost.
Kijk daarom niet naar de keychain maar naar wat Claude Code zelf heeft opgeslagen:
python3 - <<'PY'
import json, os
for label, path in (("eigen", "~/.claude.json"),
("werk", "~/.claude-werk/.claude.json")):
oa = (json.load(open(os.path.expanduser(path))) or {}).get("oauthAccount") or {}
print(label, oa.get("emailAddress"), oa.get("organizationName"))
PYLet op de asymmetrie in die paden. De standaardmap legt zijn staat in ~/.claude.json, in je home. Een eigen config-map legt hem BINNEN die map. Zoek je op één patroon, dan mis je er één.
Wat je NIET moet doen is wat ik eerst deed: de tijdstempels lezen. security find-generic-password toont cdat en mdat, en ik concludeerde uit "cdat is 9 juni" dat mijn oorspronkelijke login er nog in zat. Dat klopt niet. cdat is wanneer het keychain-ITEM is aangemaakt.
Een /login werkt datzelfde item bij en bumpt alleen mdat. Ik las identiteit af uit een aanmaakdatum, en zat er daardoor met volle overtuiging naast terwijl het bewijs voor het tegendeel op mijn scherm stond.
Wat je hiermee ook krijgt: een lege werkbank
Een eigen config-map is een volledig eigen map. Niet alleen voor je login.
Mijn werk-sessie kende mijn eigen /kickoff niet. Logisch, achteraf: mijn 25 skills, 14 agents, mijn commands en mijn user-CLAUDE.md staan allemaal in ~/.claude, en die map had die sessie niet meer.
Dat is het moment waarop je een echte keuze maakt, en die keuze is persoonlijker dan hij lijkt.
| Onderdeel | Waar het leeft | Mijn keuze |
|---|---|---|
| Login | keychain, per config-map | gescheiden |
| Sessies | sessions/ | gescheiden |
| Plugins | plugins/ | gescheiden |
| Skills | skills/ | gedeeld |
| Agents | agents/ | gedeeld |
| Commands | commands/ | gedeeld |
| User-CLAUDE.md | CLAUDE.md | gedeeld |
| Hooks | hooks/ | gedeeld |
| Projecten en history | projects/, history.jsonl | gedeeld |
| MCP-servers | .claude.json | nee, zie onder |
| Settings | settings.json | gescheiden |
Delen doe je met symlinks:
cd ~/.claude-werk
for item in skills commands agents hooks CLAUDE.md projects history.jsonl; do
ln -s "$HOME/.claude/$item" "$item"
doneStaat er al iets in die map, dan overschrijf je dat niet. Hernoem het eerst, maak dan de symlink, en kopieer de inhoud daarna in de gedeelde boom. Bij mij waren dat 55 bestanden uit drie werksessies.
Wanneer je wat kiest
De tabel hierboven is mijn keuze, niet de juiste keuze. Per onderdeel loopt de afweging anders, en de vraag die telt is steeds dezelfde: draagt dit ding data, draagt het een sleutel, of voert het iets uit.
Historie en projecten
Ik deel ze. Dat was mijn tweede beslissing, niet mijn eerste.
Ik begon gescheiden, en liep binnen een dag tegen de rekening aan. Ik zocht een gesprek van gisteren, --continue vond het niet, en ik moest gaan bedenken onder welk account ik het ook alweer gedaan had. Dat is precies de mentale last die ik met dit hele verhaal wilde wegnemen.
Wat het kost is niet niks. Transcripten bevatten letterlijk de inhoud van je werk: klantcode, klantnamen, wat er intern besproken is. Deel je ze, dan staat dat op één hoop met je privéwerk, en verschijnt het in dezelfde /resume-lijst.
Deel ze als je alleen werkt en beide petten van jou zijn. Houd ze gescheiden zodra er iemand anders op die machine kan, of zodra het materiaal onder een geheimhoudingsafspraak valt. Dat is geen technische afweging maar een afspraak die je met een opdrachtgever hebt.
MCP-servers
Hier zou ik het meest voorzichtig zijn, en dat is niet vanwege data.
Een MCP-server is geen tekstbestand. Het is een openstaande verbinding met iets, meestal met een sleutel erin. Mijn eigen configuratie wijst naar een database met bedrijfsgegevens.
Dat is precies het soort ding dat ik niet bereikbaar wil hebben vanuit een sessie die voor een opdrachtgever draait, ook al ben ik het zelf die daar zit.
Praktisch is delen bovendien lastig. Servers op gebruikersniveau staan in .claude.json, en dat bestand bevat bij mij ook de staat van ruim honderd projecten. Dat wil je niet meeslepen om één server te delen.
De uitweg is prettiger dan de keuze. Zet klant- of projectgebonden servers in de .mcp.json van de repo zelf. Die staat buiten je config-map, dus hij werkt in beide accounts zonder dat je iets deelt. Wat overblijft op gebruikersniveau is klein genoeg om per account apart te zetten.
Mijn regel: deel een server alleen als hij niets kan openen wat het andere account niet mag zien.
Settings
Dit is de enige waar ik standaard scheiden zou aanraden, en het is ook de enige waar delen weinig oplevert.
Wat je wint is je statusline en je thema. Wat je riskeert is dat je persoonlijke hooks meedraaien op klantcode. Zit daar iets tussen dat naar je eigen repo pusht of naar je eigen logbestand schrijft, dan lekt er werk naar een plek waar het niet hoort. En het gebeurt stil, want een hook meldt zich niet.
Permissies zijn hetzelfde verhaal in een ander jasje. Wat jij jezelf toestaat op een hobbyproject is niet automatisch wat je wilt toestaan op een systeem van een klant.
Op 31 augustus was mijn eigen settings.json 6.942 bytes met hooks, statusline en permissies. Die van mijn werkmap was 22 bytes met alleen een thema. Wil je toch de statusline, kopieer het bestand dan in plaats van het te symlinken, en gooi de hooks eruit die je daar niet wilt.
Skills, agents, commands en je CLAUDE.md
De makkelijkste ja. Dit is gereedschap dat jij hebt gebouwd en het draagt geen data.
Met één ding om naar te kijken. Je user-CLAUDE.md kan klantnamen bevatten, of voorkeuren die je liever niet in een werkcontext hebt staan. Bij mij importeert dat bestand mijn profiel met absolute paden, dus die schrijfregels reizen mee. Lees hem één keer door voor je hem deelt.
Plugins en sessies
Niet delen. In plugins/ en sessions/ schrijft de CLI zelf per account. Delen levert daar botsingen op in plaats van gemak.
De vuistregel
Deel wat je zelf hebt geschreven en wat geen data bevat. Scheid alles dat data draagt, een sleutel bevat, of code uitvoert.
Historie is de uitzondering die ik bewust maak, omdat het dagelijkse gemak bij mij zwaarder weegt dan het risico. Bij jou kan dat anders liggen, en dan is dat geen slordigheid maar een andere som.
Twee manieren waarop dit stil misgaat
De opzet hierboven werkt. Wat me daarna alsnog twee dagen kostte, waren twee dingen die geen van beide een foutmelding geven.
Een token zonder config-map kaapt je standaard-account
Ik had een oude hulpfunctie staan die het werk-account regelde met CLAUDE_CODE_OAUTH_TOKEN, en die zette de token wel en de config-map niet. Hij draaide dus op mijn eigen map met een werk-token erbovenop.
Die token was verlopen. Claude Code viel netjes terug op een inlogscherm, ik logde in als werk, en die login landde in het standaard keychain-item. Mijn eigen account was daarmee weg, vervangen door het werk-account, zonder één regel uitvoer die daarop wees.
Dat is erger dan een kapotte sessie. Alles wat claude aanroept zonder config-map draaide vanaf dat moment op het verkeerde abonnement. Bij mij is dat niet alleen mijn terminal maar ook een stapel achtergrondprocessen.
/login vraagt niet welk account je bedoelt
Toen ik het wilde herstellen, deed ik het voor de hand liggende: /login en inloggen als mezelf. Het resultaat was opnieuw het werk-account.
/login opent je browser, en die was bij claude.ai nog ingelogd als werk. De OAuth-flow gebruikt die sessie en stelt geen vraag. Je klikt door en bevestigt precies wat je probeerde te veranderen. Twee keer achter elkaar, in mijn geval.
De uitweg is klein: druk c op het inlogscherm, dan kopieert Claude Code de link naar je klembord. Sluit het tabblad dat eventueel al openging, en plak de link in een privévenster en kies daar je account. Werkt dat niet, log dan eerst uit bij claude.ai.
De rode draad
Geen van beide gaf een foutmelding. In allebei de gevallen deed het systeem precies wat het gevraagd werd, met de verkeerde identiteit, en zag het er van buiten normaal uit.
Daarom is dat controle-script uit de vorige sectie geen extraatje. Zonder een manier om te zien welk account in welke map zit, merk je dit type fout pas als iemand je erop wijst dat het verkeerde abonnement is afgeschreven. Ik heb er een commando van gemaakt dat ik nu na elke login draai.
Er is één woord van maken
Het geheel is pas prettig als je er niet over hoeft na te denken. Ik heb mijn launcher een tweede argument gegeven, zodat het ene commando mijn eigen account start en hetzelfde commando met werk erachter het andere.
Daar zit één valkuil in die me een verkeerde diagnose kostte. Ik zette de variabele met export vóór tmux new-session, en dat werkt niet: tmux neemt alleen de variabelen over die in update-environment staan. De sessie startte netjes op en draaide vrolijk op het verkeerde account.
De variabele moet in het commando dat de pane zelf uitvoert:
cmd="export CLAUDE_CONFIG_DIR='$HOME/.claude-werk'; claude --continue || claude"
tmux new-session -d -s werk-sessie -c "$dir" "$cmd"Dat de sessie zonder foutmelding op het verkeerde account draaide, is trouwens het echte gevaar hier. Er ging niets stuk. Het werkte gewoon, met de verkeerde identiteit, en dat zie je alleen als je ernaar kijkt.
Lees ook: Claude Code configureren: CLAUDE.md, rules en skills
Wat ik ervan meeneem
De documentatie beschreef mijn platform toen niet volledig, en mijn conclusie uit wat er níet stond was fout. Twee commando's tegen de keychain lieten binnen een minuut zien hoe het echt zat.
Dat is geen verwijt aan de documentatie. Het is het verschil tussen lezen wat een systeem belooft en meten wat het doet, en dat verschil is bij authenticatie groter dan waar dan ook. Een verkeerde aanname kost je hier niet een foutmelding maar je login.
Draai je zelf werk en privé op één machine, dan ben ik benieuwd waar jij de streep legt. Ik deel mijn gereedschap en mijn historie, en houd mijn settings en mijn MCP-servers gescheiden. Dat is een som die ik voor mezelf heb gemaakt en niet een norm, dus ik hoor graag waar jouw som anders uitvalt.
Werk je met Claude Code voor klanten en wil je dat netjes gescheiden inrichten? Zo pak ik dat aan bij bedrijven die AI inzetten.