Skip to content

[Reborn] Migrate secrets, OAuth, and auth setup product flows #3289

Description

@serrrfirat

Parent: #3031
Related: #3094, #3068, #3088, #3140, #3032, #3288, #3020, #3029, #3026

What to build

Preserve current credential, OAuth, and auth-setup product behavior while moving product authority to typed auth-flow, interaction, credential-account, secret-broker, and host-mediated injection services.

This issue is about product-facing auth setup and recovery flows. It does not own low-level durable secret encryption, one-shot lease mechanics, host-mediated HTTP credential injection, capability authorization, or no-exposure scanning, but it must compose those services safely.

Scope includes:

  • hosted OAuth callback for integration/provider auth;
  • OAuth authorization start, callback completion, stale/failed callback recovery;
  • manual token entry without transcript/model leakage;
  • missing/expired credential recovery states;
  • extension/channel/provider/MCP/WASM auth setup;
  • credential account creation/update/selection UX;
  • token refresh product status and recoverability;
  • secret/credential cleanup on uninstall/deactivate;
  • stable redacted auth state projections for web/CLI/chat/API;
  • no raw secret/backend-error leakage.

Resolved design decisions

  • Start with typed product auth boundaries, not a V1 port. Add contracts for AuthFlowManager, AuthInteractionService, and CredentialSetupService first. Product routes/chat/CLI should create/list/complete/cancel typed auth flows and credential setup gates, not own raw OAuth callback logic or secret writes.
  • Use durable scoped AuthFlowRecords as source of truth. V1 has several pending authorities (PendingOAuthRegistry, web login OAuthStateStore, extension pending_auth, engine PendingGateStore, MCP OAuth helpers). Reborn auth flows should be durable scoped records keyed by opaque flow id + verifier/state hash, scoped by tenant/user/agent/project/session/thread/product surface. In-memory caches are accelerators only.
  • Create typed CredentialAccount records for OAuth and manual tokens. Product surfaces refer to CredentialAccountId and redacted account metadata, not loose secret names. Account records reference SecretHandles for access/refresh/client credentials and carry provider/extension/account labels, status, owner scope, and target policy.
  • Manual token entry uses a secure out-of-band input channel. Chat can initiate setup, but token values must be collected through AuthInteractionService secret input channels that bypass model transcript/tool arguments. Web uses secret fields, CLI/TUI uses hidden input, API uses a dedicated secret-submit endpoint. Model-visible outputs see only redacted status such as credential_submitted or auth_failed.
  • Public OAuth callbacks only complete the auth flow and enqueue a typed continuation. Callback handlers validate/consume the AuthFlowRecord, perform token exchange through auth services, store/update credential accounts via secret services, mark complete/failed, and emit a continuation event. They do not directly activate extensions, resume turns, replay messages, or mutate lifecycle state.
  • Use typed AuthContinuationRef, not raw message replay. Auth flows can carry redacted continuation refs such as SetupOnly, LifecycleActivation { package_ref }, TurnGateResume { turn_run_ref, gate_ref }, or ProductActionResume { action_ref }. ProductWorkflow/AuthInteractionService handles the continuation after completion.
  • Token refresh happens in credential broker/session preparation before approved use. Product auth flows display expired / reauthorize_required states but do not read raw tokens or refresh from web/CLI/chat route logic. Refresh failures map to stable recoverable auth-required states.
  • Replace implicit admin/default credential fallback with explicit shared credential accounts/grants. V1’s default secret fallback is legacy/default-off migration behavior. Reborn credential-session creation must name a scoped account or explicit inherited/shared grant; product UX may show “admin-managed credential available.”
  • Credential account selection is policy/user/admin controlled. Model/tool requests can express provider/capability intent, but cannot invent or bind arbitrary CredentialAccountIds. A unique authorized account can be selected by policy/grant/admin config; otherwise return sanitized account_selection_required / auth_required interaction state.
  • Uninstall/deactivate cleanup follows ownership class. Extension-owned credentials are revoked/deleted/tombstoned on uninstall. User/shared reusable CredentialAccounts are not deleted automatically, but extension bindings, grants, sessions, and visibility are revoked. Deactivate revokes active sessions/visibility but keeps accounts. Partial failures produce redacted quarantine diagnostics.
  • OAuth discovery/token exchange/refresh uses a narrow auth network client over host-managed egress. OAuthHttpEgress / AuthProviderClient should centralize HTTPS/SSRF/redirect/body-limit/proxy behavior and sanitized errors. Product routes and auth-flow services must not instantiate raw reqwest clients directly.
  • Shared auth-flow substrate can support identity login later, but first slice is integration credential flows only. Existing user login OAuth (/auth/login/{provider}, session cookies, identity linking, domain checks) remains a separate owner/intent for now. [Reborn] Migrate secrets, OAuth, and auth setup product flows #3289 first slice targets extension/channel/provider/MCP/WASM credential setup and recovery.
  • Successful UX compatibility is preserved where safe; unsafe behavior becomes documented drift. Preserve OAuth callback landing, auth-required gates, retry/recovery, auto-continuation, and setup status UX. Remove or drift raw chat-token entry, implicit default secret fallback, route-owned activation/resume, raw backend errors, and direct route-owned network clients as needed under Reborn cutover blocker: add compatibility gate for pre-Reborn behavior #3020.

First implementation slice

Add contracts/types and fake-service tests only. Do not rewrite production OAuth callback routes, extension setup routes, CLI auth flows, or secret storage until #3094/#3088/#3140/#3032 dependencies are ready.

Suggested first PR shape:

