crypto: forward-only key-path ceiling + OSV resilience + token serialization
SEC-028 -- a rotated-out server signing key must stop being trusted even when the agent cannot phone home. pubkey.go: bounded stale-cache window on public-key fetch failure; past the window (or when cache age is unknown) it fails closed instead of trusting the cached key indefinitely. Window length is operator policy (command_signing.stale_key_max_age_hours, default 168h/7d) delivered fleet-wide via GET /agents/:id/config; the [1h, 30d] clamp and the existence of the ceiling are doctrine, not knobs. verification.go: CheckKeyRotation refuses when the named key_id is not in the server active set (no primary fallback), and applies the same bounded-stale ceiling to the active-set fetch-failure path so key_id'd commands are no weaker than keyless ones. Server carries the default + 1-720h validation; web surfaces it in Security Settings. SEC-029 -- the standalone OSV.dev client retries transient transport/5xx/429 with exponential backoff and trips a process-wide circuit breaker after a run of failures, fast-failing to 'unreachable'. Verdict semantics unchanged and still fail-closed; the resilience only stops a transient scanner blip from forcing an operator override. GATE-004 #4 -- Consumer.ProcessToken holds a mutex so the replay-state guards are never raced by a concurrent caller. Today's single caller (the poll loop) never overlaps; this enforces the one-token-at-a-time invariant for future callers (local-API trigger, retry worker). RAF/verification/03 and RAF/security/05 document the key-path and OSV changes. ETHOS #3, #4; forward-only doctrine.
This commit is contained in:
parent
e0765c29f4
commit
0b1b8124b0
13 changed files with 374 additions and 57 deletions
|
|
@ -130,6 +130,15 @@ const SecuritySettings: React.FC = () => {
|
|||
description: 'Cryptographic algorithm for signing commands',
|
||||
disabled: !localSettings?.command_signing?.enabled,
|
||||
},
|
||||
{
|
||||
key: 'stale_key_max_age_hours',
|
||||
label: 'Stale Key Tolerance (hours)',
|
||||
type: 'number',
|
||||
value: localSettings?.command_signing?.stale_key_max_age_hours ?? 168,
|
||||
min: 1,
|
||||
max: 720,
|
||||
description: 'How long an offline agent keeps trusting its cached server key before failing closed. Forward-only doctrine bounds this 1-720h; the agent enforces the ceiling.',
|
||||
},
|
||||
];
|
||||
|
||||
// Update Security Settings
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ export interface CommandSigningSettings {
|
|||
enforcement_mode: 'strict' | 'warning' | 'disabled';
|
||||
algorithm: 'ed25519' | 'rsa' | 'ecdsa';
|
||||
key_id?: string;
|
||||
// How long an offline agent keeps trusting its cached server key before it
|
||||
// fails closed (SEC-028). Bounded 1-720h; the agent enforces the ceiling.
|
||||
stale_key_max_age_hours?: number;
|
||||
}
|
||||
|
||||
export interface UpdateSecuritySettings {
|
||||
|
|
|
|||
Loading…
Reference in a new issue