docs: inbound API key store — shared SQL Server provider on central pairs (spec, runbook + central-pairs procedure, DBA DDL copy, topology, env inventory, CLAUDE.md, register row 108 closed with rig proof, row 109 Secrets backoff follow-up, Delmia spec §8)
Claude-Session: https://claude.ai/code/session_013L3XdmVii9i5sY4FChU8pB
This commit is contained in:
@@ -21,7 +21,31 @@ Central cluster only. Method scripts execute on the **active** central node; a *
|
||||
## API Key Management
|
||||
|
||||
### Storage
|
||||
- API keys are stored in the **configuration database (MS SQL)**.
|
||||
- API keys are stored in the shared `ZB.MOM.WW.Auth.ApiKeys` library's store — **SQLite per node by
|
||||
default**, or the shared `zbauth` schema in the **configuration database (MS SQL)** on a central
|
||||
pair when `Provider=SqlServer` (see *Key store provider* below). Revoke/rotate/scope changes are
|
||||
cluster-wide immediately only under `SqlServer`; under `Sqlite` they apply to whichever node served
|
||||
the management call.
|
||||
|
||||
### Key store provider
|
||||
|
||||
Config section `ScadaBridge:InboundApi:ApiKeyStore` (design 2026-09-02, register row 108):
|
||||
|
||||
| Key | Default | Notes |
|
||||
|---|---|---|
|
||||
| `Provider` | `Sqlite` | `Sqlite` (per node) or `SqlServer` (shared across a central pair). Case-insensitive; an unrecognized value fails startup via `StartupValidator`. |
|
||||
| `SqlServer:ConnectionString` | `ScadaBridge:Database:ConfigurationDb` | Must be a literal or env override, **never** a `${secret:}` reference — the secrets store is itself SQL-backed, so resolving one through the other would be circular. |
|
||||
| `SqlServer:Schema` | `zbauth` | Owns `schema_version`, `api_keys`, `api_key_audit`. |
|
||||
| `SqlServer:CommandTimeout` | 30 s | |
|
||||
| `ImportFromSqlitePath` | the library's `SqlitePath` default | SQLite file imported **once**, at boot, when `Provider=SqlServer`; insert-where-absent, so both nodes of a pair may import their own file and the result is the union. On success the file is renamed `*.imported` (plus `-wal`/`-shm`); on failure the import logs Error and the node keeps booting on the keys already in SQL. |
|
||||
|
||||
A Central node with ≥2 seed nodes still running `Provider=Sqlite` logs a boot-time Warning (not a hard
|
||||
fail — availability-first, matching the auto-down decision) naming this design, because a failover
|
||||
will otherwise 401 every inbound client until keys are re-issued. Both docker rigs (`docker/`,
|
||||
`docker-env2/`) run `Provider=SqlServer`; QA/prod are a separate deployment record. See
|
||||
`docs/operations/inbound-api-key-reissue.md` → *Central pairs* for the reissue/migration runbook and
|
||||
`docs/operations/sql/zbauth-schema.sql` for the DDL a DBA runs by hand when the app login lacks
|
||||
CREATE SCHEMA/TABLE rights.
|
||||
|
||||
### Key Properties
|
||||
- **Name/Label**: Human-readable identifier for the key (e.g., "MES-Production", "RecipeManager-Dev").
|
||||
@@ -306,7 +330,7 @@ A standby now **relays** the request to the active peer instead (`InboundApiEndp
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Configuration Database (MS SQL)**: Stores API keys and method definitions.
|
||||
- **Configuration Database (MS SQL)**: Stores method definitions, and — under `Provider=SqlServer` — API keys in the `zbauth` schema (see *Key store provider* above). Under the `Sqlite` default, API keys live in a per-node SQLite file instead.
|
||||
- **Communication Layer**: Routes requests to sites when method implementations need site data.
|
||||
- **Security & Auth**: API key validation (separate from LDAP/AD — API uses key-based auth).
|
||||
- **Configuration Database (via IAuditService)**: All API key and method definition changes are audit logged.
|
||||
|
||||
Reference in New Issue
Block a user