HarperFast / HarperFast/harper
operationsApi.network.mtls and mtls_required are unregistered config params — client-cert verification can never be enabled on the ops/replication ports
- Dominant language
- JavaScript
- Stars
- 89
- Forks
- 10
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 200
Description
## Summary
`operationsApi.network.mtls` and `operationsApi.network.mtls_required` are read by the server but are **not registered config parameters**, so they resolve to `undefined` no matter how they are set. The operations and replication listeners therefore can never be configured to request or require client certificates — `requestCert` stays false and `rejectUnauthorized` stays false on those ports.
This is not just the env-var path: the value is unreachable via environment variable, via `harper-config.yaml` / `harperdb-config.yaml`, and via `set_configuration` alike.
## Mechanism
The read site builds the parameter name dynamically from the server prefix:
```js
// v5 main — server/http.ts:595-596
const mtls = env.get(serverPrefix + '_mtls');
const mtlsRequired = env.get(serverPrefix + '_mtls_required');
```
…and the result feeds `requestCert` / `rejectUnauthorized` (`server/http.ts:610-611`) and `server.verifiesClientCerts` (`:816`).
But `env.get` is gated on the registry:
```js
// config/configUtils.ts:282-297
const paramMap = CONFIG_PARAM_MAP[param.toLowerCase()];
if (paramMap === undefined) return undefined;
return flatConfigObj[paramMap.toLowerCase()];
```
`CONFIG_PARAM_MAP` is built solely from the static `CONFIG_PARAMS` registry plus manual aliases (`utility/hdbTerms.ts:661-735`). The `OPERATIONSAPI_NETWORK_*` block (`utility/hdbTerms.ts:576-592`) registers CORS, CORSACCESSLIST, HEADERSTIMEOUT, HTTPS, KEEPALIVETIMEOUT, PORT, DOMAINSOCKET, SECUREPORT, HTTP2, MAXREQUESTBODYSIZE, TIMEOUT — **there is no `OPERATIONSAPI_NETWORK_MTLS` or `_MTLS_REQUIRED` entry**, and none of the aliases map to one. By contrast `HTTP_MTLS` (`:533`) and `MQTT_NETWORK_MTLS` (`:707`) are both registered.
`environmentManager.get()`'s fallback does not rescue it either — `installProps` is populated only from the boot-properties file, never by matching arbitrary environment keys to parameter names.
And environment variables only ever enter config for names already in the map:
```js
// bin/run.js:100 (also bin/restart.js:75)
const parsed_args = assignCMDENVVariables(Object.keys(terms.CONFIG_PARAM_MAP), true);
```
so an unregistered name is never ingested from the environment at all.
Consistent with the above, `validation/configValidator.ts:286-296` (the `operationsApi.network` Joi schema) and `static/defaultConfig.yaml:62-69` both omit `mtls`, while the equivalent `http` and `mqtt.network` blocks declare it. `set_configuration` also refuses to write an unregistered parameter (`config/configUtils.ts:757-765`, "unrecognized config parameter").
There is a second dead end worth noting: `flattenConfig` (`config/configUtils.ts:884-886`) *does* compute a merged `operationsapi_network_mtls` key in `flatConfigObj` (inheriting `http.mtls` when unset), but the `CONFIG_PARAM_MAP` gate above means that computed value can never be read back through `env.get()`. It is dead data.
## Impact
An operator who sets `operationsApi.network.mtls: true` (or the corresponding env var) to require client certificates on the operations/replication ports gets **no error and no effect**. The setting appears accepted; client-certificate verification is simply never enabled. A hand-edited YAML entry is the worst case — it shows up in `get_configuration` output, so it reads as applied config while remaining functionally inert.
This is a hardening control being silently unavailable rather than an authentication bypass — request authentication still applies — but it means "we require mTLS on the operations API" cannot currently be made true by configuration.
## Versions
Present in **v5 `main`** and in **v4** (verified at tag `release_4.5.36`): `getConfigValue` and `environmentManager.get()` are logically identical there, `hdbTerms` likewise registers only `HTTP_MTLS*`/`MQTT_NETWORK_MTLS*`, and the read site is `server/threads/threadServer.js:433`. v4 has no `server/http.ts`, but the root cause — the missing `CONFIG_PARAMS` entry plus the `CONFIG_PARAM_MAP` gate — predates v5 and is unchanged.
## Expected
Either register `OPERATIONSAPI_NETWORK_MTLS` / `_MTLS_REQUIRED` in `CONFIG_PARAMS` (and add them to the Joi schema and default config, matching the `http` block), or reject/warn on the unrecognized key at load so it cannot silently read as applied.
## Related
`harper-pro#734` — same failure class (`env.get` resolves only names registered in `CONFIG_PARAMS`, so config values are silently ignored and the compiled-in default always wins), different subsystem. Worth fixing together, and worth a general sweep for other read sites that build parameter names dynamically.
Contributor guide
Research direction
Start with the OPERATIONSAPI_NETWORK_* entries in utility/hdbTerms.ts, then compare validation/configValidator.ts, static/defaultConfig.yaml, config/configUtils.ts, and the server/http.ts read site. Done means both mTLS settings are recognized and validated, and values supplied through environment variables, YAML, or set_configuration reach requestCert, rejectUnauthorized, and server.verifiesClientCerts.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- api, backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100