Skip to content

Bedrock first-startup login: SSO auth, keyring credentials, explicit provider activation - #7

Merged
wparad merged 13 commits into
mainfrom
claude/bedrock-first-startup-login-qc3gpw
Jun 28, 2026
Merged

Bedrock first-startup login: SSO auth, keyring credentials, explicit provider activation#7
wparad merged 13 commits into
mainfrom
claude/bedrock-first-startup-login-qc3gpw

Conversation

@wparad

@wparad wparad commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds AWS Bedrock as a model provider, authenticated via AWS SSO's device-authorization flow (src/aws_sso.rs). The SSO access token is cached in the OS keyring; short-lived role credentials are exchanged fresh on every use through gitzi creds-helper aws --provider , an AWS credential_process helper invoked by the AWS SDK itself.
  • Extends ProviderDef (src/config.rs) with a kind discriminator (openai-compatible | bedrock) and Bedrock-specific fields (region, profile, SSO start URL/account/role, model ID), plus an enabled flag so providers can exist in config without being wired into any agent.
  • Rewrites bootstrap.rs's first-run discovery to be purely informational and non-blocking: every provider found (LM Studio, Ollama, AWS SSO sessions/Bedrock) is recorded enabled = false and nothing is auto-started, auto-loaded, or auto-logged-into. Onboarding can no longer get stuck waiting on infrastructure.
  • Adds two main-agent chat tools (gitzi_rediscover_providers, gitzi_activate_providersrc/agent/main_agent.rs, dispatched in src/dispatcher/mod.rs) so the user can ask "what providers are available?" and then activate one through conversation. Activating an OpenAI-compatible provider is immediate; activating Bedrock walks through SSO login → account selection → role selection → credential validation across tool calls, then writes a credential_process profile into ~/.aws/config.
  • Updates kb/configuration.md and plan.md's "Bootstrapping" section to describe the new disabled-by-default/explicit-activation model (replacing the old auto-select/auto-start/force-load language); todo.md's Bootstrapping checklist is updated to match (checked off what this PR delivers, dropped the now-superseded "onboarding selection UI" item since activation is chat-driven instead).
  • Fixes 17 integration test files that had fallen out of sync with the model: 16 still referenced Column::Testing/TestBuffer, AgentRole::Tester, and Stage::Testing/TestBuffer/InTesting from an earlier upstream commit that removed the Tester role; tests/e2e_pipeline.rs predated later ProviderDef field additions and the Task.repo parameter on gitzi_create_task. cargo test (lib + every integration test file) now passes cleanly.
  • Merged origin/main to resolve a conflict from upstream's doc consolidation (docs/bootstrap.md/docs/bootstrap-spec.md were deleted and folded into plan.md/todo.md upstream, but that consolidated content still described the old auto-use/force-load behavior — rewrote it to match this PR's actual non-blocking/explicit-activation implementation).

Both new tools read and write ~/.gitzi/config.toml directly rather than the daemon's in-memory Config (immutable for the daemon's lifetime); activating a provider requires a gitzi restart to take effect, which the tool's response states.

Test plan

  • cargo check --lib --bins --tests — clean
  • cargo test — all lib and integration tests pass (0 failed), re-verified after merging origin/main
  • Manually traced the Bedrock activation flow against the AWS SDK source for aws-sdk-sso/aws-sdk-ssooidc API shapes
  • Manual end-to-end test against a real AWS SSO session (not run in this environment — no AWS access)

🤖 Generated with Claude Code

https://claude.ai/code/session_016D4d2Y4sEXsFwnTr4VRsuY


Generated by Claude Code

claude added 13 commits June 26, 2026 15:41
…xplicit provider activation

Adds a Bedrock agent backend authenticated via AWS SSO device-authorization
flow (src/aws_sso.rs), with role credentials exchanged fresh on every call
through a `gitzi creds-helper aws` credential_process helper and the SSO
access token cached in the OS keyring. Provider config (src/config.rs)
gains a `kind` discriminator and Bedrock-specific fields, plus an `enabled`
flag so discovered providers stay inert until explicitly turned on.

Rewrites bootstrap.rs's first-run discovery to be purely informational —
it records every found provider (LM Studio, Ollama, Bedrock/SSO sessions)
disabled and never auto-wires, starts, or logs into anything, so onboarding
can no longer get stuck. The main agent gets two new chat tools,
gitzi_rediscover_providers and gitzi_activate_provider, to re-scan and then
walk the user through turning a provider on (including the multi-step SSO
account/role selection for Bedrock) without blocking the TUI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016D4d2Y4sEXsFwnTr4VRsuY
…shapes

Column::Testing/TestBuffer, AgentRole::Tester, and Stage::Testing/TestBuffer/
InTesting were removed upstream (a9f0fd4) without updating the 16 integration
test files that referenced them, breaking CI. Also fixes tests/e2e_pipeline.rs,
which predated later ProviderDef field additions and the Task.repo parameter
on gitzi_create_task.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016D4d2Y4sEXsFwnTr4VRsuY
…startup-login-qc3gpw

