Skip to content

feat(#45): pass the HA fallback root password as an env var, not -D - #55

Merged
robfrank merged 1 commit into
mainfrom
feat/45-ha-fallback-root-password-env
Oct 22, 2026
Merged

robfrank merged 1 commit into
mainfrom
feat/45-ha-fallback-root-password-env

Conversation

@robfrank

@robfrank robfrank commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Closes #45

In HA mode on an image older than 26.11.1 with no explicit arcadedb.credentials.clusterToken (i.e. a user-supplied root password Secret), the chart still rendered -Darcadedb.server.rootPassword=$(rootPassword), which Kubernetes expands into the argument, so the password was readable through /proc/<pid>/cmdline. This PR drops that flag and exports the setting as an environment variable named after its key, arcadedb.server.rootPassword (a secretKeyRef to the root password Secret), the same way #41 does for the TLS store passwords. The env var is rendered only on that fallback branch; every other configuration keeps using -Darcadedb.server.rootPasswordPath and gets no new env var. The config-key drift guard (ci/check-config-keys.sh) now also checks arcadedb.* env var names, so the fallback render keeps covering arcadedb.server.rootPassword, and the #41 TLS env names are now covered as well.

Proof the issue asked for (pre-26.11.1 derives the token from the setting value, not System.getProperty)

Source, ArcadeDB tag 26.10.2 (the chart's appVersion):

  • GlobalConfiguration.readConfiguration(): prop = System.getProperty(config.key); if (prop == null) prop = System.getenv(config.key);. The same fallback exists at tags 24.11.1, 25.6.1, 26.1.1, 26.7.1 and 26.10.2 (git show <tag>:engine/.../GlobalConfiguration.java | grep -c "System.getenv(config.key)" returns 1 for each).
  • ha-raft/.../ClusterTokenProvider.initClusterToken() (26.5.1, 26.7.1, 26.10.2): configuration.getValueAsString(GlobalConfiguration.SERVER_ROOT_PASSWORD), then falls back to GlobalConfiguration.SERVER_ROOT_PASSWORD.getValueAsString(). git grep 'getProperty("arcadedb.server.rootPassword' over 26.7.1 and 26.10.2 main sources returns nothing.

Live kind run (local, kind single node, image.tag=26.10.2, replicaCount=3, user-supplied Secret my-root/pw, no cluster token):

  • 3/3 pods Ready; all three report the same Raft leader.
  • /proc/1/cmdline on pod-0 has no rootPassword flag and does not contain the password.
  • Pod env has arcadedb.server.rootPassword; the startup dump lists arcadedb.server.rootPassword = <hidden>.
  • Each node logs Using auto-derived cluster token (no explicit token, derived from the env-sourced setting).
  • Root login with the Secret's password succeeds on every pod; create database, create document type and an insert sent to a follower return 200, and the row is read back from the third pod.

Test plan

  • helm unittest charts/arcadedb: 347/347 pass. Against the old template, 6 fail (the 4 new fallback tests and the 2 updated ones).
  • helm lint charts/arcadedb
  • bash ci/check-config-keys.sh against arcadedata/arcadedb:26.10.2: OK, 42 keys (now including arcadedb.server.rootPassword, arcadedb.ssl.keyStorePassword, arcadedb.ssl.trustStorePassword as env names)
  • Local kind HA run on 26.10.2 in the fallback configuration (see above)
  • CI CI - Lint, Unit Tests, Integration Tests on 0b14dc0: success (the integration job exercises the file branch only; see Known gaps)

Existing tests changed: two existing tests asserted contains -Darcadedb.server.rootPassword=$(rootPassword), which is the behaviour this issue removes: "HA with a user-supplied root password Secret and no token ..." and "a non-version tag falls back to ...". Their assertions were flipped to notContains plus a check for the env var, and their titles reworded. Each has an # issue #45: was ... comment. No other existing test was touched.

Coverage

Invariant: no rendered container argument carries the root password; on the pre-26.11.1 HA fallback the server still receives arcadedb.server.rootPassword.

Sweep commands (run in the worktree after the change):

$ grep -rn '\$(' charts/arcadedb/templates
NOTES.txt:9,10,15,18,19   (shell snippets for the user, not container args)
_helpers.tpl:336          (comment)
statefulset.yaml:116      - -Darcadedb.server.name=$(HOSTNAME)
$ grep -rniE 'Darcadedb\.[a-zA-Z.]*(password|token)[a-zA-Z]*=' charts/arcadedb/templates
statefulset.yaml:119      - -Darcadedb.server.rootPasswordPath=...
statefulset.yaml:135      - -Darcadedb.ha.clusterTokenPath=...
Entry point to the fallback branch (rootPasswordFromFile false) Fixed Test
replicaCount>1, user Secret, pre-26.11.1 tag yes #45 the HA fallback renders no -D flag ... + updated existing test
replicaCount>1, user Secret, non-version tag (latest) yes updated a non-version tag falls back ...
autoscaling.enabled, user Secret, pre-26.11.1 yes #45 ... under autoscaling ...
native flavor, -native pre-26.11.1 tag yes #45 ... on a native image ...
helm upgrade --reuse-values (null clusterToken/mountPath) yes #45 ... after an upgrade with --reuse-values ...
File branches (single node, HA + mounted token, >=26.11.1) get no extra env var yes three #45 the root password setting env var is not set ... tests
arcadedb.extraCommands referencing $(rootPassword) argued user-authored args; the chart keeps the rootPassword env var for them, as documented in the README
Real server boots on the fallback branch live-checked locally not in CI, filed as #54

Known gaps

Residual risk: a future ArcadeDB release that drops the env var fallback in readConfiguration() would break the fallback branch. The drift guard does not catch that, because it checks only that the key exists. That release would also be ≥26.11.1, though, where the chart uses the file branch, so the risk is limited to pinned pre-26.11.1 images, and those do have the fallback.

Adversarial pass

Not run: this session had no subagent-spawning tool, so the independent Phase 1.5 reviewer could not be launched. The coverage sweep above and the bot review loop are the only checks.

Review cycles

Deferred items

None. No review feedback was received.

Final state: timeout (no bot reviewer on this repository). The PR needs a human review. Merging is the developer's call.

🤖 Generated with Claude Code

On a pre-26.11.1 image in HA mode without an explicit cluster token the
chart cannot use rootPasswordPath, and it put the password on the command
line as -Darcadedb.server.rootPassword=$(rootPassword). Export it instead as
an env var named after the setting key, which GlobalConfiguration reads
when no system property of that name is set; ClusterTokenProvider derives
the token from the setting value, whatever its source.

The config-key drift guard now also checks arcadedb.* env var names.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HA fallback on pre-26.11.1 images still passes the root password as -Darcadedb.server.rootPassword

1 participant