AuthInteractionService contracts
  -> AuthFlowManager fake
  -> CredentialSetupService fake
  -> CredentialAccountService fake
  -> OAuthHttpEgress / AuthProviderClient fake
  -> SecretRepository / SecretBroker / SecretLease fakes from #3088 boundary
  -> SecretCleanupService fake
  -> ProductWorkflow continuation sink fake
  -> NoExposure/redaction guard fake

Define product DTOs/statuses such as:

AuthFlowRecord
AuthFlowId
AuthFlowKind::{IntegrationCredential, IdentityLogin /* future */}
AuthFlowStatus::{pending, awaiting_user, callback_received, completing, completed, failed, expired, canceled}
AuthChallenge::{oauth_url, manual_token_required, account_selection_required, setup_required, reauthorize_required}
CredentialAccount
CredentialAccountStatus::{configured, missing, expired, refresh_failed, revoked, pending_setup}
CredentialOwnership::{extension_owned, user_reusable, shared_admin_managed, system}
AuthContinuationRef::{setup_only, lifecycle_activation, turn_gate_resume, product_action_resume}
AuthErrorCode::{unknown_or_expired_flow, cross_scope_denied, provider_denied, token_exchange_failed, refresh_failed, credential_missing, account_selection_required, backend_unavailable}

The first slice should include a behavior inventory mapping each V1 auth behavior to:

  • product surface: chat action, web route, CLI/TUI, setup/admin, callback;
  • current V1 implementation path;
  • Reborn owner service;
  • auth-flow record shape and scope;
  • credential-account shape and ownership class;
  • secret handles and broker/session behavior;
  • continuation behavior;
  • setup/recovery status projection;
  • no-exposure and redaction requirements;
  • supported, blocked, or deferred legacy status;
  • Reborn cutover blocker: add compatibility gate for pre-Reborn behavior #3020 compatibility drift note if intentionally changed.

Representative V1 paths to inventory:

  • src/auth/oauth.rs pending OAuth flow construction, callback state, token exchange, refresh, token storage;
  • src/channels/web/features/oauth/mod.rs public extension OAuth callback, auto-activation, SSE broadcast, engine gate resume/replay;
  • src/auth/extension.rs auth preflight, missing-credential descriptions, readiness, latent provider auth;
  • src/extensions/manager.rs extension/MCP/WASM/channel auth, configure token, cleanup, pending auth maps;
  • src/tools/mcp/auth.rs MCP OAuth/DCR/discovery/refresh;
  • src/tools/wasm/credential_injector.rs and src/tools/builtin/http.rs V1 host-boundary credential injection expectations;
  • src/channels/web/handlers/secrets.rs admin secret create/list/delete;
  • src/tools/builtin/secrets_tools.rs model-facing secret metadata/delete behavior;
  • src/setup/wizard.rs setup/keychain/provider credential entry.

Acceptance criteria

  • Product-facing auth flows go through AuthFlowManager, AuthInteractionService, and CredentialSetupService contracts.
  • Durable scoped AuthFlowRecords are source of truth; in-memory pending maps are not product authority.
  • OAuth/manual-token setup creates or updates scoped CredentialAccount records referencing SecretHandles, not loose secret names as primary identity.
  • Manual token values bypass model transcripts/tool args and are accepted only through secure secret-submit interactions.
  • Public OAuth callbacks validate and atomically consume flow records using opaque state/verifier data, and return generic responses for unknown/stale/cross-scope flows.
  • OAuth callbacks do not directly activate extensions, resume turns, replay messages, or mutate lifecycle state; they emit typed continuations.
  • AuthContinuationRef supports setup-only, lifecycle activation, turn-gate resume, and product-action resume without storing raw prompt/message content.
  • Token refresh is represented as broker/session/pre-injection behavior with sanitized product status projection.
  • Missing, expired, refresh-failed, ambiguous-account, and revoked credentials produce stable recoverable auth states rather than raw backend errors.
  • Shared/admin-managed credentials use explicit credential accounts/grants, not implicit default secret fallback.
  • Model/runtime/tool input cannot directly choose arbitrary credential accounts; account selection is policy/user/admin controlled.
  • Uninstall/deactivate cleanup is idempotent, ownership-aware, auditable, and produces quarantine diagnostics on partial failure.
  • OAuth discovery/token exchange/refresh use OAuthHttpEgress / AuthProviderClient over host-managed egress/proxy policy; product routes do not use raw HTTP clients.
  • First slice targets integration/provider credential flows; identity-login OAuth is either explicitly out of scope or represented as a future IdentityLogin flow kind without credential-account semantics.
  • Adapter-facing DTOs are stable, redacted, tenant/user/agent/project/session scoped, and safe for web/CLI/chat/API/projection rendering.
  • Tests cover OAuth start, callback success, stale callback, malformed callback, cross-scope callback denial, provider-denied callback, manual token secure-submit, missing credential, expired credential, refresh-failed credential, account selection required, explicit shared account grant, cleanup delete/revoke/tombstone, typed continuation emission, and redaction/no-exposure sentinels.
  • Architecture tests prove product auth code does not depend on v1 ExtensionManager as auth authority, raw SecretsStore::get_decrypted, raw secret names as primary identity, raw reqwest, raw pending maps, direct lifecycle activation, direct turn replay/resume, raw provider errors, or runtime/host secret material.

Non-goals for first slice

Blocked by / coordinates with

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

module:M1-webui-productReborn WebUI beta module M1: browser-facing WebUI/WebChat product surfacerebornIronClaw Reborn architecture and landing worksuggested_P1Issue creator suggests Priority 1

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions