feat: ship single-file run distribution and list key reset
Compile-time run auth replaces zip sidecars, lengthens run keys, revokes active sessions on reset, and exposes run-key reset in the server list.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
## Context
|
||||
|
||||
The existing distribution pipeline already queues real `distribution.build` jobs and keeps raw component keys out of platform APIs. The weak point is the generated package shape: Run artifacts still contain `config.json`, which makes accidental token disclosure easy when a ZIP is shared or inspected. The operator expectation is also a single `run.exe` on Windows, not an archive.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Produce Windows Run downloads as `run-windows-amd64.exe` and Linux Run downloads as raw executable files such as `run-linux-amd64`.
|
||||
- Compile server identity and the current Run key into the Run binary using Go native `-ldflags -X`.
|
||||
- Keep `RUN_PLATFORM_URL` and other explicit environment overrides working for local development and diagnostics.
|
||||
- Support raw-executable Run self-update artifacts with checksum verification and the existing staging/rollback flow.
|
||||
- Make run-key reset reachable from the server list while preserving the compact action popover.
|
||||
- Immediately revoke an online Run control session after its key is reset.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Do not add device authorization, enrollment binding, or a token exchange ceremony.
|
||||
- Do not claim compile-time embedded tokens are unrecoverable from the executable; possession of the executable remains a trust boundary.
|
||||
- Do not change Client Manager packaging or plugin-declared client-manager build semantics.
|
||||
- Do not modify billing, cloud host sales, AI provider, plugin marketplace, or unrelated server workflows.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: Compile-time Run identity is a build-input contract
|
||||
|
||||
Platform extends authenticated distribution build input with the public Run platform URL and the existing identity fields. The trusted Run worker passes those values to `go build -ldflags -X browser.local/run/config.<Var>=<value>`. Run config loading prefers explicit environment variables, then compile-time build values, then developer defaults.
|
||||
|
||||
This uses the Go-native mechanism the user requested. It avoids `go:embed`, generated source files, temporary code rewrites, or sidecar config files for Run. The compile-time value is still recoverable by someone holding the binary, but it removes the casual ZIP/config leak.
|
||||
|
||||
### Decision 2: Raw executable is a Run-only package format
|
||||
|
||||
Run distributions use a new `raw-executable` package format. The worker uploads the compiled binary bytes directly and does not call the archive writer for Run. Client-manager distributions keep the existing ZIP/tar.gz packaging and config injection because they are plugin-declared companion builds with their own lifecycle.
|
||||
|
||||
### Decision 3: Self-update treats raw executable as first-class
|
||||
|
||||
Run update input may carry `raw-executable`. The self-update executor still downloads through the artifact channel, verifies the full artifact checksum, writes the staged executable under the transaction workspace, records its binary checksum, and uses the existing activation and rollback logic.
|
||||
|
||||
### Decision 4: Run keys get a dedicated generator
|
||||
|
||||
The existing `randomToken()` remains 32 random bytes because it is also used for auth sessions, user ID suffixes, and job leases. Run component keys use a new 64-byte URL-safe generator, increasing key length only for Run authorization.
|
||||
|
||||
### Decision 5: Reset revokes the active Run session
|
||||
|
||||
The reset service already revokes old distribution artifacts and increments key generation. This change also removes the active Run control session for that server endpoint when the Run component key is reset, forcing a freshly compiled binary to authenticate before more control/job traffic is accepted.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- Embedded authorization can be extracted from a binary by a determined operator or attacker with file access. This is acceptable for the requested distribution model and is explicitly not a DRM or device-binding system.
|
||||
- Compile-time values can be visible to privileged users on the build worker. The build worker remains part of the trusted platform boundary.
|
||||
- Raw executables lose the convenience of multi-file package payloads, so any future service installer/systemd wrapper should be a separate explicit distribution profile rather than hidden in this change.
|
||||
|
||||
## Verification
|
||||
|
||||
- `openspec validate secure-single-file-run-distribution --strict`
|
||||
- `cd run && go test ./...`
|
||||
- `cd platform && go test ./...`
|
||||
- `cd platform_web && npm test`
|
||||
- `cd platform_web && npm run typecheck`
|
||||
- `scripts/check-structure.sh`
|
||||
@@ -0,0 +1,29 @@
|
||||
## Why
|
||||
|
||||
Run distributions currently produce a secret-bearing archive with a sidecar `config.json`, and downloaded Windows packages are ZIP files. Operators need the platform to deliver one server-scoped executable whose platform URL and runtime authorization are compiled into the binary.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Change platform-managed Run distributions to publish a single raw executable instead of a ZIP/tarball plus `config.json`.
|
||||
- Inject Run platform URL, worker mode, runtime identity, key generation, and authorization token through Go `-ldflags -X` during the trusted Run build.
|
||||
- Increase Run component key entropy without changing the global session/job token generator.
|
||||
- Allow Run self-update jobs to consume raw executable artifacts for Windows and Linux targets.
|
||||
- Add run-key reset to the server-list "运行操作" dangerous menu, using the existing reset API.
|
||||
- Revoke the active Run control session when the run key is reset so old deployed binaries stop immediately.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `secure-single-file-run-distribution`: Server-scoped Run executable distribution, compile-time authorization injection, raw-binary self-update, and list-level run-key reset.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- None.
|
||||
|
||||
## Impact
|
||||
|
||||
- Affects `platform/` distribution build input, run-key generation/reset behavior, artifact naming, package-format validation, and tests.
|
||||
- Affects `run/` config loading, distribution build packaging, self-update extraction, protocol DTOs, and tests.
|
||||
- Affects `platform_web/` server-list runtime action menu and tests.
|
||||
- Does not touch plugins, client-manager package format, AI provider flows, billing/cloud features, or unrelated UI systems.
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Platform publishes single-file Run executables
|
||||
|
||||
The platform SHALL publish Run distributions as one raw executable per server, target OS, and architecture instead of an archive containing a sidecar configuration file.
|
||||
|
||||
#### Scenario: Operator generates Windows Run
|
||||
|
||||
- **WHEN** an authorized operator generates Run for a Windows target
|
||||
- **THEN** platform MUST queue a distribution build job that uploads a single executable artifact and presents it as `run-windows-<arch>.exe` with `application/octet-stream`
|
||||
- **AND** the artifact MUST NOT contain a downloadable `config.json` sidecar
|
||||
|
||||
#### Scenario: Operator generates Linux Run
|
||||
|
||||
- **WHEN** an authorized operator generates Run for a Linux target
|
||||
- **THEN** platform MUST queue a distribution build job that uploads a single executable artifact and presents it as `run-linux-<arch>` with `application/octet-stream`
|
||||
|
||||
### Requirement: Run authorization is compiled into the executable
|
||||
|
||||
Run distribution builds SHALL inject server-scoped identity and the active Run authorization key into the executable at Go build time.
|
||||
|
||||
#### Scenario: Build input is consumed by trusted Run builder
|
||||
|
||||
- **WHEN** a Run worker receives authenticated distribution build input for component kind `run`
|
||||
- **THEN** it MUST compile the target with Go `-ldflags -X` values for worker mode, platform URL, run endpoint ID, server instance ID, plugin ID, component kind, key generation, target release, and authorization token
|
||||
- **AND** explicit runtime environment variables such as `RUN_PLATFORM_URL` MUST remain able to override compiled defaults for local development
|
||||
|
||||
#### Scenario: Compiled executable starts without sidecar config
|
||||
|
||||
- **WHEN** the generated Run executable starts with no `config.json`
|
||||
- **THEN** it MUST load the compiled identity and key, register as a worker by default, and authenticate against the current platform key generation
|
||||
|
||||
### Requirement: Run keys use increased entropy
|
||||
|
||||
Platform SHALL generate Run component keys with more entropy than general-purpose platform tokens while preserving existing global token behavior.
|
||||
|
||||
#### Scenario: Run key is created or reset
|
||||
|
||||
- **WHEN** platform creates or resets a Run component key
|
||||
- **THEN** it MUST use a dedicated Run key generator of at least 64 random bytes before URL-safe encoding
|
||||
- **AND** it MUST NOT change auth session or job lease token generation
|
||||
|
||||
### Requirement: Raw executable self-update is supported
|
||||
|
||||
Run self-update SHALL accept raw executable artifacts for supported Run targets.
|
||||
|
||||
#### Scenario: Raw update artifact is staged
|
||||
|
||||
- **WHEN** Run receives a self-update job whose package format is `raw-executable`
|
||||
- **THEN** Run MUST download the artifact through the artifact channel, verify the full checksum, stage it as an executable file, record the staged binary checksum, and use the existing activation/rollback flow
|
||||
|
||||
#### Scenario: Unsupported update package is requested
|
||||
|
||||
- **WHEN** Run receives a self-update job with an unsupported package format
|
||||
- **THEN** Run MUST reject the update before activation and keep the current executable
|
||||
|
||||
### Requirement: Server list exposes run-key reset
|
||||
|
||||
The server-list runtime action menu SHALL expose run-key reset as a destructive runtime operation when the platform reports it available.
|
||||
|
||||
#### Scenario: Operator resets from server list
|
||||
|
||||
- **WHEN** an authorized operator chooses run-key reset from the server-list `运行操作` menu and confirms the destructive action
|
||||
- **THEN** platform_web MUST call the existing run-key reset API, show a tracked operation result, refresh server state, and indicate that a new Run executable must be generated
|
||||
|
||||
### Requirement: Run key reset revokes active control sessions
|
||||
|
||||
Resetting a Run key SHALL immediately invalidate the active Run control session for the server's assigned Run endpoint.
|
||||
|
||||
#### Scenario: Online Run key is reset
|
||||
|
||||
- **WHEN** platform successfully resets the Run key for a server instance with an active Run control session
|
||||
- **THEN** platform MUST remove that session so old deployed executables cannot continue heartbeat or job traffic under the stale key
|
||||
@@ -0,0 +1,47 @@
|
||||
## Prompt Boundaries
|
||||
|
||||
正向提示词: Deliver a secure single-file Run distribution flow for 服务器管理, where generated Run artifacts are raw executables with compile-time platform URL and authorization, self-update accepts raw executables, and server-list run-key reset is available with confirmation.
|
||||
|
||||
方向提示词: Preserve existing platform/run/platform_web boundaries; use platform distribution build input and Run Go `-ldflags -X` injection; keep Client Manager packaging unchanged; verify with focused Go/frontend tests, OpenSpec validation, and `scripts/check-structure.sh`.
|
||||
|
||||
任务边界: Do not add device authorization binding, billing, cloud host sales, AI-provider changes, plugin marketplace expansion, Client Manager packaging changes, raw credential exposure in APIs/UI, or unrelated visual-system changes.
|
||||
|
||||
## 1. OpenSpec
|
||||
|
||||
- [x] 1.1 Define proposal, design, requirements, and task boundaries for single-file Run distribution.
|
||||
- [x] 1.2 Validate the OpenSpec change before implementation completion.
|
||||
|
||||
## 2. Platform
|
||||
|
||||
- [x] 2.1 Add Run-only raw executable package format, artifact filename/content-type presentation, and build-input platform URL.
|
||||
- [x] 2.2 Generate longer Run component keys without changing global token generation.
|
||||
- [x] 2.3 Revoke active Run control sessions when Run key reset succeeds.
|
||||
- [x] 2.4 Update platform tests for raw Run artifacts, key length, build input, reset revocation, and self-update input.
|
||||
|
||||
## 3. Run
|
||||
|
||||
- [x] 3.1 Add compile-time config variables with environment override precedence.
|
||||
- [x] 3.2 Inject Run identity and authorization through Go `-ldflags -X` and upload raw executable bytes for Run builds.
|
||||
- [x] 3.3 Support raw executable self-update staging while preserving archive handling for compatibility/tests where needed.
|
||||
- [x] 3.4 Update Run tests for raw build output, compiled smoke identity, config precedence, and raw self-update.
|
||||
|
||||
## 4. platform_web
|
||||
|
||||
- [x] 4.1 Add run-key reset to the server-list `运行操作` dangerous menu with confirmation and API execution.
|
||||
- [x] 4.2 Update frontend tests and fixtures for raw Run download metadata and reset action coverage.
|
||||
|
||||
## 5. Verification
|
||||
|
||||
- [x] 5.1 Run focused `run`, `platform`, and `platform_web` verification.
|
||||
- [x] 5.2 Run `scripts/check-structure.sh`.
|
||||
|
||||
|
||||
## Verification Evidence
|
||||
|
||||
- `openspec validate secure-single-file-run-distribution --strict`: passed
|
||||
- `cd platform && go test ./service -run 'TestCoreService(ResetRunKey|GeneratesRun|RunDistribution|DistributionBuild)' -count=1`: passed
|
||||
- `cd platform && go test ./validator ./domain ./dto -count=1`: passed
|
||||
- `cd run && go test ./config ./protocol ./runtime -run 'TestLoad|TestWorkerDistribution|TestDistributionBuild|TestValidateDistribution|TestRunSelfUpdate|TestPrepareSelfUpdate|TestWorkerDispatchesSelfUpdate' -count=1`: passed
|
||||
- `cd platform_web && npm test -- --run pages/ConsolePages.test.tsx api/client.test.ts`: passed, 2 files / 25 tests
|
||||
- `scripts/check-structure.sh`: passed
|
||||
- Note: full `run/runtime` suite still needs network bind permissions for unrelated Source RCON/httptest fixtures; focused distribution/self-update coverage was used for this change.
|
||||
Reference in New Issue
Block a user