Files
scadaproj/components/secrets/current-state/mxaccessgw/CURRENT-STATE.md
T
Joseph Doherty e347286f28 docs(components): normalize Secrets component + index the shared lib
Add components/secrets/ (SPEC, realized shared-contract, code-verified
current-state for OtOpcUa/mxaccessgw/ScadaBridge, GAPS adoption backlog) and
register the Secrets row in CLAUDE.md + components/README.md. The
ZB.MOM.WW.Secrets lib is built + published 0.1.2 + reference-consumer-proven
(HistorianGateway, live vs the wonder historian); per-app adoption is the
tracked follow-on.
2026-07-16 04:49:57 -04:00

47 lines
3.5 KiB
Markdown

# MxAccessGateway — secrets current state
Descriptive baseline (code-verified) of how `mxaccessgw` handles secrets **today**, before
adopting `ZB.MOM.WW.Secrets`. Paths are relative to `~/Desktop/MxAccessGateway`.
## Where each secret lives today
| Secret | Location today | At-rest protection |
|---|---|---|
| gRPC inbound API keys | Peppered HMAC-SHA256 hashes in SQLite `gateway-auth.db` (`MxGateway:Authentication:SqlitePath`, `…Server/appsettings.json:17`) via `ZB.MOM.WW.Auth.ApiKeys` (`…/Security/Authentication/AuthStoreServiceCollectionExtensions.cs:70`) | Hashed (not reversible); plaintext key never stored |
| API-key **pepper** | Read by config-key **name** `MxGateway:ApiKeyPepper`; value supplied out-of-band (env `MxGateway__ApiKeyPepper`), intentionally **not** in appsettings (`AuthStoreServiceCollectionExtensions.cs:36,54-55`) | Runtime-supplied; no dedicated env reader (default config binding); flagged open item SEC-10 |
| LDAP dashboard bind password | **Plaintext** `appsettings.json:29` `ServiceAccountPassword: "serviceaccount123"`; also a hardcoded default in `Configuration/LdapOptions.cs:61` | None |
| Galaxy-repository SQL connection string | **Plaintext** `appsettings.json:76` (currently `Integrated Security=True`, but the field is a raw connstr that would carry `Password=` in plaintext) | None (redacted for **display** only, `Dashboard/DashboardConnectionStringDisplay.cs:10-24`) |
| TLS PFX | Generated/persisted with a **null password**, ACL-protected on disk (`Security/Tls/SelfSignedCertificateProvider.cs:153,193`) | Filesystem ACL, no password |
| MXAccess/Wonderware creds | **Not stored** — pass-through runtime gRPC request payload forwarded to COM (`Worker/MxAccess/MxAccessCommandExecutor.cs:318-325`) | N/A |
## Encryption-at-rest today
- **None** for the secrets above. The only Data Protection use is short-lived SignalR hub
bearer tokens (`Dashboard/HubTokenService.cs:43-46`) — and Data Protection is **never
explicitly configured** (no `AddDataProtection`/`PersistKeysTo`/`ProtectKeysWith`/
`SetApplicationName` anywhere), so the key ring falls back to the ASP.NET default. Not
applied to any credential.
## Config expansion today
- **None.** Stock `WebApplication.CreateBuilder` chain (`GatewayApplication.cs:60`); no
`${...}` expansion, no custom config post-processing before options binding. Secrets are
read verbatim from resolved config values.
## Adoption plan (toward SPEC)
1. **Highest value first:** move the plaintext **LDAP `ServiceAccountPassword`** and the
**Galaxy connection-string password** behind `${secret:ldap/mxgateway/bind}` /
`${secret:sql/mxgateway/galaxy}` — pre-host `SecretReferenceExpander` before the existing
`GatewayOptionsValidator` runs. Delete the hardcoded plaintext defaults in `LdapOptions`.
2. **Pepper:** the pepper is already runtime-supplied by design — optionally source it via
`${secret:apikey-pepper/mxgateway}` to close SEC-10's "no dedicated env reader" gap while
keeping it out of appsettings.
3. **Master key:** env provider (`ZB_SECRETS_MASTER_KEY`) for the Windows/NSSM deployment,
or DPAPI provider (Windows box) if a machine-bound key is preferred.
4. **UI:** mount `/admin/secrets` in the existing Blazor dashboard; map the gateway's
`Administrator` role onto `secrets:manage`/`secrets:reveal`.
5. **Keep bespoke:** the peppered-HMAC API-key store (already best-practice — hashed, not
encrypted-reversible) and the ACL-protected passwordless TLS PFX stay as-is; MXAccess
pass-through creds are out of scope (never stored).