e347286f28
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.
3.5 KiB
3.5 KiB
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 (noAddDataProtection/PersistKeysTo/ProtectKeysWith/SetApplicationNameanywhere), so the key ring falls back to the ASP.NET default. Not applied to any credential.
Config expansion today
- None. Stock
WebApplication.CreateBuilderchain (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)
- Highest value first: move the plaintext LDAP
ServiceAccountPasswordand the Galaxy connection-string password behind${secret:ldap/mxgateway/bind}/${secret:sql/mxgateway/galaxy}— pre-hostSecretReferenceExpanderbefore the existingGatewayOptionsValidatorruns. Delete the hardcoded plaintext defaults inLdapOptions. - 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. - 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. - UI: mount
/admin/secretsin the existing Blazor dashboard; map the gateway'sAdministratorrole ontosecrets:manage/secrets:reveal. - 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).