client

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 15, 2026 License: GPL-3.0 Imports: 16 Imported by: 0

Documentation

Overview

Package client provides the OpenCTEM API client.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsAuthenticationError

func IsAuthenticationError(err error) bool

IsAuthenticationError checks if the error is a 401 authentication error.

func IsAuthorizationError

func IsAuthorizationError(err error) bool

IsAuthorizationError checks if the error is a 403 authorization error.

func IsClientError

func IsClientError(err error) bool

IsClientError checks if the error is a 4xx client error.

func IsNotFoundError

func IsNotFoundError(err error) bool

IsNotFoundError checks if the error is a 404 not found error.

func IsRateLimitError

func IsRateLimitError(err error) bool

IsRateLimitError checks if the error is a 429 rate limit error.

func IsRetryable

func IsRetryable(err error) bool

IsRetryable checks if the error should be retried.

func IsServerError

func IsServerError(err error) bool

IsServerError checks if the error is a 5xx server error.

Types

type ChunkUploadResponse

type ChunkUploadResponse struct {
	ChunkID         string `json:"chunk_id"`
	ReportID        string `json:"report_id"`
	ChunkIndex      int    `json:"chunk_index"`
	Status          string `json:"status"`
	AssetsCreated   int    `json:"assets_created"`
	AssetsUpdated   int    `json:"assets_updated"`
	FindingsCreated int    `json:"findings_created"`
	FindingsUpdated int    `json:"findings_updated"`
	FindingsSkipped int    `json:"findings_skipped"`
}

ChunkUploadResponse is the response from chunk upload endpoint.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the OpenCTEM API client. It implements the core.Pusher interface.

func New

func New(cfg *Config) *Client

New creates a new OpenCTEM API client.

func NewWithOptions

func NewWithOptions(opts ...Option) *Client

NewWithOptions creates a new client using functional options. Example:

client := client.NewWithOptions(
    client.WithBaseURL("http://localhost:8080"),
    client.WithAPIKey("xxx"),
    client.WithAgentID("agent-1"),
    client.WithTimeout(30 * time.Second),
)

func (*Client) AcknowledgeCommand

func (c *Client) AcknowledgeCommand(ctx context.Context, cmdID string) error

AcknowledgeCommand acknowledges receipt of a command.

func (*Client) AsChunkUploader

func (c *Client) AsChunkUploader() chunk.Uploader

AsChunkUploader returns the client as a chunk.Uploader interface. This is useful for passing to chunk.Manager.

func (*Client) CheckFingerprints

func (c *Client) CheckFingerprints(ctx context.Context, fingerprints []string) (*retry.FingerprintCheckResult, error)

CheckFingerprints checks which fingerprints already exist on the server. This is used by the retry mechanism to avoid re-uploading data that already exists. It also serves as a connectivity check before processing the retry queue. This method implements retry.FingerprintChecker interface.

func (*Client) Close

func (c *Client) Close() error

Close gracefully shuts down the client and releases resources. This stops the retry worker and closes the retry queue if enabled.

func (*Client) CompleteCommand

func (c *Client) CompleteCommand(ctx context.Context, cmdID string, result json.RawMessage) error

CompleteCommand marks a command as completed with optional result.

func (*Client) DisableRetryQueue

func (c *Client) DisableRetryQueue(ctx context.Context) error

DisableRetryQueue stops the worker and closes the retry queue.

func (*Client) EnableRetryQueue

func (c *Client) EnableRetryQueue(ctx context.Context, cfg *RetryQueueConfig) error

EnableRetryQueue enables the retry queue with the given configuration. This creates a file-based retry queue and optionally starts the background worker.

func (*Client) EnrichFindings

func (c *Client) EnrichFindings(ctx context.Context, findings []ctis.Finding) ([]ctis.Finding, error)

EnrichFindings adds EPSS and KEV data to findings with CVE IDs.

func (*Client) FailCommand

func (c *Client) FailCommand(ctx context.Context, cmdID string, errorMsg string) error

FailCommand marks a command as failed with an error message.

func (*Client) FilterSuppressedFindings

func (c *Client) FilterSuppressedFindings(findings []ctis.Finding, rules []SuppressionRule) []ctis.Finding

FilterSuppressedFindings removes findings that match suppression rules. This is used by the security gate to exclude false positives.

func (*Client) GetCommands

func (c *Client) GetCommands(ctx context.Context) (*core.GetCommandsResponse, error)

