Skip to content

BUG: Onboarding writes phantom provider entries (OpenCode Zen, Anthropic) without user selection #455

Description

@jeonghun-jj-lee

Only write user-selected providers to config during onboarding

Important

Problem: The Amicode onboarding flow writes provider entries to ~/.config/opencode/opencode.json for providers the user never chose — OpenCode Zen (auto-provisioned key from the credential scanner finding account.json) and Anthropic (placeholder "sk-test" key). These phantom providers appear in the settings UI as "connected," confuse users who pay for different services (e.g. OpenCode Go), and risk accidental API calls against unintended backends.

Approach: Enforce a strict "write-only-selected" policy: after onboarding completes, the config contains provider entries only for providers the user explicitly selected, plus the Amicode-provisioned Bedrock credential (product infrastructure, always written). The credential scanner continues to discover everything (useful for the import UI), but the config-writing step gates on explicit user selection. Placeholder/dummy keys are never written.

Approaches Considered:

Approach Verdict
Write-only-selected (chosen) Minimal change; the config reflects user intent; "Popular" catalog section in settings still shows all available providers for future connection
enabled_providers whitelist Upstream mechanism exists, but it also hides providers from the catalog/Popular section — conflicts with keeping the full browse experience
Write all + disabled_providers blacklist Contradictory (credentials present for disabled providers); more config surface; credentials could be accidentally consumed by code that doesn't check the disabled list

Scope:

  • Fix the confirm-import handler to only write providers the user explicitly checked (already partially implemented — ensure defaults are opt-in, not opt-out)
  • Fix the config-success handler: no change needed (already writes single provider)
  • Always write the amazon-bedrock entry with the Amicode service credential (infrastructure, not user choice)
  • Add a guard in writeBatchConfig to reject placeholder keys ("sk-test", keys shorter than 10 chars)
  • Stop auto-provisioning the OpenCode Zen key unless the user explicitly selects "OpenCode Zen" in onboarding
  • Forward-only: no migration for existing users' configs

Assumptions:

  • The Amicode-provisioned Bedrock credential (ABSK...) is always written because it's product infrastructure — users see it as a normal "amazon-bedrock" provider in their list
  • OpenCode Zen remains available as a choosable provider in onboarding, just not auto-selected
  • The settings panel layout (Connected + Popular catalog browse) stays unchanged
  • Existing users with phantom providers can manually remove entries; no automated cleanup

Acceptance Criteria

  • After onboarding (manual path), only the user-selected provider + amazon-bedrock appear in opencode.json's provider block
  • After onboarding (auto-import path), only providers the user explicitly checked + amazon-bedrock appear in opencode.json's provider block
  • Provider checkboxes in the auto-import UI default to unchecked (opt-in selection)
  • OpenCode Zen key is written only if the user selects "OpenCode Zen" as a provider
  • Placeholder keys ("sk-test", empty strings, keys < 10 chars) are never written to config
  • The amazon-bedrock entry with the Amicode service credential is always present after onboarding, regardless of user selection
  • Providers not in the config do not appear as "connected" in the settings panel (they still appear in "Popular" from the catalog)

Key Decisions

Config-writing gate

The onboarding UI is the sole gate for what enters the provider block. The credential scanner discovers credentials (for display in the import UI), but nothing is written until the user confirms their selection. The import UI presents discovered providers as opt-in checkboxes (unchecked by default).

Bedrock as infrastructure

The amazon-bedrock entry is unconditionally written by both writeOnboardingConfig and writeBatchConfig (or a shared post-write step). It carries the Amicode service credential and is not subject to user selection — it's what makes the product work.

Placeholder key rejection

writeBatchConfig and writeOnboardingConfig reject keys matching: empty string, "sk-test", or key.length < 10. These are never valid credentials and should never have been persisted.

Constraints & Invariants

  • The credential scanner's behavior is unchanged — it still finds everything across all sources
  • The PROVIDER_MODELS map is unchanged — it drives the onboarding UI choices, not config writing
  • The opencode engine's catalog fetch is unchanged — "Popular" section continues to show all providers from models.opencode.ai
  • No migration: existing users' configs are untouched; this is forward-only

Prior Art

Source

Sub-issue of #449 (Auto-Import Credentials: detect existing API keys and configure providers automatically)

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions