feat: 完整游戏运维功能
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
# Design
|
||||
|
||||
## Session records
|
||||
|
||||
`AuthSessionRecord` stores only a SHA-256 token hash, user ID, issued/expiry timestamps, revoked timestamp, and rotation generation. The bearer token is returned once at login/rotation and is never stored in a snapshot. `GetCurrentUser` hashes the presented token and loads the record from the repository, rejecting missing, revoked, expired, or disabled-user sessions. The default TTL is bounded (8 hours); rotation revokes the prior generation before creating a new record. FileStore and MySQLStore snapshots load these records before serving requests.
|
||||
|
||||
Strict production routers deliver the platform session in an `HttpOnly`, `SameSite=Strict` cookie and omit the token from JSON, so platform_web JavaScript does not persist new raw tokens. Explicit CLI/local tooling may request a bearer response with `X-Auth-Token-Response: bearer`; the explicitly named `NewTestRouterWithCore` compatibility constructor retains the bearer response contract for existing in-process tests. All normal router constructors enforce authorization.
|
||||
|
||||
Run control state follows the same shape: a Run session has a bounded TTL, status, generation, capability fingerprint, and last-seen timestamp. Heartbeat/claim/ack/progress/result/cancel/reconcile/log/artifact operations must validate the current session and reject expired or revoked state.
|
||||
|
||||
## Signed Run envelope
|
||||
|
||||
HTTP Run channel requests carry `X-Run-Endpoint`, `X-Run-Timestamp`, `X-Run-Nonce`, and `X-Run-Signature`. The signature is HMAC-SHA256 over method, path, timestamp, nonce, and SHA-256 request body using the established Run session token as the channel key. Timestamps are accepted only inside a five-minute clock-skew window and each nonce is accepted once per Run session. The body is buffered and restored before JSON decoding. Legacy in-process service calls remain available for existing tests, but HTTP channel handlers reject missing/invalid signatures after session establishment. Signature errors are safe 401/403 failures and never echo token material.
|
||||
|
||||
## Authorization matrix
|
||||
|
||||
- Public: health, login, registration, and read-only marketplace/plugin discovery that contains no secret or host detail.
|
||||
- Platform admin: user administration, AI provider metadata, plugin installation/registration/state, Run endpoint administration, platform metrics, audit inspection, and global job/artifact/log metadata.
|
||||
- Authenticated server owner or assigned server administrator: server list/detail, runtime binding review, lifecycle, config diff/approval, logs, artifacts, distributions, dependency and client-manager actions for servers visible to that user.
|
||||
- Owner or platform admin only: runtime binding writes, key reset, server administrator membership changes, destructive/archive actions.
|
||||
- Run service identity: channelized control/jobs/logs/artifacts for its own endpoint and only resources addressed by a validated job/transfer/session; never browser bearer sessions.
|
||||
|
||||
Services repeat ownership and role checks even when a route already checked them. Cross-owner reads/writes return `forbidden`; missing/invalid/expired credentials return `unauthorized`.
|
||||
|
||||
## Secret boundary
|
||||
|
||||
Secret-bearing writes accept only controlled `secret://` references or opaque logical refs already declared by a plugin. Stored records keep references, encrypted component-key material, status, generation, and fingerprints; raw values are never returned. DTOs expose only `configured`, `secret`, `presence`, and safe fingerprint/status fields. Snapshot tests scan serialized JSON and browser responses for secret literals, paths, sockets, and credentials.
|
||||
|
||||
## Failure and migration behavior
|
||||
|
||||
Older snapshots decode absent auth/session/secret arrays as empty. Existing users remain valid but must log in again after upgrade if no session record exists. Existing Run endpoints without a persisted session require a fresh signed hello. Expired/revoked records remain durable for audit and can be pruned in a later change. No rollback step writes raw secret data.
|
||||
|
||||
## Deferred risks
|
||||
|
||||
The controlled secret reference is not a production vault and encrypted component-key material still depends on the configured platform protection boundary. KMS/HSM integration, key wrapping, and multi-resource transactions are explicitly deferred and must not be represented as complete by this change.
|
||||
@@ -0,0 +1,33 @@
|
||||
# Harden Platform Authentication, Authorization, and Secret Persistence
|
||||
|
||||
## Why
|
||||
|
||||
Platform account sessions and Run control sessions currently live only in process memory, so a restart invalidates valid clients and leaves revocation/expiry state implicit. Several management routes also rely on the caller reaching a UI path rather than enforcing an authenticated role or resource-ownership boundary at the API/service boundary. Existing component-key and distribution metadata is not included in the durable file/MySQL snapshot, while secret-bearing values must remain platform-owned and redacted.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Persist hashed platform sessions and Run control session state with explicit issued/expiry/revoked timestamps and safe rotation.
|
||||
- Require authenticated sessions for sensitive management APIs and enforce platform-admin, server-owner/administrator, and Run-service boundaries in handlers and services.
|
||||
- Add a signed, timestamped Run request envelope for control/job/log/artifact channel requests where the HTTP boundary can validate a trusted Run session and reject stale/replayed messages.
|
||||
- Persist existing encrypted component-key and distribution metadata in FileStore/MySQLStore snapshots, plus controlled secret metadata references and presence/fingerprint projections.
|
||||
- Ensure auth failures are stable 401/403 API errors and the web client clears invalid sessions without rendering token, key, path, socket, or secret literals.
|
||||
- Add regression coverage for login/reload, expiry/revocation/rotation, signed Run requests, cross-owner/role rejection, replay/clock failures, snapshot recovery, and non-disclosure.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Make session and authorization decisions durable and independently enforceable from the UI.
|
||||
- Keep raw credentials, host paths, direct sockets, and provider keys out of DTOs, logs, snapshots, and browser state.
|
||||
- Preserve the independent `run` repository boundary and channel priorities.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- A production KMS/vault, encrypted secret-value storage, durable scheduling, process supervision, logs/artifacts backends, dependency installation, self-update, client-manager lifecycle, or production scaling.
|
||||
- Re-adding Run source code to this repository or claiming the later roadmap is complete.
|
||||
|
||||
## Impact
|
||||
|
||||
- `platform/`: auth/session domain, repositories, snapshots, signed Run request validation, route authorization, safe secret metadata.
|
||||
- `platform_web/`: API error/session handling and safe auth capability projections.
|
||||
- `plugins/`: no raw credential or direct channel access; manifest/SDK contracts remain unchanged except for regression fixtures if needed.
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
# Platform Authentication, Authorization, and Secret Persistence
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Platform sessions are durable and bounded
|
||||
The platform SHALL persist only hashed bearer-session records with user ownership, issued time, expiry time, revocation time, and rotation generation, and SHALL reject missing, expired, revoked, or disabled-user sessions.
|
||||
|
||||
#### Scenario: Session survives restart
|
||||
- **WHEN** a user logs in, the platform store is closed and reopened, and the same bearer token is presented before expiry
|
||||
- **THEN** the platform restores the session record and authenticates the user without storing the raw token
|
||||
|
||||
#### Scenario: Expired or revoked session is rejected
|
||||
- **WHEN** an expired or revoked bearer token is presented
|
||||
- **THEN** the API returns 401 and performs no protected read or write
|
||||
|
||||
#### Scenario: Session rotation revokes the old generation
|
||||
- **WHEN** an authenticated user rotates a session
|
||||
- **THEN** a new token is issued, the previous generation is revoked durably, and the previous token is rejected
|
||||
|
||||
#### Scenario: Browser session token is not script-readable
|
||||
- **WHEN** a user logs in through the strict production router
|
||||
- **THEN** the platform sets an HttpOnly SameSite session cookie and omits the raw token from the JSON response
|
||||
|
||||
### Requirement: Run requests use a trusted bounded channel
|
||||
Run control, job, log, and artifact channel requests SHALL validate the current endpoint session and, at the HTTP boundary, a timestamped HMAC signature with a five-minute clock-skew limit and single-use nonce.
|
||||
|
||||
#### Scenario: Valid signed request
|
||||
- **WHEN** a request is signed by the current Run session with an accepted timestamp and unused nonce
|
||||
- **THEN** the request is processed for that endpoint and the nonce is recorded as used
|
||||
|
||||
#### Scenario: Invalid, stale, or replayed request
|
||||
- **WHEN** the signature is invalid, the timestamp is outside the skew window, or the nonce was already used
|
||||
- **THEN** the request is rejected with a safe authentication error and no state mutation occurs
|
||||
|
||||
### Requirement: Sensitive APIs enforce role and resource ownership
|
||||
Sensitive user, provider, plugin, server, distribution, job, runtime-binding, audit, and channel metadata APIs SHALL enforce platform-admin, server-owner/administrator, or Run-service identity at the API and service boundaries.
|
||||
|
||||
#### Scenario: Cross-owner access
|
||||
- **WHEN** an authenticated non-owner requests another owner's server binding, job, config, artifact, or action
|
||||
- **THEN** the platform returns 403 and leaves the resource unchanged
|
||||
|
||||
#### Scenario: UI bypass
|
||||
- **WHEN** a caller invokes a sensitive route directly without the required role or session
|
||||
- **THEN** the platform rejects the call regardless of UI state or request shape
|
||||
|
||||
### Requirement: Core auth and secret metadata are durable and redacted
|
||||
FileStore and MySQLStore SHALL persist auth sessions, Run session state, encrypted component-key metadata, distributions, and controlled secret references through the repository snapshot contract; raw tokens, keys, credentials, paths, sockets, and provider secret values MUST NOT appear in snapshots, logs, DTOs, or browser responses.
|
||||
|
||||
#### Scenario: Snapshot reload preserves safe metadata
|
||||
- **WHEN** the store is reopened after creating a session, Run identity, component key, or secret reference
|
||||
- **THEN** safe status/generation/presence metadata remains available and raw values remain absent
|
||||
|
||||
#### Scenario: Secret presence projection
|
||||
- **WHEN** a secret reference is configured
|
||||
- **THEN** API and web responses expose only presence/configured/secret flags and safe fingerprints, never the reference value or storage location
|
||||
|
||||
### Requirement: Web clients handle auth failures safely
|
||||
The platform web client SHALL treat 401 as a session reset/re-login condition and 403 as a capability/ownership denial, without persisting or rendering raw tokens, credentials, paths, sockets, or secret references.
|
||||
|
||||
#### Scenario: API session expires in the console
|
||||
- **WHEN** an API call returns 401
|
||||
- **THEN** the client clears the bearer token and exposes a safe re-authentication state
|
||||
|
||||
#### Scenario: API authorization is denied
|
||||
- **WHEN** an API call returns 403
|
||||
- **THEN** the client reports a safe access-denied error without including secret or infrastructure details
|
||||
|
||||
## Deferred Requirements
|
||||
|
||||
- Production KMS/HSM/vault encryption and secret-value rotation are deferred.
|
||||
- Durable scheduling, process supervision, logs/artifacts backends, dependency installation, self-update, client-manager lifecycle, and production scaling are outside this change.
|
||||
@@ -0,0 +1,22 @@
|
||||
## 1. Planning and contracts
|
||||
|
||||
- [x] 1.1 Add typed durable auth-session and Run-session contracts, repository interfaces, validation rules, and safe DTO projections.
|
||||
- [x] 1.2 Document the auth/authorization matrix, signed envelope, replay/clock constraints, secret-ref boundary, and deferred production risks.
|
||||
|
||||
## 2. Durable authentication and Run trust
|
||||
|
||||
- [x] 2.1 Persist hashed user sessions with expiry, revocation, rotation, and reload support in MemoryStore/FileStore/MySQLStore.
|
||||
- [x] 2.2 Persist Run session state and enforce bounded lifecycle plus signed timestamp/nonce validation at HTTP channel boundaries.
|
||||
- [x] 2.3 Add login/session-rotation/revocation routes and safe 401/403 error behavior.
|
||||
|
||||
## 3. Authorization and secret boundary
|
||||
|
||||
- [x] 3.1 Enforce platform-admin, owner/administrator, and Run-service authorization on sensitive routes and repeat checks in services.
|
||||
- [x] 3.2 Persist component-key/distribution/secret metadata through all durable snapshots without raw secret disclosure.
|
||||
- [x] 3.3 Add API and service regressions for cross-owner access, expired/revoked credentials, replay, and non-disclosure.
|
||||
|
||||
## 4. Web and verification
|
||||
|
||||
- [x] 4.1 Update platform_web API/session handling for 401/403 and capability-safe projections with no secret literals.
|
||||
- [x] 4.2 Add frontend regressions for session reset/denied access and secret/path/socket non-disclosure.
|
||||
- [x] 4.3 Run platform, plugin, web, OpenSpec strict validation, structure checks, and risk-relevant independent Run tests; record evidence and leave later roadmap work explicitly deferred.
|
||||
Reference in New Issue
Block a user