🚧 Add topic explorer

This commit is contained in:
Jonas Bengtsson
2026-09-20 09:23:04 +02:00
parent 1e491642f1
commit 6385a27411
11 changed files with 1184 additions and 6 deletions
+42 -2
View File
@@ -81,9 +81,48 @@ async def lifespan(app: FastAPI):
logger.info("sys-observe role granted to the management identity")
except Exception as exc: # noqa: BLE001
logger.warning("could not grant sys-observe: %s", exc)
# The topic explorer (spec section 35) publishes and subscribes
# to APPLICATION topics as the management identity. The 2.1
# auto-generated admin role set does NOT include publish/subscribe
# on # (deliberately: "the admin user does not have access to
# publish to normal application topics"). A dedicated role keeps
# the grant explicit and auditable; publishes through the
# explorer remain audited as TOPIC_PUBLISHED (spec section 35).
from app.dynsec import DynsecError
try:
try:
dynsec_client.create_role(
"topic-explorer",
acls=[
{
"acltype": "publishClientSend",
"topic": "#",
"allow": True,
"priority": 0,
},
{
"acltype": "subscribePattern",
"topic": "#",
"allow": True,
"priority": 0,
},
],
)
except DynsecError:
pass # role already exists (idempotent startup)
dynsec_client.add_client_role(
settings.mosquitto_dynsec_username, "topic-explorer", priority=1
)
logger.info("topic-explorer role granted to the management identity")
except Exception as exc: # noqa: BLE001
logger.warning("could not grant topic-explorer: %s", exc)
except Exception as exc: # noqa: BLE001 - startup should not crash the API
logger.warning("dynsec channel not ready yet: %s", exc)
yield
from app import explorer
explorer.sessions.stop_all()
dynsec_client.close()
@@ -140,11 +179,12 @@ def health_ready():
# Routers
from app.routers import auth, broker, mqtt, pki, system, users # noqa: E402
from app.routers import auth, broker, mqtt, pki, system, topics, users # noqa: E402
app.include_router(auth.router)
app.include_router(users.router)
app.include_router(mqtt.router)
app.include_router(broker.router)
app.include_router(pki.router)
app.include_router(system.router)
app.include_router(system.router)
app.include_router(topics.router)