refactor(scum): declare protected run requests
This commit is contained in:
@@ -5,12 +5,13 @@ feature gate: no SCUM game, database, UE4SS build, or source revision controls
|
||||
plugin availability.
|
||||
|
||||
The Companion declares availability from its server-bound typed ports and
|
||||
runtime schema probes. Notification and fixed vehicle spawning can use a local
|
||||
typed transport, but callers never supply a command, socket, credential, path,
|
||||
or raw transport reply. Vehicle spawning creates only the private
|
||||
`#spawnvehicle <vehicleCode>` template from the plugin allowlist.
|
||||
runtime schema probes. Plugin-generated SQL, RCON, and management-program
|
||||
request text is declared through the protected Platform-to-Run transport, not
|
||||
executed by the Companion. Callers never receive a socket, credential, path,
|
||||
or raw transport reply. A management-program request is not host OS shell
|
||||
access.
|
||||
|
||||
Semantic events come from bounded Run stdout/stderr records. Unknown records
|
||||
create diagnostics and never produce fabricated events. Run database access is
|
||||
limited to typed allowlisted projections and safe mutations; DSNs, rows, SQL,
|
||||
and credentials do not leave Run.
|
||||
Semantic events come from bounded Run stdout/stderr console records. Unknown
|
||||
records create diagnostics and never produce fabricated events. DSNs, rows,
|
||||
connections, and credentials do not leave Run; request text is protected and
|
||||
redacted from browser and audit projections.
|
||||
|
||||
@@ -68,7 +68,7 @@ func TestRuntimeAdapterUsesOnlyLogicalConfigValuesAndRedactsDiagnostics(t *testi
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionedUE4SSNotificationIsFixedTypedAndRedacted(t *testing.T) {
|
||||
func TestUE4SSNotificationIsTypedAndRedacted(t *testing.T) {
|
||||
port := ¬ificationPortFixture{accepted: true}
|
||||
adapter := RuntimeAdapter{BoundServerID: "server-1", Notification: port}
|
||||
result, err := adapter.NotifyPlayer(context.Background(), map[string]any{"playerId": "76561198000000001", "message": "Moon \"gift\""})
|
||||
|
||||
@@ -10,7 +10,8 @@ import (
|
||||
)
|
||||
|
||||
// SafeAdapter is intentionally narrow: it receives typed values only and has
|
||||
// no raw RCON, SQL, host-path, credential, or shell access.
|
||||
// no direct transport, host-path, credential, or shell access. Protected SQL,
|
||||
// RCON, and management-program text is forwarded to Run by Platform, not here.
|
||||
type SafeAdapter interface {
|
||||
ReadConfiguration(context.Context) (map[string]any, error)
|
||||
PatchConfiguration(context.Context, map[string]any) (map[string]any, error)
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
"remote.run.process.start",
|
||||
"remote.run.process.stop",
|
||||
"remote.run.logs.transfer",
|
||||
"remote.run.protected.sql",
|
||||
"remote.run.protected.rcon",
|
||||
"remote.run.program.command",
|
||||
"client-manager.deploy",
|
||||
"client-manager.control",
|
||||
"client-manager.update",
|
||||
@@ -67,7 +70,10 @@
|
||||
"remote.run.files.write",
|
||||
"remote.run.process.start",
|
||||
"remote.run.process.stop",
|
||||
"remote.run.logs.transfer"
|
||||
"remote.run.logs.transfer",
|
||||
"remote.run.protected.sql",
|
||||
"remote.run.protected.rcon",
|
||||
"remote.run.program.command"
|
||||
],
|
||||
"logTransfer": true
|
||||
},
|
||||
@@ -190,6 +196,39 @@
|
||||
"resultSchemaRef": "schemas/bridge/game-state-patch.result.schema.json",
|
||||
"timeoutSeconds": 120,
|
||||
"maxPayloadBytes": 4096
|
||||
},
|
||||
{
|
||||
"type": "database.request",
|
||||
"title": "Execute approved SCUM database request",
|
||||
"permission": "server.game-client.maintenance",
|
||||
"approvalLevel": "platform-admin",
|
||||
"payloadSchemaRef": "schemas/bridge/protected-request.payload.schema.json",
|
||||
"resultSchemaRef": "schemas/bridge/protected-request.result.schema.json",
|
||||
"timeoutSeconds": 120,
|
||||
"maxPayloadBytes": 16384,
|
||||
"protectedRequest": { "kind": "sql", "transportKey": "scum-database", "targetKey": "scum-database", "textField": "requestText", "maxTextBytes": 16384 }
|
||||
},
|
||||
{
|
||||
"type": "management.rcon.request",
|
||||
"title": "Execute approved SCUM management command",
|
||||
"permission": "server.game-client.command",
|
||||
"approvalLevel": "operator",
|
||||
"payloadSchemaRef": "schemas/bridge/protected-request.payload.schema.json",
|
||||
"resultSchemaRef": "schemas/bridge/protected-request.result.schema.json",
|
||||
"timeoutSeconds": 120,
|
||||
"maxPayloadBytes": 8192,
|
||||
"protectedRequest": { "kind": "rcon", "transportKey": "scum-management", "targetKey": "scum-management", "textField": "requestText", "maxTextBytes": 8192 }
|
||||
},
|
||||
{
|
||||
"type": "management.program.request",
|
||||
"title": "Execute approved SCUM management program request",
|
||||
"permission": "server.game-client.maintenance",
|
||||
"approvalLevel": "platform-admin",
|
||||
"payloadSchemaRef": "schemas/bridge/protected-request.payload.schema.json",
|
||||
"resultSchemaRef": "schemas/bridge/protected-request.result.schema.json",
|
||||
"timeoutSeconds": 120,
|
||||
"maxPayloadBytes": 8192,
|
||||
"protectedRequest": { "kind": "program", "transportKey": "scum-program", "targetKey": "scum-program", "textField": "requestText", "maxTextBytes": 8192 }
|
||||
}
|
||||
],
|
||||
"snapshots": [
|
||||
@@ -271,7 +310,10 @@
|
||||
"vehicle.spawn",
|
||||
"event.start",
|
||||
"restart.prepare",
|
||||
"maintenance.prepare"
|
||||
"maintenance.prepare",
|
||||
"database.request",
|
||||
"management.rcon.request",
|
||||
"management.program.request"
|
||||
],
|
||||
"snapshotTypes": ["companion.health", "online.sessions", "players", "squads", "vehicles", "flags"],
|
||||
"featureKeys": ["config.manage", "player.intelligence", "reward.delivery", "state.patch", "vehicle.spawn", "trajectory.collect"]
|
||||
@@ -482,7 +524,6 @@
|
||||
],
|
||||
"discoveryMarkers": [
|
||||
{ "key": "scum-executable", "kind": "file.exists", "targetKey": "scum/server-executable", "required": true },
|
||||
{ "key": "scum-version", "kind": "command.version", "targetKey": "scum/server-executable", "required": true },
|
||||
{ "key": "scum-steam-app", "kind": "steam.app", "targetKey": "server/install-root", "expected": "3792580", "required": true },
|
||||
{ "key": "scum-config", "kind": "file.exists", "targetKey": "scum/server-settings", "expected": "ServerSettings.ini", "required": true },
|
||||
{ "key": "scum-game-port", "kind": "port.open", "targetKey": "game-port", "required": true },
|
||||
@@ -490,7 +531,6 @@
|
||||
],
|
||||
"verificationChecks": [
|
||||
{ "key": "executable", "kind": "executable.present", "targetKey": "scum/server-executable", "required": true },
|
||||
{ "key": "version", "kind": "version.matches", "targetKey": "scum/server-executable", "required": true },
|
||||
{ "key": "game-port", "kind": "port.bound", "targetKey": "game-port", "required": true },
|
||||
{ "key": "config", "kind": "config.readable", "targetKey": "scum/server-settings", "required": true },
|
||||
{ "key": "process", "kind": "process.healthy", "targetKey": "scum/server-executable", "required": true }
|
||||
@@ -498,6 +538,22 @@
|
||||
}
|
||||
],
|
||||
"logSources": [
|
||||
{
|
||||
"key": "scum-console-stdout",
|
||||
"kind": "process.stdout",
|
||||
"targetKey": "scum/server-process",
|
||||
"streamKey": "scum.console.stdout",
|
||||
"cursorKind": "sequence",
|
||||
"retentionDays": 30
|
||||
},
|
||||
{
|
||||
"key": "scum-console-stderr",
|
||||
"kind": "process.stderr",
|
||||
"targetKey": "scum/server-process",
|
||||
"streamKey": "scum.console.stderr",
|
||||
"cursorKind": "sequence",
|
||||
"retentionDays": 30
|
||||
},
|
||||
{
|
||||
"key": "scum-chat-events",
|
||||
"kind": "file.tail",
|
||||
@@ -686,6 +742,24 @@
|
||||
"remote.rsync.read",
|
||||
"remote.rsync.write"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "scum-database",
|
||||
"kind": "sqlite",
|
||||
"targetKey": "scum-database",
|
||||
"capabilities": ["remote.run.protected.sql"]
|
||||
},
|
||||
{
|
||||
"key": "scum-management",
|
||||
"kind": "rcon",
|
||||
"targetKey": "scum-management",
|
||||
"capabilities": ["remote.run.protected.rcon"]
|
||||
},
|
||||
{
|
||||
"key": "scum-program",
|
||||
"kind": "program",
|
||||
"targetKey": "scum-program",
|
||||
"capabilities": ["remote.run.program.command"]
|
||||
}
|
||||
],
|
||||
"clientManagers": [
|
||||
@@ -742,10 +816,6 @@
|
||||
"offlineAfterSeconds": 120,
|
||||
"requiredCapabilities": ["component.register", "component.heartbeat", "component.health", "component.control", "game-client.bridge", "logs.stream"]
|
||||
},
|
||||
"compatibility": {
|
||||
"minimumVersion": "1.0.0",
|
||||
"allowDowngrade": false
|
||||
},
|
||||
"updatePolicy": {
|
||||
"strategy": "manual-staged",
|
||||
"requireApproval": true,
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["requestText"],
|
||||
"properties": { "requestText": { "type": "string", "minLength": 1, "maxLength": 16384 } }
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["outcome"],
|
||||
"properties": { "outcome": { "enum": ["succeeded", "failed", "unknown"] }, "diagnostic": { "type": "string", "maxLength": 512 } }
|
||||
}
|
||||
Reference in New Issue
Block a user