feat(mcp): cut over from Hub OAuth to local accounts #122
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/YT-69-local-accounts-cutover"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
yt mcp serveauthenticated every browser against YouTrack Hub and reused each user's Hub access token as their YouTrack REST bearer, so the service's identity, its allowlist, and its only YouTrack credential were all one upstream grant. This replaces that with the local accounts YT-67 added, and gives each account its own YouTrack instance. YT-68 was the schema half of the same cut and is absorbed here: the two deadlock (droppingusersforces deletingoauth_hub.rs, and repointingclient_for_userneedsyoutrack_instancesto exist), so they are one commit or neither.Schema: migration 0004 adds
youtrack_instances, keyed one-to-one onaccounts(id)with ON DELETE CASCADE (the primary key is the foreign key, so 0-or-1 is structural), holding the account's base URL plus its permanent YouTrack token as AEAD ciphertext under YOUTRACK_MCP_MASTER_KEY.hub_tokens,allowlist, andusersare dropped;access_tokens,refresh_tokens, andauthorization_codeskeep their shape with their principal repointed ataccounts(id). The column is renameduser_id->account_idin the same change:users.idandaccounts.idwere independent AUTOINCREMENT sequences, so a mistaken write across them would have bound a token to an unrelated Hub user, and after this there is nousers(id)column left to write into. No data is carried over, per YT-66.Authorization Server:
/authorizesends an unauthenticated browser to/loginwith the pending request stashed in the signed session cookie, and the local sign-in (password, TOTP, or a recovery code) resumes it. Dynamic client registration, PKCE, codes, access/refresh tokens, consent, and the RS middleware are untouched.oauth_hub.rs, the/oauth/hub/callbackroute,hub_auth.rs,hub_scope.rs,allowlist.rs, and theoauth2dependency are gone, and with them the defect class they generated: the scope trap, the client secret and its rotation, and Hub token liveness and recovery.client_for_accountbuilds a client from the account's own base URL and decrypted token, with no expiry check and no refresh path: a permanent token does not expire and cannot be re-minted, so the retry and diagnosis machinery inserver.rsgoes too. An account with no instance is a fresh account, not a fault, and its tool calls come back naming the page where it adds one.yt mcp serveno longer reads YOUTRACK_BASE_URL (the base URL is per-account data now);yt mcp stdiostill does and is unchanged. No YOUTRACK_MCP_HUB_* variable is read anywhere, and none remain in .env.example, compose.mcp.yml, or docs/deployment.md.yt mcp secret rotate,yt mcp allowlist,yt mcp auth, andyt mcp hubare removed: each exists only to manage a Hub credential or a table this drops.yt mcp service installbakes the local-account configuration instead.The admin UI is repointed at accounts (list, ban and revoke, settings); an account's instance is deliberately not readable there. A minimal
/instancepage is added so an account can supply its own base URL and token, which is what makes any tool call possible at all; the fuller settings and admin surfaces stay tracked in YT-70 and YT-71, and the deny list over local accounts in YT-65.it_oauth.rsdrops every Hub-driven test and drives the whole dance against a local account through the real endpoints, ending in an MCPtools/callagainst a stubbed YouTrack that accepts only that account's own token.#YT-69