4-tier ladder customer<internal<dev<bcos. Re-tagged Architect/Testing/Claude + platform/technical from internal->dev; Processes stays bcos. Backend visible() enforces a per-instance served-audiences cap at the API. bcos.dev/DLX serve all; production sets GUIDE_SERVED_AUDIENCES=customer,internal so dev/bcos never leave dev. Verified: capped instance returns only Customer+Internal, 404s dev/bcos. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.3 KiB
module, title, tab, order, audience
| module | title | tab | order | audience |
|---|---|---|---|---|
| devices.agent-scripts | Agent Scripts | Architect | 30 | dev |
Architect · internal. Written 2026-07-01 from source. Describes both what is built (a devices-owned CRUD store) and the intended signed-delivery pipeline that partly exists in hiveops-fleet + the agent but is not yet connected to this module's Push action.
Ownership & shape
devices.agent-scripts is a thin CRUD feature fully owned by hiveops-devices (Spring Boot, port 8096, DB hiveiq_devices). No Kafka topics, no consumers, no cross-service calls, no agent contact originate from this module. See [platform.service-ownership].
Devices SPA (AgentScripts.svelte, Settings)
│ agentScriptAPI → devicesApi (baseURL = window.__APP_CONFIG__.apiUrl, e.g. api.bcos.cloud/devices)
▼
hiveops-devices : AgentScriptController (/api/fleet/scripts)
▼
AgentScriptService → AgentScriptRepository (JPA)
▼
Postgres hiveiq_devices : agent_scripts
Components (hiveops-devices)
| Layer | Class |
|---|---|
| Controller | com.hiveops.devices.controller.AgentScriptController (@RequestMapping("/api/fleet/scripts")) |
| Service | com.hiveops.devices.service.AgentScriptService (@Transactional) |
| Repository | com.hiveops.devices.repository.AgentScriptRepository extends JpaRepository<AgentScript, Long> |
| Entity | com.hiveops.devices.entity.AgentScript (@Table("agent_scripts")) |
| DTO | com.hiveops.devices.dto.AgentScriptRequest (name, description, content, institutionKey) |
Data — agent_scripts (Flyway V15__create_agent_scripts.sql)
| Column | Type | Notes |
|---|---|---|
id |
BIGSERIAL PK | GenerationType.IDENTITY |
name |
VARCHAR(200) NOT NULL | file name; extension implies type |
description |
TEXT | nullable |
content |
TEXT NOT NULL | raw script body |
institution_key |
VARCHAR(50) | nullable; indexed (idx_agent_scripts_institution_key) |
created_at |
TIMESTAMPTZ | @CreationTimestamp / DEFAULT now() |
updated_at |
TIMESTAMPTZ | @UpdateTimestamp / DEFAULT now() |
Repository queries: findAllByOrderByNameAsc() and findByInstitutionKeyOrderByNameAsc(String). This is the only persistence — no mirror tables, no device_summary involvement. See [platform.data-architecture].
API surface
| Method + Path | Behaviour |
|---|---|
GET /api/fleet/scripts?institutionKey= |
Lists all, or filtered by institution key. |
POST /api/fleet/scripts |
400 if name/content blank; else 201 with saved entity. Sets institutionKey from body. |
PUT /api/fleet/scripts/{id} |
404 if missing; updates name (if non-blank), description, content. |
DELETE /api/fleet/scripts/{id} |
404 if missing; else 204. |
POST /api/fleet/scripts/{id}/push |
Stub — returns 200 with List.of(). Comment in code: "requires fleet service integration (not yet implemented)". |
All gated by @PreAuthorize("hasAnyRole('MSP_ADMIN','BCOS_ADMIN')") at class level.
Kafka
None for this module. It neither produces nor consumes. (The devices service overall publishes hiveops.device.events for device inventory, but agent-scripts writes never touch that path.) See [platform.kafka].
Intended signed-delivery pipeline (NOT wired to this module)
The Overview/SPA copy promises "signed server-side with RSA-SHA256, agent verifies before writing" and "SCRIPT_UPDATE fleet tasks." That machinery exists — but in hiveops-fleet and the agent, not behind the devices Push endpoint:
(intended) devices push ──X──▶ hiveops-fleet FleetTaskService (kind = UPDATE_SCRIPT)
│ ScriptSigningService.sign(scriptBytes) [SHA256withRSA, private key]
▼ configPatch += signature
fleet_tasks ──▶ agent-proxy ──▶ ATM agent
│
hiveops-agent hiveops-file-collection ProcessScriptUpdate
verifySignature(...) [SHA256withRSA public key] ──▶ writes to scripts dir
- hiveops-fleet:
FleetTaskKind.UPDATE_SCRIPT(andRUN_SCRIPT);ScriptSigningServiceloads a PKCS8 RSA private key fromscript.signing.private-key(envSCRIPT_SIGNING_PRIVATE_KEY) and signsSHA256withRSA. Signed tasks flow through the standard fleet-task → agent-proxy path (executor→task-store pattern). - agent:
com.hiveops.filemgmt.ProcessScriptUpdaterequiresscriptName,scriptContent(base64),scriptSignature; rejects unsigned scripts; verifiesSHA256withRSAagainst an embedded public key; only writes files with.cmd/.sh/.ps1extensions.
The gap: the devices push endpoint is a no-op stub and never calls hiveops-fleet, so nothing in this module actually creates a task or signs anything today. There is also a config-patch key mismatch between the fleet signer and the agent consumer (see Claude tab / uncertainties) that would need reconciling if the two are ever wired together.
Cross-links
- [platform.data-architecture] — where device-domain data lives.
- [platform.kafka] — device event bus (not used by this module).
- [platform.service-ownership] — devices owns
agent_scripts; fleet owns task delivery + signing.