GetCommands retrieves pending commands from the server (implements core.CommandClient).

func (*Client) GetEPSSScores

func (c *Client) GetEPSSScores(ctx context.Context, cveIDs []string) ([]EPSSScore, error)

GetEPSSScores fetches EPSS scores for the given CVE IDs.

func (*Client) GetKEVEntries

func (c *Client) GetKEVEntries(ctx context.Context, cveIDs []string) ([]KEVEntry, error)

GetKEVEntries fetches CISA KEV entries for the given CVE IDs.

func (*Client) GetRetryQueueStats

func (c *Client) GetRetryQueueStats(ctx context.Context) (*retry.QueueStats, error)

GetRetryQueueStats returns statistics about the retry queue.

func (*Client) GetRetryWorkerStats

func (c *Client) GetRetryWorkerStats() (*retry.WorkerStats, error)

GetRetryWorkerStats returns statistics about the retry worker.

func (*Client) GetSuppressions

func (c *Client) GetSuppressions(ctx context.Context) ([]SuppressionRule, error)

GetSuppressions fetches active suppression rules from the platform. These rules are used to filter out false positives from scan results.

func (*Client) PollCommands

func (c *Client) PollCommands(ctx context.Context, limit int) ([]Command, error)

PollCommands retrieves pending commands for this agent.

func (*Client) ProcessRetryQueueNow

func (c *Client) ProcessRetryQueueNow(ctx context.Context) error

ProcessRetryQueueNow immediately processes pending items in the retry queue. This is useful for testing or manual intervention.

func (*Client) PushAssets

func (c *Client) PushAssets(ctx context.Context, report *ctis.Report) (*core.PushResult, error)

PushAssets sends assets to OpenCTEM. If the push fails and a retry queue is configured, the report is queued for later retry.

func (*Client) PushExposures

func (c *Client) PushExposures(ctx context.Context, events []ExposureEvent) (*PushExposuresResult, error)

PushExposures sends exposure events to OpenCTEM.

func (*Client) PushFindings

func (c *Client) PushFindings(ctx context.Context, report *ctis.Report) (*core.PushResult, error)

PushFindings sends findings to OpenCTEM. If the push fails and a retry queue is configured, the report is queued for later retry.

func (*Client) PushReport

func (c *Client) PushReport(ctx context.Context, report *ctis.Report) error

PushReport implements retry.ReportPusher interface. This is used by the retry worker to push items from the queue.

func (*Client) ReportCommandProgress

func (c *Client) ReportCommandProgress(ctx context.Context, cmdID string, progress int, message string) error

ReportCommandProgress reports progress of command execution.

func (*Client) ReportCommandResult

func (c *Client) ReportCommandResult(ctx context.Context, cmdID string, result *core.CommandResult) error

ReportCommandResult reports the result of command execution (implements core.CommandClient).

func (*Client) SendHeartbeat

func (c *Client) SendHeartbeat(ctx context.Context, status *core.AgentStatus) error

SendHeartbeat sends a heartbeat to OpenCTEM.

func (*Client) SetVerbose

func (c *Client) SetVerbose(v bool)

SetVerbose sets verbose mode.

func (*Client) StartCommand

func (c *Client) StartCommand(ctx context.Context, cmdID string) error

StartCommand marks a command as started.

func (*Client) StartRetryWorker

func (c *Client) StartRetryWorker(ctx context.Context) error

StartRetryWorker starts the background retry worker. EnableRetryQueue must be called first.

func (*Client) StopRetryWorker

func (c *Client) StopRetryWorker(ctx context.Context) error

StopRetryWorker stops the background retry worker gracefully.

func (*Client) TestConnection

func (c *Client) TestConnection(ctx context.Context) error

TestConnection tests the API connection.

func (*Client) UploadChunk

func (c *Client) UploadChunk(ctx context.Context, data *chunk.ChunkData) error

UploadChunk uploads a single chunk of a large report. This implements the chunk.Uploader interface.

type Command

