aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/config.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-15 02:34:19 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-15 02:34:19 +0200
commit84b032c65e17267d41e04605e79eea82a6f5a59f (patch)
treeeb7708a72944bb15540e103b4319242199af6fbb /packages/meshbay-node/src/meshbay_node/config.py
parent5338894f7fec9e1a60affb0e2ff3b9797bcbc968 (diff)
downloadmeshbay-84b032c65e17267d41e04605e79eea82a6f5a59f.tar.gz
feat(groups): editable description, and one source of operator authority
A description could only be set the moment a group was created, so every group made before anyone thought of one stayed blank for good. The owner can now edit it from the group's page, and PATCH /v1/groups/{id} takes it. That endpoint takes the description and nothing else, deliberately. The name, the visibility and the join policy are the terms members joined on; a private group that can quietly become public is not the group they agreed to be in. Changing those needs a decision about who gets told, not a field on a form — there is a test saying so. Separately, the legacy operator key is gone. `admin_pk_ed25519` in node.toml named the operator before the roster existed and was kept so that an existing deployment would keep working; nothing uses it, and a second source of node authority is not something to carry around out of politeness. Authority is the roster, read fresh on every check. It is removed rather than ignored: a config that still names the key gets a warning at startup pointing at the file. Dropping it in silence would refuse invites and file deletion with a signature error that looks like a bug somewhere else — which is exactly how finding M3 presented. Two tests were verifying admin operations by naming a key in the context, which was the legacy path. They now pair an operator into a roster, the way an operator does. The authority test anchored on the deleted function and passed vacuously once it disappeared; it states the invariant against the verifier and the daemon instead. Also defined .btn-secondary, used in four places and styled in none. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/config.py')
-rw-r--r--packages/meshbay-node/src/meshbay_node/config.py19
1 files changed, 13 insertions, 6 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/config.py b/packages/meshbay-node/src/meshbay_node/config.py
index f3752ea..e4444d3 100644
--- a/packages/meshbay-node/src/meshbay_node/config.py
+++ b/packages/meshbay-node/src/meshbay_node/config.py
@@ -6,6 +6,7 @@ All values have sensible defaults and can be overridden by env vars
prefixed with MESHBAY_ (e.g. MESHBAY_HUB_URL).
"""
+import logging
import os
from dataclasses import dataclass, field
from pathlib import Path
@@ -15,6 +16,8 @@ try:
except ImportError:
import tomli as tomllib # type: ignore[no-redef]
+log = logging.getLogger(__name__)
+
DEFAULT_CONFIG_PATH = Path.home() / ".config" / "meshbay" / "node.toml"
EXAMPLE_CONFIG = """\
@@ -58,10 +61,9 @@ visibility = "public" # discoverable on the hub
# unlock_file = "~/.config/meshbay/unlock.key"
# or set MESHBAY_UNLOCK_KEY env var
-# Node sovereignty: pin the operator's Ed25519 public key (base64, 32 bytes raw).
-# Admin operations (file delete) require cryptographic proof of this key.
-# Auto-pinned on first startup from the node operator's keystore.
-# admin_pk_ed25519 = "base64-encoded-32-bytes"
+# Operator authority is not configured here. Run `meshbay-node operator pair` and
+# enter the code in your browser: the node pins that browser's key, and invites
+# and file deletion are signed with it.
"""
@@ -112,7 +114,6 @@ class Config:
groups: list[GroupConfig] = field(default_factory=list)
keystore: KeystoreConfig = field(default_factory=KeystoreConfig)
data_dir: Path = field(default_factory=lambda: Path.home() / ".local" / "share" / "meshbay")
- admin_pk_ed25519: str = "" # base64 raw Ed25519 public key pinned locally
# Back-compat: single-group access
@property
@@ -167,7 +168,13 @@ def load_config(path: Path = DEFAULT_CONFIG_PATH) -> Config:
cfg.data_dir = Path(raw["data_dir"]).expanduser().resolve()
if "admin_pk_ed25519" in raw:
- cfg.admin_pk_ed25519 = raw["admin_pk_ed25519"]
+ # Removed, not merely unused: a key named here granted operator
+ # authority, and dropping it silently would refuse invites and file
+ # deletion with a signature error that looks like something else.
+ log.warning(
+ "admin_pk_ed25519 in %s is ignored — operator authority now comes "
+ "from the roster. Run `meshbay-node operator pair` and delete the "
+ "line.", path)
ks = raw.get("keystore", {})
if "path" in ks: