Skip to content

fix(env): a default install reaches the fleet — the live CA and members, written from public/ every build - #1026

Merged
cryptskii merged 2 commits into
mainfrom
fix/bundled-fleet-ca-and-config
Sep 27, 2026
Merged

cryptskii merged 2 commits into
mainfrom
fix/bundled-fleet-ca-and-config

Conversation

@cryptskii

Copy link
Copy Markdown
Collaborator

What

A default install now reaches the beta fleet with nothing pushed to the device. The APK bundles:

  • the fleet's CA;
  • the five live members, with their endpoints and register incarnations.

Every build now writes those two files from public/ and checks them byte for byte.

Why

Two separate defects kept a default install off the network.

  1. Stale bundled files.
    • dsm_client/frontend/public/ca.crt was a retired CA with the same subject (CN=DSM-Storage-CA) and a different key. MainActivity re-materializes it over files/ca.crt on every launch, so rustls refused every member's certificate, which surfaced as error sending request.
    • public/dsm_env_config.toml named the retired three-node Alibaba set with no register incarnations, which the loader refuses.
    • The 2026-09-27 device run only worked because I pushed an override config naming the CA under another file name.
  2. The build could package stale copies anyway. The two files reached the APK through public/ → webpack → dist/ → copy-to-android.js → the git-ignored Android assets.
    • One build on 2026-09-26 packaged dist/'s previous copy of both while public/ already held the new ones.
    • copy-to-android.js kept those two files across builds, and a comment called the ignored assets copy the "single source of truth", although every build overwrites it.

Change

  • frontend/public/ca.crt: the fleet's CA (sha256 8a8b36a6…), the issuer of every member's certificate.
  • frontend/public/dsm_env_config.toml: the five members, their endpoints, and their register incarnations as each logged them after the reprovision. custom_ca_certs names the bundled ca.crt.
  • android/app/src/main/dsm_env_config.toml is deleted. It was the dead six-node fleet of 2026-03-31, and nothing reads it.
  • copy-to-android.js rebuilds the assets directory with nothing carried over. It then writes both files straight from public/, after everything else, and exits non-zero unless each copy equals its source byte for byte.
  • validate-android-assets.js:
    • requires both files to be the tracked public/ copies;
    • now runs in build:full-deploy, so make android fails rather than package another CA;
    • drops its js/runtime/js/vendors requirements, which described the web build. The Android build emits one entry chunk, so the validator had failed on every Android build and ran nowhere.
  • StorageSetCatalog::from_env and canonical_set_in split the existing functions so the bundled file can be checked through the same parser, catalog and pinned-set resolution every read uses. parse_env_config_toml becomes pub(crate). No test-only seam is added.
  • The fast-deploy scripts no longer describe the bundled fleet as six nodes. MainActivity's comment no longer calls ca.crt the AWS nodes' CA.

Verified

  • New tests:
    • dsm_sdk::sdk::storage_set::tests::the_bundled_env_config_resolves_the_pinned_beta_set: the bundled pairs must re-derive Core's pinned set 7GBBB51D….
    • dsm_sdk::sdk::storage_node_sdk::tests::the_bundled_env_config_names_a_ca_the_storage_client_builds_from.
    • Mutation controls, each red, then restored byte-identical and green: a stale incarnation in the bundled config, and the custom_ca_certs line removed.
  • dsm_sdk sdk::storage_set, sdk::storage_node_sdk, network::tests: 18/0. make lint: exit 0.
  • Asset pipeline:
    • with the old CA and the Alibaba config planted in dist/, the copy step still wrote the tracked files;
    • a tampered assets ca.crt fails the validator;
    • make android with the webpack cache warm packaged CA 8a8b36a6… and the five-member config, with no retired node.
  • Proven on a real Android device: 9FF ran this build with its override config and pushed CA deleted, so only what the APK bundles was in play. It read the default config, trusted the bundled CA, and all five members answered over TLS (merged … from 5 of 5 members (Complete)). There were no transport errors and no "not resolvable".

Which CA issued the members' certificates is not decidable offline. The device run is what shows this CA verifies them.

…lt install reaches the network

A default install could not reach the beta fleet. The APK bundled
dsm_client/frontend/public/ca.crt, a retired CA with the same subject
(CN=DSM-Storage-CA) and a different key, and MainActivity re-materializes it
over files/ca.crt on every launch, so rustls refused every member's
certificate (UnknownIssuer, surfacing as "error sending request"). The
bundled dsm_env_config.toml named the retired three-node Alibaba set with no
register incarnations, which the loader refuses. Only a pushed developer
override, with the CA under another file name, made the 2026-09-27 device
run possible.

- frontend/public/ca.crt: the fleet's CA (the issuer of every member's
  certificate; sha256 8a8b36a6…).
- frontend/public/dsm_env_config.toml: the five members, their endpoints and
  their register incarnations as each logged at its first boot after the
  reprovision; custom_ca_certs names the bundled ca.crt.
- android/app/src/main/dsm_env_config.toml deleted: the dead six-node fleet
  of 2026-03-31, read by nothing.
- The fast-deploy scripts no longer describe the bundled fleet as six nodes.

The bundled file is now checked through the loader's own parser, the
catalog it builds and the canonical-set resolution every read uses:
the_bundled_env_config_resolves_the_pinned_beta_set refuses a pair that does
not re-derive core's pinned set, and
the_bundled_env_config_names_a_ca_the_storage_client_builds_from builds the
storage client from the CA the config names. Both went red under their
mutation (a stale incarnation; the CA line removed) and green restored.
Which CA issued the members' certificates is not decidable offline; the
device run against the fleet is what showed this CA verifies them.
…very build, checked byte for byte

The bundled dsm_env_config.toml and ca.crt reached the APK by a two-step
copy: webpack copied public/ into dist/, and copy-to-android.js copied dist/
into the git-ignored Android assets directory. A build on 2026-09-26
packaged dist/'s previous copy of both, the retired CA and the retired fleet,
while public/ already held the new ones. copy-to-android.js also kept those
two files across builds and carried a comment calling the ignored assets copy
the "single source of truth", which every build overwrites.

- copy-to-android.js regenerates the assets directory with nothing kept, then
  writes both files straight from public/, after everything else, and
  refuses to finish unless each copy equals its source byte for byte.
- validate-android-assets.js requires both files to be the tracked public/
  copies, and now runs in build:full-deploy, so make android fails rather than
  package another CA. Its js/runtime and js/vendors requirements described the
  web build; the Android build emits one entry chunk (splitChunks and
  runtimeChunk are off for it), so it failed on every Android build and ran
  nowhere.
- MainActivity's comment no longer calls ca.crt the AWS nodes' CA.

Checked: with the old CA and the Alibaba config planted in dist/, the copy
step still wrote the tracked files; a tampered assets ca.crt fails the
validator; make android with the webpack cache warm packaged CA 8a8b36a6…
and the five-member config.
@cryptskii
cryptskii merged commit ba2dc58 into main Sep 27, 2026
24 checks passed
@cryptskii
cryptskii deleted the fix/bundled-fleet-ca-and-config branch September 27, 2026 05:15
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.

1 participant