type Command struct {
	ID             string          `json:"id"`
	TenantID       string          `json:"tenant_id,omitempty"`
	SourceID       string          `json:"source_id,omitempty"`
	Type           string          `json:"type"`
	Priority       string          `json:"priority"`
	Payload        json.RawMessage `json:"payload,omitempty"`
	Status         string          `json:"status"`
	ErrorMessage   string          `json:"error_message,omitempty"`
	CreatedAt      time.Time       `json:"created_at"`
	ExpiresAt      *time.Time      `json:"expires_at,omitempty"`
	AcknowledgedAt *time.Time      `json:"acknowledged_at,omitempty"`
	StartedAt      *time.Time      `json:"started_at,omitempty"`
	CompletedAt    *time.Time      `json:"completed_at,omitempty"`
	Result         json.RawMessage `json:"result,omitempty"`
}

Command represents a command from the server.

type Config

type Config struct {
	BaseURL    string        `yaml:"base_url" json:"base_url"`
	APIKey     string        `yaml:"api_key" json:"api_key"`
	AgentID    string        `yaml:"agent_id" json:"agent_id"` // Registered agent ID for audit trail
	Timeout    time.Duration `yaml:"timeout" json:"timeout"`
	MaxRetries int           `yaml:"max_retries" json:"max_retries"`
	RetryDelay time.Duration `yaml:"retry_delay" json:"retry_delay"`
	Verbose    bool          `yaml:"verbose" json:"verbose"`

	// Compression configuration
	EnableCompression bool   `yaml:"enable_compression" json:"enable_compression"` // Enable request compression (default: true)
	CompressionAlgo   string `yaml:"compression_algo" json:"compression_algo"`     // "zstd" or "gzip" (default: "zstd")
	CompressionLevel  int    `yaml:"compression_level" json:"compression_level"`   // 1-9 (default: 3)

	// Retry queue configuration (optional)
	EnableRetryQueue bool          `yaml:"enable_retry_queue" json:"enable_retry_queue"`
	RetryQueueDir    string        `yaml:"retry_queue_dir" json:"retry_queue_dir"`       // Default: ~/.openctem/retry-queue
	RetryInterval    time.Duration `yaml:"retry_interval" json:"retry_interval"`         // Default: 5m
	RetryMaxAttempts int           `yaml:"retry_max_attempts" json:"retry_max_attempts"` // Default: 10
	RetryTTL         time.Duration `yaml:"retry_ttl" json:"retry_ttl"`                   // Default: 7d (168h)
}

Config holds client configuration.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns default client config.

type EPSSScore

type EPSSScore struct {
	CVEID      string    `json:"cve_id"`
	Score      float64   `json:"score"`      // 0.0 to 1.0
	Percentile float64   `json:"percentile"` // 0.0 to 100.0
	Date       time.Time `json:"date"`
}

EPSSScore represents an EPSS score for a CVE.

type ExposureEvent

type ExposureEvent struct {
	// Event type: new_asset, asset_removed, exposure_detected, exposure_resolved
	Type string `json:"type"`

	// Asset identifier
	AssetID   string `json:"asset_id,omitempty"`
	AssetType string `json:"asset_type,omitempty"`
	AssetName string `json:"asset_name,omitempty"`

	// Exposure details
	ExposureType string `json:"exposure_type,omitempty"` // port_open, service_exposed, etc.
	Protocol     string `json:"protocol,omitempty"`
	Port         int    `json:"port,omitempty"`
	Service      string `json:"service,omitempty"`

	// Detection info
	DetectedAt  time.Time `json:"detected_at"`
	DetectedBy  string    `json:"detected_by,omitempty"` // scan source
	Severity    string    `json:"severity,omitempty"`
	Description string    `json:"description,omitempty"`

	// Resolution
	ResolvedAt *time.Time `json:"resolved_at,omitempty"`

	// Metadata
	Tags       []string       `json:"tags,omitempty"`
	Properties map[string]any `json:"properties,omitempty"`
}

ExposureEvent represents an attack surface change event.

type HTTPError

type HTTPError struct {
	StatusCode int    `json:"status_code"`
	Body       string `json:"body"`
	RequestID  string `json:"request_id,omitempty"`
}

HTTPError represents an HTTP error response.

func IsHTTPError

func IsHTTPError(err error) (*HTTPError, bool)

IsHTTPError checks if err is an HTTPError and returns it.

func (*HTTPError) Error

func (e *HTTPError) Error() string

type HeartbeatRequest