# Conflicts:
#	docs/bootstrap-spec.md
#	docs/bootstrap.md
Collapse nested if/if-let chains into single if-let chains, drop a
redundant Ok(x?) wrap, remove needless borrows/to_string calls, add
Default for InMemoryStore, and allow too-many-arguments on
AgentPool::spawn.
register_client's client_id/client_secret were re-requested on every
login. AWS fixes their lifetime at 90 days (independent of the org's
session-duration setting) and recommends caching them for reuse, so
persist them the same way the access token already is.
OS keyrings (Keychain/Credential Manager/Secret Service) are flat
(service, account) maps with no real hierarchy, so structure has to
come from a naming convention we enforce ourselves. AWS SSO and LLM
API keys had each invented their own ad-hoc scheme. Standardize on
service = "gitzi/<domain>/<kind>", account = <resource identity>,
via a new secrets::service_name helper, so future cloud/provider
integrations (GCP, Azure, more LLM providers) stay consistent and
every keyring entry is self-describing.
Records candidate crates (azure-identity-helpers/azure_identity for Azure,
yup-oauth2/gcp_auth for GCP) and the architectural differences from AWS SSO
(no dynamic client registration, no role-exchange step) to inform future
provider implementations.
… ~/.aws/config

gitzi no longer writes a credential_process profile to ~/.aws/config (or any
other cloud's config files) to get Bedrock credentials to the AWS SDK.
SsoCredentialsProvider implements ProvideCredentials directly, reusing the
cached SSO token and exchanging role credentials on demand; BedrockAgent
builds its aws_sdk_bedrockruntime client with that provider rather than via a
named profile. Removes the now-pointless `gitzi creds-helper aws` subcommand
and the ProviderDef.profile field along with it.
Combine main's WIP-column-stripping logic with this branch's secret
migration and unknown-role stripping in Config::load — all three now
trigger a single rewrite if any changed something. Also fixes a
clippy useless_format lint in main's error_relay.rs that surfaced
once merged.
Capture the agreed design for first-run/every-run LLM setup: a binary
setup-or-use state owned by the daemon, a backend setup state machine
published over the event bus with the TUI as a thin renderer, a
distinguished fallback "control-plane" provider that powers setup and
recovery conversations (never transparent failover), and Config::load
no longer doing discovery.
Add src/setup.rs: the backend-owned "setup or use" gate. SetupState
(Loading/NeedsProvider/Error/Ready), ProviderCandidate, gate_ready
(main bound to enabled provider OR distinguished fallback enabled),
and shared discover-merge + activate logic.

- Config gains fallback_provider (the control-plane brain set on first
  activation) and Config::load stops discovering — load is now pure
  read-and-report; discovery is owned by the setup phase.
- Daemon runs a setup phase on the socket (setup_state / setup_rescan /
  setup_select / subscribe streaming SetupState) before the dispatcher
  is built, so no agents come alive until the gate clears. cmd_daemon
  gates on this.
- gitzi_rediscover_providers / gitzi_activate_provider collapse into
  thin wrappers over crate::setup, sharing one implementation with the
  pre-agent setup path.

Backend compiles clean, clippy clean, 83 lib tests pass.
The TUI becomes a thin renderer over the daemon-owned SetupState:
splash while loading, a provider picker, or an error with a rescan
hint — no setup logic in the frontend. New full-screen draw_setup
switches on the state; setup input (↑/↓/Enter/r) owns the keyboard
until the gate clears.

daemon_client gains a reconnect outer loop that probes the daemon
phase via setup_state and runs either the setup sub-protocol
(subscribe to SetupState, relay SetupSelect/SetupRescan) or the
existing board protocol, reconnecting across the setup→board handoff.

Build + clippy clean, 83 lib tests pass.
- build_main_agent now resolves a named provider into the concrete
  endpoint URL the chat harness talks to, so an activated provider
  (e.g. Ollama on :11434) actually drives chat instead of silently
  falling back to the localhost default.
- Dispatcher gains a fallback control-plane brain (build_fallback_agent):
  a chat agent bound to the distinguished fallback_provider, built only
  when it's enabled, OpenAI-compatible, and distinct from main's own
  provider. run_main_agent_turn falls back to it once, with a recovery
  preamble, when main's provider is down — an explicit "what do you want
  to do?" conversation, never a silent swap of the user's real request.
- Docs: kb/configuration.md documents fallback_provider + the setup
  gate; bootstrap module doc + ADR-002 status updated to "implemented".
- Updated the four integration tests that construct Dispatcher / call
  build_main_agent for the new signature + field. Fixed a pre-existing
  redundant-closure lint in state/review.rs test helper.

Build + clippy clean; 86 lib tests and the full integration suite pass.
@wparad
wparad merged commit 8e00131 into main Jun 28, 2026
1 check passed
@wparad
wparad deleted the claude/bedrock-first-startup-login-qc3gpw branch June 28, 2026 09:55
wparad added a commit that referenced this pull request Jul 25, 2026
…qc3gpw

Bedrock first-startup login: SSO auth, keyring credentials, explicit provider activation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants