# Migrating from 3.0 to 3.1

3.1 is the **Phase Q** incremental release on top of 3.0. The
migration is **purely additive** — every new capability is opt-in via
env or Helm value, and the default
`docker compose --profile demo up` runs identically on 3.0 and 3.1.
No behaviour flips required. (3.0.1 was a republish-only version bump
with no behaviour change.)

## tl;dr

| You are running… | Required action |
|---|---|
| The OSS demo (`docker compose --profile demo up`) | None — defaults unchanged. |
| `helm install obs ./helm/observability-mcp` (defaults) | None — still single-replica, no Redis, no SCIM, anonymous auth. |
| Any custom Helm values from 3.0 | None. The new value blocks below are all off by default. |
| Basic-auth (`OMCP_AUTH=basic`) | None. The new password policy is enforced only when you *mint* a password via `hash-password.mjs`; existing hashes keep working. Account lockout is on by default but only triggers after repeated failures (tunable / disablable). |
| A plugin author | Optionally adopt `manifest.hooks[]` auto-registration; programmatic registration still works. |

## New opt-in capabilities

| Env / Value | What it does | Docs |
|---|---|---|
| `OMCP_SCIM_BACKEND=redis` + `OMCP_SCIM_REDIS_URL` | Shared SCIM snapshot across replicas (file remains default). | [scim-provisioning.md](../scim-provisioning.md) |
| `OMCP_AUTH_REVOCATION_FILE=<path>` | Persist the session revocation blocklist across restarts. | [access-control.md](../access-control.md#session-revocation) |
| `OMCP_AUTH_LOCKOUT_*` | Tune per-account login lockout (`MAX_FAILURES` / `WINDOW` / `BASE` / `MAX`); `OMCP_AUTH_LOCKOUT_DISABLED=true` turns it off. | [auth-basic.md](../auth-basic.md#account-lockout) |
| `OMCP_PASSWORD_*` | Tune the credential-minting password policy (`MIN_LENGTH` / `MIN_CLASSES` / `DENYLIST_DISABLED` / `POLICY_DISABLED`). | [auth-basic.md](../auth-basic.md#password-policy) |
| `OMCP_CSP_STRICT_REPORT=true` | Emit the strict report-only CSP (surfaces inline-handler debt; off by default to avoid console noise). | [auth-and-tls.md](../auth-and-tls.md#content-security-policy-web-ui) |
| `OMCP_REDIS_URL` (already in 3.0) | Now also backs the Streamable HTTP **transport session map** and the **account-lockout** store — multi-replica gateways no longer need sticky ingress. | [horizontal-scaling.md](../horizontal-scaling.md) |
| `audit.s3.*` (Helm) / `OMCP_AUDIT_S3_*` | S3-compatible audit sink (S3 / MinIO / R2 / B2). | [audit-sinks.md](../audit-sinks.md) |
| `OMCP_FEDERATION_UPSTREAMS=name=stdio:<cmd>` / `name=ws://…` | Federate upstream MCP servers over stdio or WebSocket. | [federation.md](../federation.md) |

## New topology providers

Five concrete providers on the 3.0 multi-cloud merger foundation —
each a filesystem connector installed from the hub or mounted under
`plugins/`:

| Provider | Discovers | Edges |
|---|---|---|
| `aws` | EC2 / ECS / EKS | `OWNED_BY`, `RUNS_ON` |
| `gcp` | GCE / Cloud Run / GKE | `OWNED_BY`, `RUNS_ON` |
| `istio` | mesh services (via Prometheus) | `CALLS` |
| `linkerd` | mesh services (via viz) | `CALLS` |
| `consul` | Consul Connect services | `CALLS` |

They merge into the same topology graph as the built-in Kubernetes
source, so a service that appears in multiple providers collapses to
one node.

## Enhanced MCP tools

- **`query_logs`** gains two optional, additive params (issue #415):
  `labels` (exact-match filters on backend-extracted fields like
  method/status/url/environment) and `aggregate`
  (`count_over_time`/`sum`/`topk` pushed down to LogQL metric queries).
  Existing `query_logs` calls are unchanged. See
  [loki.md](../loki.md#structured-label-filters-labels).

## New endpoints

- `GET /api/health/anomaly-sparklines` — per-service last-hour
  anomaly-score series for the Health-tab sparkline.
- `POST /api/auth/revocations` / `GET /api/auth/revocations` —
  session revocation (admin).
- `POST /api/csp-violations` — CSP report sink (browser-posted).
- `POST /api/playground/invoke` — backs the in-product Playground tab.

## New UI

- **Playground** tab — invoke any live tool from a generated form.
- **Health** cards now render an anomaly-score sparkline (last hour).

These are inert until you use them; no existing view changed shape.

## Security defaults that changed

Two hardening features are **on by default** but designed to be
invisible in normal use:

- **Account lockout** — only triggers after
  `OMCP_AUTH_LOCKOUT_MAX_FAILURES` (default 5) failed logins for one
  username inside the window. Set `OMCP_AUTH_LOCKOUT_DISABLED=true` to
  opt out.
- **Content-Security-Policy** — the enforced policy keeps the UI fully
  working (it allows the inline handlers the single-file UI relies on).
  If you embed the UI in an iframe, note `frame-ancestors 'none'`.

Everything else (revocation persistence, strict CSP report-only,
password policy tuning, Redis backends) is opt-in.

## Nothing removed

No env var, Helm value, endpoint, MCP tool, or CLI command was
removed or renamed in 3.1. The 3.0 surface is a strict subset of 3.1.
