Files
hiveops-guide/backend/src/main/resources/content/devices/agent-scripts/architect.md
T
johannes 930a4b968e feat(guide): dev audience tier + GUIDE_SERVED_AUDIENCES env cap (prod = customer,internal)
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>
2026-07-01 17:11:00 -04:00

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 (and RUN_SCRIPT); ScriptSigningService loads a PKCS8 RSA private key from script.signing.private-key (env SCRIPT_SIGNING_PRIVATE_KEY) and signs SHA256withRSA. Signed tasks flow through the standard fleet-task → agent-proxy path (executor→task-store pattern).
  • agent: com.hiveops.filemgmt.ProcessScriptUpdate requires scriptName, scriptContent (base64), scriptSignature; rejects unsigned scripts; verifies SHA256withRSA against an embedded public key; only writes files with .cmd/.sh/.ps1 extensions.

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.

  • [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.