Skip to content

Replace organization-id with Scope through the broker data plane.#1241

Open
floitsch wants to merge 5 commits into
floitsch/build-artemis-service.s-new.050from
floitsch/build-artemis-service.s-new.060
Open

Replace organization-id with Scope through the broker data plane.#1241
floitsch wants to merge 5 commits into
floitsch/build-artemis-service.s-new.050from
floitsch/build-artemis-service.s-new.060

Conversation

@floitsch
Copy link
Copy Markdown
Member

@floitsch floitsch commented May 20, 2026

Completes the Scope penetration started in PRs #1239 (Scope type at
the BrokerCli boundary) and #1240 (fleet-file $schema + per-server
scope on disk). After this PR, the CLI says "scope" wherever it
operates on the broker data plane, and "organization-id" stays only in
auth-provider land.

Changes

Cache keys (broker data plane)

  • cache-key-pod-parts, cache-key-pod-manifest, and cache-key-patch
    now take --scope/Scope instead of --organization-id/Uuid.

Broker class

  • Broker.organization-id/Uuid field renamed to scope/Scope.
  • Constructor takes --scope/Scope.
  • The previous transitional scope getter that wrapped organization-id
    is gone — scope is now the canonical field.

FleetFile

  • FleetFile.organization-id/Uuid field replaced. The in-memory shape
    now mirrors the on-disk shape: each ServerConfig in servers
    carries its own scope. FleetFile.broker-scope is a derived getter
    returning servers[broker-name].scope.
  • An organization-id -> Uuid getter is kept as a derived view for
    auth-provider call sites that still deal in concrete org-ids.
  • The constructor and with drop the --broker-scope/--organization-id
    parameter.

Fleet

  • Fleet.organization-id/Uuid field renamed to broker-scope/Scope.
  • Same organization-id -> Uuid getter for auth-provider readers.
  • All internal Broker constructions pass --scope=broker-scope.

ServerConfig

  • Gains an optional scope/Scope? field. from-json reads it,
    to-json emits it when non-null.
  • ServerConfigHttp.to-service-json strips it (devices never see scope).
  • scope is moved from src/cli/scope.toit to src/shared/scope.toit
    so ServerConfig (in shared/) can hold one.

fleet.toit reader/writer

  • Reader stops manually stripping scope from each server entry —
    ServerConfig.from-json handles it.
  • Writer stops manually adding scope to each server entry —
    ServerConfig.to-json handles it.
  • Legacy-format reader path pins the top-level organization onto the
    broker server's scope post-construction so the in-memory shape is
    consistent across both on-disk formats.

Compatibility

  • Wire protocol unchanged. Old and new CLIs continue to talk to
    Supabase the same way.
  • On-disk fleet.json shape unchanged from Add $schema versioning to fleet.json; carry scope per server entry. #1240 — the per-server
    scope field is still where it landed there. This PR just cleans up
    the in-memory layer.
  • The CLI commands that read fleet.organization-id keep working
    unchanged via the new derived getter — they're auth-provider calls
    that deal in concrete org-ids.

Known wart

FleetFile.init() mutates the broker-config's scope before adding it
to the servers map. The broker-config can come from the global CLI
config, and mutation in this position leaks scope into in-memory state.
A follow-up will add with-scope clone methods on the ServerConfig
subclasses and switch init() to use them. TODO comment in place.

Tests

  • make test — 82/82 passed (rerun pending after the second commit)
  • make test-supabase — 32/32 passed on first commit; rerun pending

floitsch added 5 commits May 20, 2026 22:02
Completes the Scope penetration started in PRs …040 and …050:

- src/cli/cache.toit: cache-key-pod-parts, cache-key-pod-manifest, and
  cache-key-patch now take --scope/Scope instead of --organization-id/Uuid.
- src/cli/broker.toit: Broker.organization-id field renamed to scope/Scope.
  Constructor takes --scope/Scope. All internal callers updated. The
  previous 'scope' getter that wrapped organization-id is gone — scope
  is the canonical field.
- src/cli/fleet.toit:
  - FleetFile.organization-id field renamed to broker-scope/Scope.
    Constructor and 'with' updated accordingly. An organization-id getter
    is kept as a derived view for auth-provider call sites.
  - Fleet.organization-id field renamed to broker-scope/Scope. Same
    organization-id getter on the read side.
  - Broker constructor sites pass --scope=broker-scope.

The CLI commands in src/cli/cmds/ that read fleet.organization-id keep
working unchanged via the getter — those are auth-provider calls that
deal in concrete org-ids.

Wire protocol, on-disk format, and the auth-provider API are untouched.
Pulls the per-server scope into the in-memory ServerConfig type, so the
on-disk shape (each server entry carries its scope) is mirrored faithfully
in memory.

Changes:

- src/cli/scope.toit moves to src/shared/scope.toit so ServerConfig (in
  shared/) can hold one. The device-side code now references the Scope
  type transitively via ServerConfig, but never uses it.
- ServerConfig gains an optional scope/Scope? field; from-json reads it,
  to-json emits it when non-null. ServerConfigHttp.to-service-json strips
  it before sending the config to the device.
- fleet.toit's FleetFile reader stops manually stripping scope from each
  server entry — ServerConfig.from-json handles it. The legacy-format
  path attaches the top-level organization-id to the broker server's
  scope so the in-memory shape is consistent across formats.
- fleet.toit's FleetFile writer stops manually adding scope to each
  server entry — ServerConfig.to-json emits it.
- FleetFile.broker-scope is no longer a stored field; it's a getter that
  returns servers[broker-name].scope. The constructor and 'with' both
  drop the --broker-scope parameter.
- FleetFile.init() sets scope on the broker-config before adding it to
  the servers map.

TODO: avoid the mutation in init(). The broker-config can come from the
global CLI config, and mutating it leaks scope into in-memory state.
Adding a 'with-scope' clone method to each ServerConfig subclass would
fix this cleanly; queued for a follow-up.
Now that ServerConfig itself carries the scope, the Broker class doesn't
need its own field/getter — it's just indirection. Internal call sites
read server-config.scope directly.

Also tightens the FleetFile reader's legacy-format path to attach scope
to every server entry (not just the broker's), so migrating-from
brokers and the very-legacy no-broker-entry fallback are consistent in
memory. Both still mutate broker configs in place; same TODO as init()
about cloning with-scope as the proper fix.
Cache keys already receive --broker-config, and ServerConfig carries
its scope. The --scope parameter was redundant: every call site passed
broker-config.scope as the scope. Now the cache-key functions just
read it off broker-config themselves.

No call sites remain that pass both broker-config and a separate scope.
BrokerCli methods still take --scope directly (they don't receive a
broker-config, and some upload sites use the device's scope rather than
the broker's).
migration-start receives a ServerConfig from the global CLI config,
which never carries a scope. Without setting scope on it, the new
broker entry would be written to fleet.json without a scope field, and
subsequent reads would trip the strict per-server scope check.

Same pattern (and same TODO) as init() and the legacy-format reader:
mutate the broker config in place; the proper fix is to add a
'with-scope' clone on each ServerConfig subclass and use it here.
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