---
module: processes.customer-provisioning
title: Customer & Institution Provisioning Wizard
tab: Overview
order: 10
audience: bcos
---

How to provision a new **institution** (customer + license + modules + MSP allocation) and hand
agent onboarding off to an MSP admin — in one pass, from the mgmt portal.

**Where:** `https://mgmt.bcos.cloud/portal/customers/wizard` (also `portal.bcos.cloud`).
**Who:** requires the `ADMIN` role in the **mgmt portal** (a separate account from your
`bcos.cloud` SSO login — see [[technical.mgmt]]).

> There is no "institution" entity. An institution **is** a `Customer` of type `BANK` carrying a
> unique `institutionKey`. The wizard is orchestration over existing services.

## The five steps

| # | Step | What it does | Required? |
|---|------|--------------|-----------|
| 1 | **Institution details** | Creates the BANK customer | Name, Email, Company Domain, Institution Key |
| 2 | **License** | Issues a license key | Tier (BASIC / PRO / ENTERPRISE) |
| 3 | **Modules** | Grants modules to the institution | Optional |
| 4 | **MSP allocation** | Gives an MSP access to this institution | **Skippable** |
| 5 | **Review & handoff** | Confirms, then messages MSP admins | Optional |

### 1 — Institution details
`Name`, `Email`, `Company Domain`, and `Institution Key` are required; company, phone, address and
notes are free-form.

**The institution key is normalised to UPPERCASE** on save (`first-national` → `FIRST-NATIONAL`).
Whatever casing you type, the stored key is the uppercase form — that is the value the ATM agent
must use for `incident.institution.key`.

### 2 — License
Pick a tier. `Max activations` defaults to **3**. `Expires at` may be left blank for a perpetual
license. Tick `Trial` for an evaluation licence.

**The license key is never shown in the wizard and is never sent in the handoff message.** Retrieve
it afterwards from the customer detail page you land on (`/portal/customers/{id}`).

### 3 — Modules
Only **enabled, non-default, non-core** modules are offered — defaults and core modules are granted
automatically and don't need allocating. Selection is a **full replace** of the institution's module
set, not an add.

### 4 — MSP allocation *(skippable)*
Choose the MSP that will service this institution (e.g. *Quality Data Systems*). This writes a
`customer_institution_access` row so the MSP's users can see the institution.

**Skipping this step also removes the handoff step**, because recipients in step 5 are drawn from
the selected MSP. Skip it only for an institution BCOS services directly.

### 5 — Review & handoff
The review pane summarises everything before you commit. Below it, tick the **MSP admins** who
should receive the agent-onboarding handoff.

Recipients are the enabled `MSP_ADMIN` users whose **email domain matches the MSP's
`Company Domain`** — e.g. selecting *Quality Data Systems* (`qualitydatasystems.com`) offers
`jethridge@qualitydatasystems.com` and colleagues. An MSP with no matching admins shows an empty
list.

## What happens on Submit

Steps 1–4 commit in a **single database transaction**. If any part fails, **nothing** is
persisted — no orphaned customer, no dangling license. The wizard redisplays with the error.

Then, for each ticked recipient, an in-app **DIRECT inbox message** is sent (mgmt → `hiveops-messaging`).
The success banner reports how many admins were notified.

## The handoff message

Subject: `Action needed: onboard agent for <Institution> (<KEY>)`

The body is a **runbook, not a credential drop** — it deliberately contains **no license key and no
agent token**. It asks the MSP admin to:

1. Set the agent properties on the institution's ATMs:
   - `agent.endpoint = https://api.bcos.cloud/agent`
   - `incident.institution.key = <INSTITUTION_KEY>`
2. Generate a token in the **Devices app → Agent Tokens → Generate** for that institution
   (`https://devices.bcos.cloud`).
3. Paste it into the agent properties as `agent.auth.token`.

The MSP admin does the work; BCOS never handles their token. `MSP_ADMIN` already has permission to
mint agent tokens, so no extra grant is needed.

## Gotchas

- **The handoff message cannot be recalled.** It lands in a real person's HiveOps inbox the moment
  you press Submit. There is no dry-run and no preview-send. For a first run, provision a throwaway
  institution with **no recipients ticked**, verify, then delete it.
- **No recipients ticked ⇒ no message.** Provisioning still succeeds silently. If the MSP is
  expecting a handoff, check the success banner said "sent to N MSP admins".
- **Skipping step 4 skips the handoff.** See above.
- **Disabled MSP_ADMIN users never appear** as recipients.
- Deployment requires `MESSAGING_SERVICE_URL` on the mgmt container. Without it the wizard
  provisions fine and the handoff **silently fails to send** (it defaults to `localhost:8086`).
  See [[technical.mgmt]].

## Related

- [[technical.mgmt]] — mgmt service, licensing, agent tokens, portal roles
- [[technical.messaging]] — how the DIRECT inbox message is delivered
- [[msp.institution-keys]] — institution keys and MSP access
