Documentation
¶
Index ¶
- Constants
- Variables
- func IsPostureQuery(name string) bool
- func ParseUptime(record NodePosture) (*types.NodeUptime, error)
- func PostureCategory(name string) string
- func RiskLevelFromScore(score int) string
- func SetPrefix(prefix string)
- func SummaryFromRecords(records []NodePosture) *types.NodePostureSummary
- type ControlResult
- type FleetCategorySummary
- type Framework
- type NodePosture
- type PostureManager
- func (pm *PostureManager) GetByNode(nodeUUID string) ([]NodePosture, error)
- func (pm *PostureManager) GetByNodeCategory(nodeUUID, category string) (*NodePosture, error)
- func (pm *PostureManager) GetFleetSummary(environment string) ([]FleetCategorySummary, error)
- func (pm *PostureManager) GetSummaryByNode(nodeUUID string) (*types.NodePostureSummary, error)
- func (pm *PostureManager) GetSummaryByNodes(nodeUUIDs []string) (map[string]*types.NodePostureSummary, error)
- func (pm *PostureManager) GetUptimeByNode(nodeUUID string) (*types.NodeUptime, error)
- func (pm *PostureManager) GetUptimeByNodes(nodeUUIDs []string) (map[string]*types.NodeUptime, error)
- func (pm *PostureManager) IngestResult(nodeUUID, environment, queryName string, columns json.RawMessage) error
- type PostureProfile
- type PostureScore
- type ProfileQuery
- type ScoreCalculator
- type ScoringRule
- type Severity
Constants ¶
const DefaultQueryPrefix = "osctrl:posture:"
DefaultQueryPrefix identifies scheduled queries whose result logs should be ingested as posture data by default.
Recommended practice: set the osquery schedule interval for posture queries to once per day (86400 seconds). Posture data — installed packages, users, disk encryption state — changes infrequently, and daily collection is sufficient for compliance audits without overloading agents or the logging pipeline.
const UptimeCategory = "uptime"
Variables ¶
var QueryPrefix = DefaultQueryPrefix
QueryPrefix is the active posture query prefix. It is configured once at TLS startup. Empty disables posture ingestion.
var SeverityWeight = map[Severity]int{ SeverityCritical: 30, SeverityHigh: 20, SeverityMedium: 10, SeverityLow: 5, }
SeverityWeight converts severity to risk points.
Functions ¶
func IsPostureQuery ¶
IsPostureQuery returns true if the query name starts with the posture prefix.
func ParseUptime ¶
func ParseUptime(record NodePosture) (*types.NodeUptime, error)
ParseUptime converts the latest uptime posture result into node metadata.
func PostureCategory ¶
PostureCategory extracts the category name from a posture query name. e.g. "osctrl:posture:packages" → "packages"
func RiskLevelFromScore ¶
RiskLevelFromScore converts a normalized score to a risk level.
func SummaryFromRecords ¶
func SummaryFromRecords(records []NodePosture) *types.NodePostureSummary
Types ¶
type ControlResult ¶
type ControlResult struct {
Category string `json:"category"` // posture category the evidence came from
ControlID string `json:"control_id"` // e.g. "A.8.24" or "CC6.6"
Framework Framework `json:"framework"`
Title string `json:"title"`
Description string `json:"description"`
Status string `json:"status"` // "pass", "warn", "fail"
Severity Severity `json:"severity"`
Score int `json:"score"` // 0 = pass, otherwise earned risk points
Detail string `json:"detail"` // human-readable explanation
}
ControlResult is the evaluation outcome for a single control.
type FleetCategorySummary ¶
type FleetCategorySummary struct {
Category string `json:"category"`
NodeCount int `json:"node_count"`
TotalRows int `json:"total_rows"`
}
FleetCategorySummary is a per-category summary across all nodes in an environment.
type NodePosture ¶
type NodePosture struct {
ID uint `gorm:"primarykey" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
NodeUUID string `gorm:"type:varchar(36);uniqueIndex:idx_posture_node_category" json:"node_uuid"`
Environment string `gorm:"index:idx_posture_env" json:"environment"`
Category string `gorm:"uniqueIndex:idx_posture_node_category;type:varchar(64)" json:"category"`
// QueryName is the full osquery scheduled-query name including prefix.
QueryName string `gorm:"type:varchar(255)" json:"query_name"`
// RowCount is the number of rows in the result (e.g. 3 packages, 5 users).
RowCount int `json:"row_count"`
// Summary is a compact JSON snapshot of the result data. For small
// results this is the full columns array; for large results it's
// truncated to the first 100 rows to keep the record manageable.
Summary string `gorm:"type:text" json:"summary"`
// Snapshot is the raw columns JSON from the latest result, capped at
// 256KB. Used for detail views and compatibility with existing posture data.
Snapshot string `gorm:"type:text" json:"-"`
// FirstSeen is when this category was first observed for this node.
FirstSeen time.Time `json:"first_seen"`
LastSeen time.Time `gorm:"index" json:"last_seen"`
}
NodePosture stores the latest snapshot of a single posture category for one node. Updated (upserted) every time a matching result log arrives.
func (NodePosture) TableName ¶
func (NodePosture) TableName() string
TableName overrides the default table name.
type PostureManager ¶
PostureManager manages the node posture table.
func NewPostureManager ¶
func NewPostureManager(db *gorm.DB) *PostureManager
NewPostureManager creates the manager and auto-migrates the table.
func (*PostureManager) GetByNode ¶
func (pm *PostureManager) GetByNode(nodeUUID string) ([]NodePosture, error)
GetByNode returns all posture categories for a node, ordered by category.
func (*PostureManager) GetByNodeCategory ¶
func (pm *PostureManager) GetByNodeCategory(nodeUUID, category string) (*NodePosture, error)
GetByNodeCategory returns a single posture category for a node.
func (*PostureManager) GetFleetSummary ¶
func (pm *PostureManager) GetFleetSummary(environment string) ([]FleetCategorySummary, error)
GetFleetSummary returns per-category posture counts across all nodes in an environment.
func (*PostureManager) GetSummaryByNode ¶
func (pm *PostureManager) GetSummaryByNode(nodeUUID string) (*types.NodePostureSummary, error)
func (*PostureManager) GetSummaryByNodes ¶
func (pm *PostureManager) GetSummaryByNodes(nodeUUIDs []string) (map[string]*types.NodePostureSummary, error)
func (*PostureManager) GetUptimeByNode ¶
func (pm *PostureManager) GetUptimeByNode(nodeUUID string) (*types.NodeUptime, error)
func (*PostureManager) GetUptimeByNodes ¶
func (pm *PostureManager) GetUptimeByNodes(nodeUUIDs []string) (map[string]*types.NodeUptime, error)
func (*PostureManager) IngestResult ¶
func (pm *PostureManager) IngestResult(nodeUUID, environment, queryName string, columns json.RawMessage) error
IngestResult processes a single result log entry and upserts the posture record if the query name matches the posture prefix.
type PostureProfile ¶
type PostureProfile struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Platform string `json:"platform"`
Queries map[string]ProfileQuery `json:"queries"`
}
PostureProfile is a named set of posture check queries that an operator can merge into an environment's schedule config. Each profile targets a specific node type and platform with checks tailored to that environment's compliance requirements.
func AllProfiles ¶
func AllProfiles() []PostureProfile
AllProfiles returns every predefined posture profile, sorted by name.
func GetProfile ¶
func GetProfile(id string) *PostureProfile
GetProfile returns a single profile by ID, or nil if not found.
func LinuxLaptopProfile ¶
func LinuxLaptopProfile() PostureProfile
func LinuxServerProfile ¶
func LinuxServerProfile() PostureProfile
func MacOSLaptopProfile ¶
func MacOSLaptopProfile() PostureProfile
func WindowsLaptopProfile ¶
func WindowsLaptopProfile() PostureProfile
func WindowsServerProfile ¶
func WindowsServerProfile() PostureProfile
func (PostureProfile) ToScheduleEntries ¶
func (p PostureProfile) ToScheduleEntries() (map[string]map[string]interface{}, error)
ToScheduleEntries converts a profile's queries into a JSON map suitable for merging into an environment's schedule config section.
func (PostureProfile) ToScheduleJSON ¶
func (p PostureProfile) ToScheduleJSON() (string, error)
ToScheduleJSON returns the schedule entries as pretty-printed JSON.
type PostureScore ¶
type PostureScore struct {
NodeUUID string `json:"node_uuid"`
Timestamp time.Time `json:"timestamp"`
TotalScore int `json:"total_score"` // 0-100 normalized, lower is better
RiskLevel string `json:"risk_level"` // "low", "medium", "high", "critical"
Controls []ControlResult `json:"controls"`
PassCount int `json:"pass_count"`
WarnCount int `json:"warn_count"`
FailCount int `json:"fail_count"`
}
PostureScore is the aggregate risk assessment for a node.
type ProfileQuery ¶
type ProfileQuery struct {
Query string `json:"query"`
Interval int `json:"interval"`
Platform string `json:"platform,omitempty"`
Snapshot bool `json:"snapshot"`
}
ProfileQuery is a single scheduled query within a posture profile.
type ScoreCalculator ¶
type ScoreCalculator struct {
// contains filtered or unexported fields
}
ScoreCalculator evaluates posture data against compliance controls.
func NewScoreCalculator ¶
func NewScoreCalculator() *ScoreCalculator
NewScoreCalculator returns a calculator with all built-in rules.
func (*ScoreCalculator) Score ¶
func (sc *ScoreCalculator) Score(records []NodePosture) PostureScore
Score evaluates all posture records and returns the aggregate score.
type ScoringRule ¶
type ScoringRule struct {
// Categories lists every posture category that can provide evidence
// for this control. The rule is evaluated when at least one of them
// has been collected; mutually exclusive sources (deb vs rpm) belong
// in the same rule so an empty inapplicable source is not a finding.
Categories []string `json:"categories"`
ControlID string `json:"control_id"`
Framework Framework `json:"framework"`
Title string `json:"title"`
Description string `json:"description"`
Severity Severity `json:"severity"`
// Evaluate receives the collected categories (only those present for
// the node) with their parsed rows and returns (status, detail).
// status is "pass", "warn", or "fail".
Evaluate func(data map[string][]map[string]interface{}) (status, detail string)
}
ScoringRule defines how to evaluate one control from posture data.