mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
fix(api): localize shipped security doc refs
This commit is contained in:
@@ -124,6 +124,7 @@ management, and fleet control surfaces.
|
||||
7. Preserve canonical token-lifecycle reads in shared `internal/api/` auth/security helpers so lifecycle-adjacent setup and install flows do not revoke a displayed relay pairing token after `lastUsedAt` proves that an already paired device is actively depending on that credential.
|
||||
8. Preserve backend-owned Pulse Mobile relay runtime credential minting in those same shared `internal/api/` auth/security helpers so lifecycle-adjacent setup and install flows reuse the canonical mobile token route instead of reintroducing wildcard or browser-authored runtime token bundles.
|
||||
9. Preserve the dedicated backend-owned `relay:mobile:access` capability and its governed backward-compatible route inventory plus the shared helper call sites around it, so lifecycle-adjacent setup and install flows do not widen the mobile device credential back into general AI chat/execute scope ownership.
|
||||
10. Preserve shipped security-doc guidance in shared lifecycle setup helpers so `internal/api/config_setup_handlers.go` and adjacent install/setup runtime paths point operators at the running build's local security documentation route rather than GitHub `main` links.
|
||||
|
||||
## Forbidden Paths
|
||||
|
||||
@@ -1417,6 +1418,11 @@ Proxmox install commands in `internal/api/config_setup_handlers.go` and
|
||||
configured, the canonical agent-install-command API must return tokenless
|
||||
install transport and must not persist a new API token record just because an
|
||||
operator opened a backend-driven install surface.
|
||||
That same backend-owned setup/install boundary also owns shipped security-doc
|
||||
guidance in runtime responses and logs: `internal/api/config_setup_handlers.go`
|
||||
and adjacent lifecycle setup helpers must not point operators at GitHub
|
||||
`main` for security instructions that the running build already serves
|
||||
locally, and should use the shipped `/docs/SECURITY.md` path instead.
|
||||
The same optional-auth continuity must hold after install as well: Unified Agent
|
||||
runtime startup may not reject a blank token unless enrollment is explicitly
|
||||
enabled, agent report transport must omit auth headers when no token is
|
||||
|
||||
@@ -184,6 +184,7 @@ Own canonical runtime payload shapes between backend and frontend.
|
||||
17. Governed frontend API clients open-coding `if (!response.ok) { if (isAPIResponseStatus(...)) throw new Error(...) }` status-to-user-message branches instead of using canonical shared custom-status error helpers
|
||||
18. Monitoring command-trigger clients open-coding `parseOptionalAPIResponse(response, { success: true }, ...)` success-envelope fallbacks instead of using a canonical shared success-envelope helper
|
||||
19. Governed frontend API clients open-coding `try/catch` wrappers around `apiFetchJSON(...)` just to map `402` or `404` into `[]`, `{ plans: [] }`, or `null` instead of using canonical shared API-error-status fallback helpers
|
||||
20. Backend config/settings handlers pointing operator guidance at GitHub `main` docs when the running build already ships that guidance locally under `/docs/`
|
||||
|
||||
## Completion Obligations
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ querying, and the operator-facing storage health presentation layer.
|
||||
16. Preserve optional-auth tokenless behavior in those same shared backend install-command helpers so adjacent transport surfaces do not implicitly persist API tokens and flip auth-configured state when an operator only requested a Proxmox install command on a token-optional Pulse instance.
|
||||
17. Preserve backend-owned Pulse Mobile relay runtime credential minting in those same shared `internal/api/` auth/security helpers so storage- and recovery-adjacent transport surfaces do not inherit browser-authored wildcard token bundles when they depend on the canonical security helper layer.
|
||||
18. Preserve the dedicated backend-owned `relay:mobile:access` capability and its governed backward-compatible route inventory plus the shared helper call sites around it, so storage- and recovery-adjacent transport surfaces do not treat the mobile relay credential as a general AI scope bundle.
|
||||
19. Preserve shipped local security-doc guidance in shared `internal/api/` config/setup helpers so storage- and recovery-adjacent transport surfaces do not reintroduce GitHub `main` security links when the running build already serves its own local security documentation route.
|
||||
|
||||
## Forbidden Paths
|
||||
|
||||
|
||||
@@ -87,5 +87,11 @@ func TestHandleVerifyTemperatureSSH(t *testing.T) {
|
||||
if !bytes.Contains(rec.Body.Bytes(), []byte("invalid-host-name-for-test")) {
|
||||
t.Error("expected affected node in failure list")
|
||||
}
|
||||
if !bytes.Contains(rec.Body.Bytes(), []byte("/docs/SECURITY.md")) {
|
||||
t.Error("expected shipped security doc reference in failure guidance")
|
||||
}
|
||||
if bytes.Contains(rec.Body.Bytes(), []byte("github.com/rcourtman/Pulse/blob/main/SECURITY.md")) {
|
||||
t.Error("expected failure guidance to avoid GitHub main security doc links")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -837,7 +837,7 @@ func (h *ConfigHandlers) getOrGenerateSSHKeys() SSHKeyPair {
|
||||
if isContainer && !devModeAllowSSH {
|
||||
log.Error().Msg("SECURITY BLOCK: SSH key generation disabled in containerized deployments")
|
||||
log.Error().Msg("Temperature monitoring via SSH is disabled in containerized deployments")
|
||||
log.Error().Msg("See: https://github.com/rcourtman/Pulse/blob/main/SECURITY.md#critical-security-notice-for-container-deployments")
|
||||
log.Error().Msg("See: " + shippedSecurityContainerNoticeDocAnchor)
|
||||
log.Error().Msg("To test SSH keys in dev/lab only: PULSE_DEV_ALLOW_CONTAINER_SSH=true (NEVER in production!)")
|
||||
return SSHKeyPair{}
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ func (h *ConfigHandlers) handleVerifyTemperatureSSH(w http.ResponseWriter, r *ht
|
||||
response.WriteString(fmt.Sprintf(" • %s\n", node))
|
||||
}
|
||||
response.WriteString("\n")
|
||||
response.WriteString("See: https://github.com/rcourtman/Pulse/blob/main/SECURITY.md for detailed SSH configuration options.\n")
|
||||
response.WriteString("See: " + shippedSecurityDocPath + " for detailed SSH configuration options.\n")
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
|
||||
@@ -5708,6 +5708,15 @@ func TestContract_EmbeddedFrontendWarningUsesCanonicalDevEntrypoints(t *testing.
|
||||
}
|
||||
}
|
||||
|
||||
func TestContract_ShippedSecurityDocReferencesStayLocal(t *testing.T) {
|
||||
if shippedSecurityDocPath != "/docs/SECURITY.md" {
|
||||
t.Fatalf("expected shipped security doc path, got %q", shippedSecurityDocPath)
|
||||
}
|
||||
if shippedSecurityContainerNoticeDocAnchor != "/docs/SECURITY.md#critical-security-notice-for-container-deployments" {
|
||||
t.Fatalf("expected shipped security container notice path, got %q", shippedSecurityContainerNoticeDocAnchor)
|
||||
}
|
||||
}
|
||||
|
||||
func mustStreamEvent(t *testing.T, eventType string, data interface{}) chat.StreamEvent {
|
||||
t.Helper()
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package api
|
||||
|
||||
const (
|
||||
shippedSecurityDocPath = "/docs/SECURITY.md"
|
||||
shippedSecurityContainerNoticeDocAnchor = shippedSecurityDocPath + "#critical-security-notice-for-container-deployments"
|
||||
)
|
||||
Reference in New Issue
Block a user