# Provider switching

Routed from `skills/SKILL.md`. The authoritative operation list is
[api-reference.md](api-reference.md).

## The only operation

`bun.provider.switch`. That is the whole surface.

NOT-SERVED-FAMILY: `bun.switch.*`
NOT-SERVED: `bun.provider.switch_plan` `bun.provider.switch_rollback`

There is no plan/apply pair for
switching and no rollback operation. The switch
*procedures* live in the providers package as code
(`providers/*_switch_procedure.py`), not as additional operations.

Requires tenant context and the `provider:connect` permission.

## Two categories cannot be switched, and that is permanent

- **Identity — `GUIDED`.** Password hashes cannot be exported from an identity
  provider, so no automated procedure can exist. The switch is a documented human
  procedure, and the protocol does not pretend otherwise.
- **Payments — `UNSUPPORTED`.** Card data lives in the provider's PCI vault and
  cannot leave it. This is an architectural fact, not a missing feature.

Because of these two, switch coverage has a ceiling below 100%. The deploy
readiness gate records this as a permanent `DEGRADED` item rather than an open
defect. Do not file it as work to be done, and do not write copy implying every
provider is swappable.

## What "has a switch procedure" means

It means a procedure exists and is exercised by tests — for most categories,
against fakes. It does **not** mean a real migration between two commercial
vendors has ever been performed here. No commercial provider credential exists in
this repository. See [providers.md](providers.md).

Categories that are neither identity nor payments carry a real switch procedure of
varying test depth; read `providers/CATALOG.md` and the per-category
`*_switch_procedure.py` for the current shape rather than quoting a count from
memory. Counts here move with the catalogue.

## Before you trust a switch

1. Re-wrapping of KMS-held keys is proven **OpenBao to OpenBao only**.
   Cross-vendor KMS switch is **not proven**.
2. Database migration is proven **PostgreSQL to PostgreSQL** with zero data loss
   and a restoring rollback. **Cross-engine is not proven** — see
   [migrations.md](migrations.md).
