Agent Authenticator finns för att 2FA fortfarande var ett manuellt steg i annars automatiserade arbetsflöden på Forge Nord.
Problemet var enkelt. Agenten kunde ta sig igenom inloggningen, hantera gränssnittet och fortsätta efter autentisering. Men när en TOTP-kod behövdes stannade flödet och en människa fick läsa av sex siffror från en telefon.
Den uppenbara genvägen är att ge agenten själva TOTP-hemligheten och låta den generera koder lokalt. Det ville Forge Nord inte göra. Seed:en är en långlivad hemlighet. Den aktuella TOTP-koden är det inte. De två sakerna bör inte behandlas som samma sak.
Därför byggde Forge Nord Agent Authenticator: en MCP-server som lagrar TOTP-hemligheter i ett krypterat lokalt valv och bara exponerar operationer som returnerar aktuell kod eller hanterar konton. Det finns inget MCP-anrop för att läsa ut hemligheten igen.
Design
Projektet är medvetet smalt.
- lagra TOTP-hemligheter krypterat i vila
- returnera aktuell kod vid behov
- ha lokal transport som standard
- fungera med etablerade MCP-klienter som Claude Code och Cursor
Det är hela scopet. Det här är inte en lösenordshanterare, inte en generell secrets-lösning och inte ett bredare auth-system.
Verktygsytan
MCP-gränssnittet är litet:
- lista konton
- visa icke-hemlig metadata för ett konto
- generera aktuell TOTP-kod
- lägga till konto från secret eller
otpauth://-URI - ta bort konto
Den viktigaste begränsningen är avsiktlig: modellen kan be om en kod, men kan inte läsa seed:en som genererar framtida koder.
Vad som behövde fixas före release
Den första interna versionen fungerade, men den var inte redo att släppas publikt utan städning.
Samtidiga skrivningar till valvet
Valvet använde redan fillås, men inte över hela read-modify-write-kedjan. Det fungerar tills flera processer rör samma fil. Release-versionen låser hela mutationsvägen så att skrivningar blir atomiska.
Nyckelhantering vid första uppstart
Att skriva ut nyckelmaterial till standard output är en dålig default generellt, och extra dåligt när huvudsaklig transport är MCP över stdio. First-run-flödet gjordes om så att nyckelhanteringen är tystare och mindre benägen att hamna i loggar eller transkript.
HTTP-default
Om ett verktyg kan binda på nätverket betyder defaulten mer än varningstexten i README:n. HTTP-läget är därför loopback-only som standard och kräver ett explicit val för remote bind.
Varför jag tycker mönstret är användbart
Implementationen är liten, men gränssnittstänket är användbart.
När man bygger agentinfrastruktur är det oftast mer användbart att inte fråga “vilken hemlighet behöver modellen?” utan “vilken minsta användbara operation går att exponera?”
I det här fallet var svaret enkelt:
- inte TOTP-seed:en
- bara den aktuella TOTP-koden
Samma mönster går att använda på fler ställen:
- inte databaslösenordet, utan ett smalt frågegränssnitt
- inte molninloggningen, utan en deployment-operation
- inte en generell secrets manager, utan en explicit kapabilitet
Det är den typen av gräns som är enklare att granska och enklare att drifta.
Open source-release
Innan repot publicerades lade jag till sådant som interna verktyg ofta hoppar över:
- hårdare hantering av valvskrivningar
- renare nyckelsetup
- riktig CLI med
serve,doctorochkeygen - CI och release-automation
- tydligare säkerhetsdokumentation
Koden finns på GitHub.