type HeartbeatRequest struct {
	Name       string          `json:"name,omitempty"`
	Status     core.AgentState `json:"status"`
	Version    string          `json:"version,omitempty"`
	Hostname   string          `json:"hostname,omitempty"`
	Message    string          `json:"message,omitempty"`
	Scanners   []string        `json:"scanners,omitempty"`
	Collectors []string        `json:"collectors,omitempty"`
	Uptime     int64           `json:"uptime_seconds,omitempty"`
	TotalScans int64           `json:"total_scans,omitempty"`
	Errors     int64           `json:"errors,omitempty"`

	// System Metrics
	CPUPercent    float64 `json:"cpu_percent,omitempty"`
	MemoryPercent float64 `json:"memory_percent,omitempty"`
	ActiveJobs    int     `json:"active_jobs,omitempty"`
	Region        string  `json:"region,omitempty"`
}

HeartbeatRequest is the heartbeat payload.

type IngestResponse

type IngestResponse struct {
	ScanID          string   `json:"scan_id"`
	AssetsCreated   int      `json:"assets_created"`
	AssetsUpdated   int      `json:"assets_updated"`
	FindingsCreated int      `json:"findings_created"`
	FindingsUpdated int      `json:"findings_updated"`
	FindingsSkipped int      `json:"findings_skipped"`
	Errors          []string `json:"errors,omitempty"`
}

IngestResponse is the response from ingest endpoints.

type KEVEntry

type KEVEntry struct {
	CVEID                      string    `json:"cve_id"`
	VendorProject              string    `json:"vendor_project"`
	Product                    string    `json:"product"`
	VulnerabilityName          string    `json:"vulnerability_name"`
	DateAdded                  time.Time `json:"date_added"`
	ShortDescription           string    `json:"short_description"`
	RequiredAction             string    `json:"required_action"`
	DueDate                    time.Time `json:"due_date"`
	KnownRansomwareCampaignUse string    `json:"known_ransomware_campaign_use"`
}

KEVEntry represents a CISA Known Exploited Vulnerabilities entry.

type Option

type Option func(*Client)

Option is a function that configures the client.

func WithAPIKey

func WithAPIKey(key string) Option

WithAPIKey sets the API key.

func WithAgentID

func WithAgentID(id string) Option

WithAgentID sets the agent ID for tracking which agent is pushing data.

func WithBaseURL

func WithBaseURL(url string) Option

WithBaseURL sets the API base URL.

func WithCompression

func WithCompression(algorithm string, level int) Option

WithCompression enables request compression with the specified algorithm. Supported algorithms: "zstd" (recommended), "gzip"

func WithRetry

func WithRetry(maxRetries int, retryDelay time.Duration) Option

WithRetry sets retry configuration.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the HTTP timeout.

func WithVerbose

func WithVerbose(v bool) Option

WithVerbose enables verbose logging.

func WithoutCompression

func WithoutCompression() Option

WithoutCompression disables request compression.

type PushExposuresResult

type PushExposuresResult struct {
	EventsCreated int `json:"events_created"`
	EventsUpdated int `json:"events_updated"`
	EventsSkipped int `json:"events_skipped"`
}

PushExposuresResult is the result of pushing exposure events.

type RetryQueueConfig

type RetryQueueConfig struct {
	// Dir is the directory to store queue files.
	// Default: ~/.openctem/retry-queue
	Dir string

	// MaxSize is the maximum number of items in the queue.
	// Default: 1000
	MaxSize int

	// Interval is how often to check the queue for items to retry.
	// Default: 5 minutes
	Interval time.Duration

	// BatchSize is the maximum number of items to process per check.
	// Default: 10
	BatchSize int

	// MaxAttempts is the maximum number of retry attempts per item.
	// Default: 10
	MaxAttempts int

	// TTL is how long to keep items in the queue before expiring.
	// Default: 7 days
	TTL time.Duration

	// Backoff configures the retry backoff behavior.
	Backoff *retry.BackoffConfig

	// AutoStart starts the retry worker automatically.
	// Default: true
	AutoStart bool
}

RetryQueueConfig configures the retry queue.

func DefaultRetryQueueConfig

func DefaultRetryQueueConfig() *RetryQueueConfig

DefaultRetryQueueConfig returns a configuration with default values.

type SuppressionRule

type SuppressionRule struct {
	RuleID      string  `json:"rule_id,omitempty"`
	ToolName    string  `json:"tool_name,omitempty"`
	PathPattern string  `json:"path_pattern,omitempty"`
	AssetID     *string `json:"asset_id,omitempty"`
	ExpiresAt   *string `json:"expires_at,omitempty"`
}

SuppressionRule represents a platform-controlled suppression rule.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL