fix(mcp): allow the configured first admin to bootstrap an empty allowlist #103
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/YT-46-admin-bootstrap-allowlist"
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?
What
Fixes YT-46: on a fresh
yt mcp serveinstall the allowlist is empty, so every Hub login was denied withAccess denied: not on the allowlist, including the login configured asYOUTRACK_MCP_ADMIN_HUB_LOGIN. The admin could not self-serve via/adminbecause the browser login flows through the same gate. The first-admin bootstrap the docs promise was unreachable.Root cause
HubClient::complete_logindenies before anything else whenis_allowedis false, andis_allowedchecked only theallowlisttable. The admin flag was computed only after the gate, and nothing seeded the admin login into the allowlist at startup. Empty allowlist -> nobody admitted -> no way to add the first entry.Fix
is_allowednow treats an identity whose login matchesadmin_hub_loginas implicitly allowed, through a new sharedis_bootstrap_adminpredicate thatcomplete_loginalso uses for theis_admingrant. The "implicitly allowed" set and the "granted admin" set are therefore one predicate and cannot diverge. Login-equality matching is unchanged from the prioris_adminlogic, so a non-admin, non-allowlisted identity is still denied and anadmin_hub_loginset to a non-login value neither auto-allows nor auto-admins.Invariant sweep (login admission + is_admin single-source)
oauth_hub.rsis_allowed(login gate)oauth_hub.rscomplete_loginis_adminis_bootstrap_adminadmin.rs:100!user.is_admin(admin UI authz)complete_loginnow sets; downstream of the gateoauth_as.rs:376LoginOutcome::Deniedoauth_as.rsis_allowed_redirectTests
admin_bootstrap_allowed_on_empty_allowlist: admin logs in against an EMPTY allowlist, is granted admin, and re-login is idempotent (one user row).non_allowlisted_user_is_denied_with_no_rowalready covers non-admin denial on an empty allowlist; other allowlist tests unchanged.just pre-commitgreen (fmt, clippy-D warnings, build, 83 tests).Follow-ups
yt mcp allowlist add/list/removeso operators never need raw SQL against the SQLiteallowlisttable.