Add per-provider auth.json keys; make auth methods registry-generic (P0b)
Platform API keys now live in auth.json under the platform-id scope (the per-provider auth.json key contract), resolved env > auth.json > legacy [platforms.*] config.toml (read-only fallback). The TUI login picker, paste box, auth-method advertising, and authenticate handler are all registry-generic: a new PlatformSpec row appears in the login UI and authenticates with zero UI changes. Spec rows gained vendor/console_host/ login_label display fields (moonshot strings byte-identical, pinned by tests). Adversarial review caught that auth.json keys were validated at login but never stamped onto catalog entries (completions would 401; restart lost eager auth). Fixed red-green: resolve_model_list/resolve_model_catalog now take a resolved PlatformApiKeys snapshot consumed by the credential- stamping layer (auth.json beats stale config.toml, matching the login validator), with production callers resolving fresh per catalog build. Also from review: the new auth.json writer takes the manager's cross- process flock (bounded retry — an unlocked RMW racing a token refresh could revert a rotated refresh token); the oauth-401 wiremock test is hermetic (KIGI_SHARE_DIR tempdir; it could read a dev's real auth.json and hit live moonshot); cli_models resolves real keys; auth.json is read once per registry sweep; caller-less lock_config_writes deleted; catalog resolvers tightened to pub(crate); stale config.toml doc comments and the no-credentials error copy updated.
This commit is contained in:
1 parent
99d99fb47a
commit
c5ddaec71e
19 files changed
+731
-375
No files matched your search
@@ -452,18 +452,19 @@ impl MvpAgent {
|
||||
)
|
||||
.await
|
||||
}
|
||||
/// `authenticate(moonshot-cn / moonshot-ai)`: interactive open-platform
|
||||
/// API-key login from the welcome picker.
|
||||
/// `authenticate(<api-key platform id>)`: interactive API-key login from
|
||||
/// the welcome picker for any non-OAuth registry platform.
|
||||
///
|
||||
/// Reloads the platform keys from disk+env (the TUI persists the pasted
|
||||
/// key to `[platforms.<id>]` in config.toml immediately before this call),
|
||||
/// fails with an actionable error when none is configured, validates the
|
||||
/// key against `GET {platform_base}/models`, then marks the session
|
||||
/// authenticated exactly like an external API key: publish the method id
|
||||
/// (NOT session-based — no token refresh), swap the freshly-stamped config
|
||||
/// into the models manager, and trigger the model sync so the catalog
|
||||
/// gains the platform's entries. The key itself is never logged.
|
||||
pub(super) async fn authenticate_moonshot(
|
||||
/// key to auth.json under the platform-id scope immediately before this
|
||||
/// call), fails with an actionable error when none is configured,
|
||||
/// validates the key against `GET {platform_base}/models`, then marks the
|
||||
/// session authenticated exactly like an external API key: publish the
|
||||
/// method id (NOT session-based — no token refresh), swap the
|
||||
/// freshly-stamped config into the models manager, and trigger the model
|
||||
/// sync so the catalog gains the platform's entries. The key itself is
|
||||
/// never logged.
|
||||
pub(super) async fn authenticate_api_key_platform(
|
||||
&self,
|
||||
platform: kigi_models::PlatformId,
|
||||
method_id: acp::AuthMethodId,
|
||||
@@ -480,10 +481,11 @@ impl MvpAgent {
|
||||
Some("platform_key_invalid_or_missing"),
|
||||
);
|
||||
})?;
|
||||
// Swap the on-disk config (now carrying the key) into the models
|
||||
// manager so `apply_platform_credentials` stamps the platform's
|
||||
// catalog entries; a parse failure keeps the last-known-good config
|
||||
// (`on_auth_changed` below still re-resolves keys from disk itself).
|
||||
// Rebuild the catalog from the on-disk config: the rebuild freshly
|
||||
// resolves platform keys (env > auth.json > config), so the key just
|
||||
// persisted to auth.json is stamped onto the platform's entries; a
|
||||
// parse failure keeps the last-known-good config (`on_auth_changed`
|
||||
// below still re-resolves keys from disk itself).
|
||||
match crate::config::load_effective_config()
|
||||
.map_err(|e| e.to_string())
|
||||
.and_then(|raw| crate::agent::config::Config::new_from_toml_cfg(&raw))
|
||||
|
||||
Reference in new issue
Block a user