counter

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2026 License: AGPL-3.0 Imports: 27 Imported by: 0

Documentation

Overview

Package counter implements the Counter TUI operator interface.

Package counter implements the Counter TUI operator interface.

Package counter implements the Counter operator interface components.

Package counter provides SSH agent-based authentication for the Counter TUI.

Index

Constants

View Source
const (
	AnalysisMetadataSyncStatusStarted   = "started"
	AnalysisMetadataSyncStatusCompleted = "completed"
	AnalysisMetadataSyncStatusFailed    = "failed"
)

Variables

View Source
var (
	// ErrNoSSHAgent indicates SSH_AUTH_SOCK is not set.
	ErrNoSSHAgent = errors.New("SSH_AUTH_SOCK not set - is ssh-agent running?")

	// ErrNoKeysInAgent indicates the SSH agent has no keys.
	ErrNoKeysInAgent = errors.New("no keys found in SSH agent")

	// ErrKeyNotFound indicates the specified key was not found in the agent.
	ErrKeyNotFound = errors.New("specified key not found in SSH agent")

	// ErrAuthFailed indicates authentication failed.
	ErrAuthFailed = errors.New("authentication failed")
)

Functions

func ConfigPath

func ConfigPath() string

ConfigPath returns the path to the config file. Respects SMOKEDMEAT_CONFIG_DIR env var, defaults to ~/.smokedmeat.

func GenerateOperatorName

func GenerateOperatorName() string

GenerateOperatorName generates a random operator name like Docker container names.

func ListAgentKeys

func ListAgentKeys() ([]*agent.Key, error)

ListAgentKeys returns the SSH keys available in the agent. Useful for debugging or letting users select which key to use.

func SaveConfig

func SaveConfig(cfg *Config) error

SaveConfig saves config to ~/.smokedmeat/config.yaml

Types

type AnalysisMetadataSyncPayload

type AnalysisMetadataSyncPayload struct {
	AnalysisID string    `json:"analysis_id,omitempty"`
	SessionID  string    `json:"session_id,omitempty"`
	Target     string    `json:"target,omitempty"`
	TargetType string    `json:"target_type,omitempty"`
	Status     string    `json:"status"`
	Message    string    `json:"message,omitempty"`
	ReposTotal int       `json:"repos_total,omitempty"`
	Error      string    `json:"error,omitempty"`
	UpdatedAt  time.Time `json:"updated_at,omitempty"`
}

type AnalysisProgressPayload

type AnalysisProgressPayload struct {
	AnalysisID     string    `json:"analysis_id,omitempty"`
	SessionID      string    `json:"session_id,omitempty"`
	Target         string    `json:"target,omitempty"`
	TargetType     string    `json:"target_type,omitempty"`
	Deep           bool      `json:"deep,omitempty"`
	Phase          string    `json:"phase"`
	Message        string    `json:"message,omitempty"`
	CurrentRepo    string    `json:"current_repo,omitempty"`
	ReposCompleted int       `json:"repos_completed,omitempty"`
	ReposTotal     int       `json:"repos_total,omitempty"`
	SecretFindings int       `json:"secret_findings,omitempty"`
	StartedAt      time.Time `json:"started_at,omitempty"`
	UpdatedAt      time.Time `json:"updated_at,omitempty"`
}

type AnalyzeRequest

type AnalyzeRequest struct {
	// Token is the GitHub token for API access.
	// SECURITY: This is the OPERATOR's token, used ephemerally by Kitchen.
	// It is NOT stored as loot.
	Token string `json:"token"`

	// Target is the org or org/repo to analyze.
	Target string `json:"target"`

	// TargetType is "org" or "repo".
	TargetType string `json:"target_type"`

	// Deep enables gitleaks scanning for private keys.
	Deep bool `json:"deep,omitempty"`

	// SessionID identifies the operator session (for known entity lookups).
	SessionID string `json:"session_id,omitempty"`

	AnalysisID string `json:"analysis_id,omitempty"`
}

AnalyzeRequest is the request body for the /analyze endpoint.

type AnalyzeResultStatusResponse

type AnalyzeResultStatusResponse struct {
	AnalysisID string                  `json:"analysis_id"`
	Status     string                  `json:"status"`
	Result     *poutine.AnalysisResult `json:"result,omitempty"`
	Error      string                  `json:"error,omitempty"`
}

type AppInstallation

type AppInstallation struct {
	ID      int64  `json:"id"`
	Account string `json:"account"`
	AppSlug string `json:"app_slug"`
}

type Beacon

type Beacon struct {
	AgentID       string     `json:"agent_id"`
	Hostname      string     `json:"hostname"`
	OS            string     `json:"os"`
	Arch          string     `json:"arch"`
	Timestamp     time.Time  `json:"timestamp"`
	DwellDeadline *time.Time `json:"dwell_deadline,omitempty"`
	CallbackID    string     `json:"callback_id,omitempty"`
	CallbackMode  string     `json:"callback_mode,omitempty"`
}

Beacon represents an agent heartbeat message.

type BeaconPayload

type BeaconPayload struct {
	AgentID       string     `json:"agent_id"`
	SessionID     string     `json:"session_id,omitempty"`
	Hostname      string     `json:"hostname,omitempty"`
	OS            string     `json:"os,omitempty"`
	Arch          string     `json:"arch,omitempty"`
	Timestamp     time.Time  `json:"timestamp"`
	DwellDeadline *time.Time `json:"dwell_deadline,omitempty"`
	CallbackID    string     `json:"callback_id,omitempty"`
	CallbackMode  string     `json:"callback_mode,omitempty"`
}

BeaconPayload represents agent beacon data from Kitchen.

type CallbackControlRequest

type CallbackControlRequest struct {
	Action string `json:"action"`
}

type CallbackPayload

type CallbackPayload struct {
	ID            string            `json:"id"`
	SessionID     string            `json:"session_id"`
	ResponseType  string            `json:"response_type"`
	CreatedAt     time.Time         `json:"created_at"`
	ExpiresAt     *time.Time        `json:"expires_at,omitempty"`
	CalledBack    bool              `json:"called_back"`
	CallbackAt    *time.Time        `json:"callback_at,omitempty"`
	CallbackIP    string            `json:"callback_ip,omitempty"`
	DwellTime     string            `json:"dwell_time,omitempty"`
	Persistent    bool              `json:"persistent"`
	MaxCallbacks  int               `json:"max_callbacks,omitempty"`
	DefaultMode   string            `json:"default_mode,omitempty"`
	NextMode      string            `json:"next_mode,omitempty"`
	CallbackCount int               `json:"callback_count"`
	LastAgentID   string            `json:"last_agent_id,omitempty"`
	RevokedAt     *time.Time        `json:"revoked_at,omitempty"`
	Metadata      map[string]string `json:"metadata,omitempty"`
}

type Client

type Client struct {
	KitchenURL string
	AuthToken  string
	SessionID  string
	HTTPClient *http.Client
}

Client is a thin client for interacting with Kitchen's analysis endpoints. Counter delegates all heavy lifting (poutine analysis) to Kitchen.

func NewClient

func NewClient(kitchenURL, authToken, sessionID string) *Client

NewClient creates a new Kitchen client. SessionID is required — Kitchen uses it to track known entities and repo visibility.

func (*Client) Analyze

func (c *Client) Analyze(ctx context.Context, token, target, targetType string) (*poutine.AnalysisResult, error)

Analyze performs a poutine analysis by delegating to Kitchen. The token is sent to Kitchen for ephemeral use - it is never stored.

func (*Client) AnalyzeWithID

func (c *Client) AnalyzeWithID(ctx context.Context, token, target, targetType, analysisID string) (*poutine.AnalysisResult, error)

func (*Client) DeepAnalyze

func (c *Client) DeepAnalyze(ctx context.Context, token, target, targetType string) (*poutine.AnalysisResult, error)

DeepAnalyze performs poutine analysis plus gitleaks secret scanning.

func (*Client) DeepAnalyzeWithID

func (c *Client) DeepAnalyzeWithID(ctx context.Context, token, target, targetType, analysisID string) (*poutine.AnalysisResult, error)

func (*Client) FetchAnalysisResult

func (c *Client) FetchAnalysisResult(ctx context.Context, analysisID string) (*AnalyzeResultStatusResponse, error)

type Config

type Config struct {
	KitchenURL               string `yaml:"kitchen_url"`
	Operator                 string `yaml:"operator"`
	KeyComment               string `yaml:"key_comment,omitempty"`
	Token                    string `yaml:"token,omitempty"`
	TokenSource              string `yaml:"token_source,omitempty"`
	OPSecretRef              string `yaml:"op_secret_ref,omitempty"`
	Target                   string `yaml:"target,omitempty"`
	LastAnalyzedTarget       string `yaml:"last_analyzed_target,omitempty"`
	InitialAccessToken       string `yaml:"initial_access_token,omitempty"`
	InitialAccessTokenSource string `yaml:"initial_access_token_source,omitempty"`
	Theme                    string `yaml:"theme,omitempty"`
}

Config holds Counter configuration.

func LoadConfig

func LoadConfig() (*Config, error)

LoadConfig loads config from ~/.smokedmeat/config.yaml

type CreateInstallationTokenRequest

type CreateInstallationTokenRequest struct {
	PEM            string `json:"pem"`
	AppID          string `json:"app_id"`
	InstallationID int64  `json:"installation_id"`
}

type CreateInstallationTokenResponse

type CreateInstallationTokenResponse struct {
	Token       string            `json:"token"`
	ExpiresAt   time.Time         `json:"expires_at"`
	Permissions map[string]string `json:"permissions,omitempty"`
	Error       string            `json:"error,omitempty"`
}

type DeployCommentRequest

type DeployCommentRequest struct {
	Token     string            `json:"token"`
	Vuln      VulnerabilityInfo `json:"vuln"`
	Payload   string            `json:"payload"`
	Target    string            `json:"target,omitempty"`
	StagerID  string            `json:"stager_id,omitempty"`
	AutoClose *bool             `json:"auto_close,omitempty"`
}

type DeployCommentResponse

type DeployCommentResponse struct {
	CommentURL string `json:"comment_url"`
	Error      string `json:"error,omitempty"`
}

type DeployDispatchRequest

type DeployDispatchRequest struct {
	Token        string                 `json:"token"`
	Owner        string                 `json:"owner"`
	Repo         string                 `json:"repo"`
	WorkflowFile string                 `json:"workflow_file"`
	Ref          string                 `json:"ref"`
	Inputs       map[string]interface{} `json:"inputs,omitempty"`
}

type DeployDispatchResponse

type DeployDispatchResponse struct {
	Error string `json:"error,omitempty"`
}

type DeployIssueRequest

type DeployIssueRequest struct {
	Token       string            `json:"token"`
	Vuln        VulnerabilityInfo `json:"vuln"`
	Payload     string            `json:"payload"`
	CommentMode bool              `json:"comment_mode,omitempty"`
	StagerID    string            `json:"stager_id,omitempty"`
	AutoClose   *bool             `json:"auto_close,omitempty"`
}

type DeployIssueResponse

type DeployIssueResponse struct {
	IssueURL string `json:"issue_url"`
	Error    string `json:"error,omitempty"`
}

type DeployLOTPRequest

type DeployLOTPRequest struct {
	Token       string            `json:"token"`
	RepoName    string            `json:"repo_name"`
	Vuln        VulnerabilityInfo `json:"vuln,omitempty"`
	StagerID    string            `json:"stager_id"`
	LOTPTool    string            `json:"lotp_tool,omitempty"`
	LOTPAction  string            `json:"lotp_action,omitempty"`
	LOTPTargets []string          `json:"lotp_targets,omitempty"`
	CallbackURL string            `json:"callback_url,omitempty"`
}

type DeployLOTPResponse

type DeployLOTPResponse struct {
	PRURL string `json:"pr_url"`
	Error string `json:"error,omitempty"`
}

type DeployPRRequest

type DeployPRRequest struct {
	Token     string            `json:"token"`
	Vuln      VulnerabilityInfo `json:"vuln"`
	Payload   string            `json:"payload"`
	StagerID  string            `json:"stager_id,omitempty"`
	Draft     *bool             `json:"draft,omitempty"`
	AutoClose *bool             `json:"auto_close,omitempty"`
}

type DeployPRResponse

type DeployPRResponse struct {
	PRURL string `json:"pr_url"`
	Error string `json:"error,omitempty"`
}

type DeployPreflightCapability

type DeployPreflightCapability struct {
	State  string `json:"state"`
	Reason string `json:"reason,omitempty"`
}

type DeployPreflightCheck

type DeployPreflightCheck struct {
	Name   string `json:"name"`
	State  string `json:"state"`
	Reason string `json:"reason,omitempty"`
}

type DeployPreflightRequest

type DeployPreflightRequest struct {
	Token            string            `json:"token"`
	Vuln             VulnerabilityInfo `json:"vuln"`
	TokenType        string            `json:"token_type,omitempty"`
	TokenOwner       string            `json:"token_owner,omitempty"`
	Scopes           []string          `json:"scopes,omitempty"`
	KnownPermissions map[string]string `json:"known_permissions,omitempty"`
	IssueNumber      int               `json:"issue_number,omitempty"`
	PRNumber         int               `json:"pr_number,omitempty"`
}

type DeployPreflightResponse

type DeployPreflightResponse struct {
	CacheHit     bool                                 `json:"cache_hit"`
	Capabilities map[string]DeployPreflightCapability `json:"capabilities"`
	Checks       []DeployPreflightCheck               `json:"checks,omitempty"`
}

type ExpressDataPayload

type ExpressDataPayload struct {
	AgentID          string                    `json:"agent_id"`
	SessionID        string                    `json:"session_id"`
	Hostname         string                    `json:"hostname"`
	Secrets          []ExtractedSecret         `json:"secrets"`
	Vars             map[string]string         `json:"vars,omitempty"`
	TokenPermissions map[string]string         `json:"token_permissions,omitempty"`
	CachePoison      *models.CachePoisonStatus `json:"cache_poison,omitempty"`
	Timestamp        time.Time                 `json:"timestamp"`
	Repository       string                    `json:"repository,omitempty"`
	Workflow         string                    `json:"workflow,omitempty"`
	Job              string                    `json:"job,omitempty"`
	CallbackID       string                    `json:"callback_id,omitempty"`
	CallbackMode     string                    `json:"callback_mode,omitempty"`
}

ExpressDataPayload represents extracted secrets from express mode agents.

type ExtractedSecret

type ExtractedSecret struct {
	Name      string `json:"name"`
	Value     string `json:"value"`
	Type      string `json:"type"`
	Source    string `json:"source"`
	HighValue bool   `json:"high_value"`

	Repository string `json:"repository,omitempty"`
	Workflow   string `json:"workflow,omitempty"`
	Job        string `json:"job,omitempty"`
}

ExtractedSecret represents a secret extracted from express data.

type FetchTokenInfoRequest

type FetchTokenInfoRequest struct {
	Token  string `json:"token"`
	Source string `json:"source"`
}

type FetchTokenInfoResponse

type FetchTokenInfoResponse struct {
	Owner        string   `json:"owner"`
	Scopes       []string `json:"scopes,omitempty"`
	RateLimitMax int      `json:"rate_limit_max,omitempty"`
	TokenType    string   `json:"token_type"`
	StatusCode   int      `json:"status_code"`
	Error        string   `json:"error,omitempty"`
}

type GetUserRequest

type GetUserRequest struct {
	Token string `json:"token"`
}

type GetUserResponse

type GetUserResponse struct {
	Login  string   `json:"login"`
	Scopes []string `json:"scopes,omitempty"`
	Error  string   `json:"error,omitempty"`
}

type HistoryPayload

type HistoryPayload struct {
	ID          string    `json:"id"`
	Type        string    `json:"type"`
	Timestamp   time.Time `json:"timestamp"`
	SessionID   string    `json:"session_id,omitempty"`
	Target      string    `json:"target,omitempty"`
	TargetType  string    `json:"target_type,omitempty"`
	TokenType   string    `json:"token_type,omitempty"`
	VulnID      string    `json:"vuln_id,omitempty"`
	Repository  string    `json:"repository,omitempty"`
	StagerID    string    `json:"stager_id,omitempty"`
	PRURL       string    `json:"pr_url,omitempty"`
	Outcome     string    `json:"outcome,omitempty"`
	ErrorDetail string    `json:"error_detail,omitempty"`
	AgentID     string    `json:"agent_id,omitempty"`
}

HistoryPayload represents an operation history entry from Kitchen.

type KeyInfo

type KeyInfo struct {
	Fingerprint   string
	Comment       string
	Type          string
	AuthorizedKey string // Full line for authorized_keys file
}

KeyInfo contains information about an SSH key.

func GetKeyInfo

func GetKeyInfo() ([]KeyInfo, error)

GetKeyInfo returns information about SSH keys in the agent.

type KitchenAPI

type KitchenAPI interface {
	PublishOrder(ctx context.Context, order *models.Order) error
	FetchPantry(ctx context.Context) (*pantry.Pantry, error)
	FetchHistory(ctx context.Context, limit int) ([]HistoryPayload, error)
	RecordHistory(ctx context.Context, entry HistoryPayload) error
	FetchCallbacks(ctx context.Context, sessionID string) ([]CallbackPayload, error)
	ControlCallback(ctx context.Context, callbackID string, request CallbackControlRequest) (*CallbackPayload, error)
	FetchKnownEntities(ctx context.Context, sessionID string) ([]KnownEntityPayload, error)
	RecordKnownEntity(ctx context.Context, entity KnownEntityPayload) error
	Purge(ctx context.Context, req PurgeRequest) (*PurgeResponse, error)
	StartConsuming() error
	IsConnected() bool
	Close()
	Reconnect(ctx context.Context) error
	DeployPR(ctx context.Context, req DeployPRRequest) (DeployPRResponse, error)
	DeployIssue(ctx context.Context, req DeployIssueRequest) (DeployIssueResponse, error)
	DeployComment(ctx context.Context, req DeployCommentRequest) (DeployCommentResponse, error)
	DeployLOTP(ctx context.Context, req DeployLOTPRequest) (DeployLOTPResponse, error)
	TriggerDispatch(ctx context.Context, req DeployDispatchRequest) error
	FetchDeployPreflight(ctx context.Context, req DeployPreflightRequest) (*DeployPreflightResponse, error)
	ListReposWithInfo(ctx context.Context, token string) ([]RepoInfo, error)
	ListWorkflowsWithDispatch(ctx context.Context, token, owner, repo string) ([]string, error)
	GetAuthenticatedUser(ctx context.Context, token string) (GetUserResponse, error)
	FetchTokenInfo(ctx context.Context, token, source string) (*FetchTokenInfoResponse, error)
	ListAppInstallations(ctx context.Context, pem, appID string) ([]AppInstallation, error)
	CreateInstallationToken(ctx context.Context, pem, appID string, installationID int64) (*CreateInstallationTokenResponse, error)
	RegisterCallback(ctx context.Context, stagerID string, req RegisterCallbackRequest) (*RegisterCallbackResponse, error)
	PrepareCachePoisonDeployment(ctx context.Context, req PrepareCachePoisonRequest) (*PrepareCachePoisonResponse, error)
	SetCallbacks(onBeacon func(Beacon), onColeslaw func(*models.Coleslaw), onError func(error))
	SetEventCallback(onEvent func(KitchenEvent))
	SetHistoryCallback(onHistory func(HistoryPayload))
	SetExpressDataCallback(onExpressData func(ExpressDataPayload))
	SetAnalysisProgressCallback(onAnalysisProgress func(AnalysisProgressPayload))
	SetAnalysisMetadataSyncCallback(onAnalysisMetadataSync func(AnalysisMetadataSyncPayload))
	SetAuthExpiredCallback(onAuthExpired func())
	SetReconnectCallbacks(onReconnecting func(attempt int), onReconnected func())
}

KitchenAPI defines the interface for Kitchen client operations used by the TUI.

type KitchenClient

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

KitchenClient manages WebSocket connection to the Kitchen C2 server. This replaces direct NATS connection for production deployments.

func NewKitchenClient

func NewKitchenClient(config KitchenConfig) *KitchenClient

NewKitchenClient creates a new WebSocket client for the Counter.

func (*KitchenClient) Close

func (k *KitchenClient) Close()

Close closes the WebSocket connection and stops reconnection.

func (*KitchenClient) Connect

func (k *KitchenClient) Connect(ctx context.Context) error

Connect establishes the WebSocket connection to Kitchen.

func (*KitchenClient) ControlCallback

func (k *KitchenClient) ControlCallback(ctx context.Context, callbackID string, request CallbackControlRequest) (*CallbackPayload, error)

func (*KitchenClient) CreateInstallationToken

func (k *KitchenClient) CreateInstallationToken(ctx context.Context, pemData, appID string, installationID int64) (*CreateInstallationTokenResponse, error)

func (*KitchenClient) DeployComment

func (*KitchenClient) DeployIssue

func (*KitchenClient) DeployLOTP

func (*KitchenClient) DeployPR

func (*KitchenClient) FetchCallbacks

func (k *KitchenClient) FetchCallbacks(ctx context.Context, sessionID string) ([]CallbackPayload, error)

func (*KitchenClient) FetchDeployPreflight

func (k *KitchenClient) FetchDeployPreflight(ctx context.Context, req DeployPreflightRequest) (*DeployPreflightResponse, error)

func (*KitchenClient) FetchHistory

func (k *KitchenClient) FetchHistory(ctx context.Context, limit int) ([]HistoryPayload, error)

FetchHistory retrieves operation history from Kitchen via HTTP.

func (*KitchenClient) FetchKnownEntities

func (k *KitchenClient) FetchKnownEntities(ctx context.Context, sessionID string) ([]KnownEntityPayload, error)

FetchKnownEntities retrieves known entities from Kitchen for the given session.

func (*KitchenClient) FetchPantry

func (k *KitchenClient) FetchPantry(ctx context.Context) (*pantry.Pantry, error)

FetchPantry retrieves the attack graph from Kitchen via HTTP.

func (*KitchenClient) FetchTokenInfo

func (k *KitchenClient) FetchTokenInfo(ctx context.Context, token, source string) (*FetchTokenInfoResponse, error)

func (*KitchenClient) GetAuthenticatedUser

func (k *KitchenClient) GetAuthenticatedUser(ctx context.Context, token string) (GetUserResponse, error)

func (*KitchenClient) IsConnected

func (k *KitchenClient) IsConnected() bool

IsConnected returns true if connected to Kitchen.

func (*KitchenClient) ListAppInstallations

func (k *KitchenClient) ListAppInstallations(ctx context.Context, pemData, appID string) ([]AppInstallation, error)

func (*KitchenClient) ListReposWithInfo

func (k *KitchenClient) ListReposWithInfo(ctx context.Context, token string) ([]RepoInfo, error)

func (*KitchenClient) ListWorkflowsWithDispatch

func (k *KitchenClient) ListWorkflowsWithDispatch(ctx context.Context, token, owner, repo string) ([]string, error)

func (*KitchenClient) PrepareCachePoisonDeployment

func (k *KitchenClient) PrepareCachePoisonDeployment(ctx context.Context, req PrepareCachePoisonRequest) (*PrepareCachePoisonResponse, error)

func (*KitchenClient) PublishOrder

func (k *KitchenClient) PublishOrder(ctx context.Context, order *models.Order) error

PublishOrder sends an order to Kitchen for delivery to an agent. This matches the KitchenAPI interface.

func (*KitchenClient) Purge

func (*KitchenClient) Reconnect

func (k *KitchenClient) Reconnect(ctx context.Context) error

Reconnect attempts to reconnect to Kitchen.

func (*KitchenClient) RecordHistory

func (k *KitchenClient) RecordHistory(ctx context.Context, entry HistoryPayload) error

RecordHistory posts a new history entry to Kitchen.

func (*KitchenClient) RecordKnownEntity

func (k *KitchenClient) RecordKnownEntity(ctx context.Context, entity KnownEntityPayload) error

RecordKnownEntity posts a new known entity to Kitchen.

func (*KitchenClient) RegisterCallback

func (k *KitchenClient) RegisterCallback(ctx context.Context, stagerID string, req RegisterCallbackRequest) (*RegisterCallbackResponse, error)

func (*KitchenClient) SetAnalysisMetadataSyncCallback

func (k *KitchenClient) SetAnalysisMetadataSyncCallback(onAnalysisMetadataSync func(AnalysisMetadataSyncPayload))

func (*KitchenClient) SetAnalysisProgressCallback

func (k *KitchenClient) SetAnalysisProgressCallback(onAnalysisProgress func(AnalysisProgressPayload))

func (*KitchenClient) SetAuthExpiredCallback

func (k *KitchenClient) SetAuthExpiredCallback(onAuthExpired func())

SetAuthExpiredCallback sets the callback for when authentication expires.

func (*KitchenClient) SetCallbacks

func (k *KitchenClient) SetCallbacks(onBeacon func(Beacon), onColeslaw func(*models.Coleslaw), onError func(error))

SetCallbacks sets the callbacks for Kitchen events. This matches the KitchenAPI interface.

func (*KitchenClient) SetEventCallback

func (k *KitchenClient) SetEventCallback(onEvent func(KitchenEvent))

SetEventCallback sets an optional callback for system events.

func (*KitchenClient) SetExpressDataCallback

func (k *KitchenClient) SetExpressDataCallback(onExpressData func(ExpressDataPayload))

SetExpressDataCallback sets the callback for express data broadcasts.

func (*KitchenClient) SetHistoryCallback

func (k *KitchenClient) SetHistoryCallback(onHistory func(HistoryPayload))

SetHistoryCallback sets the callback for history entry broadcasts.

func (*KitchenClient) SetReconnectCallbacks

func (k *KitchenClient) SetReconnectCallbacks(onReconnecting func(attempt int), onReconnected func())

SetReconnectCallbacks sets callbacks for reconnection events.

func (*KitchenClient) StartConsuming

func (k *KitchenClient) StartConsuming() error

StartConsuming starts receiving messages from Kitchen. This matches the KitchenAPI interface.

func (*KitchenClient) TriggerDispatch

func (k *KitchenClient) TriggerDispatch(ctx context.Context, req DeployDispatchRequest) error

type KitchenConfig

type KitchenConfig struct {
	URL       string // e.g., "wss://kitchen.example.com/ws" or "ws://localhost:8080/ws"
	SessionID string
	Token     string // JWT authentication token (optional if auth not required)
}

KitchenConfig holds configuration for the Kitchen WebSocket client.

type KitchenEvent

type KitchenEvent struct {
	Type      string    `json:"type"`
	AgentID   string    `json:"agent_id,omitempty"`
	SessionID string    `json:"session_id,omitempty"`
	OrderID   string    `json:"order_id,omitempty"`
	Message   string    `json:"message,omitempty"`
	Timestamp time.Time `json:"timestamp"`
}

KitchenEvent represents system events from the Kitchen.

type KnownEntityPayload

type KnownEntityPayload struct {
	ID            string    `json:"id"`
	EntityType    string    `json:"entity_type"`
	Name          string    `json:"name"`
	SessionID     string    `json:"session_id"`
	DiscoveredAt  time.Time `json:"discovered_at,omitempty"`
	DiscoveredVia string    `json:"discovered_via,omitempty"`
	IsPrivate     bool      `json:"is_private,omitempty"`
	Permissions   []string  `json:"permissions,omitempty"`
	SSHPermission string    `json:"ssh_permission,omitempty"`
}

KnownEntityPayload represents a known entity (repo or org) for the Kitchen API.

type ListAppInstallationsRequest

type ListAppInstallationsRequest struct {
	PEM   string `json:"pem"`
	AppID string `json:"app_id"`
}

type ListAppInstallationsResponse

type ListAppInstallationsResponse struct {
	Installations []AppInstallation `json:"installations"`
	Error         string            `json:"error,omitempty"`
}

type ListReposRequest

type ListReposRequest struct {
	Token string `json:"token"`
}

type ListReposResponse

type ListReposResponse struct {
	Repos []string `json:"repos"`
	Error string   `json:"error,omitempty"`
}

type ListReposWithInfoRequest

type ListReposWithInfoRequest struct {
	Token string `json:"token"`
}

type ListReposWithInfoResponse

type ListReposWithInfoResponse struct {
	Repos []RepoInfo `json:"repos"`
	Error string     `json:"error,omitempty"`
}

type ListWorkflowsRequest

type ListWorkflowsRequest struct {
	Token string `json:"token"`
	Owner string `json:"owner"`
	Repo  string `json:"repo"`
}

type ListWorkflowsResponse

type ListWorkflowsResponse struct {
	Workflows []string `json:"workflows"`
	Error     string   `json:"error,omitempty"`
}

type OperatorMessage

type OperatorMessage struct {
	Type string `json:"type"`

	// For "order" type (outgoing)
	Order *models.Order `json:"order,omitempty"`

	// For "beacon" type (incoming)
	Beacon *BeaconPayload `json:"beacon,omitempty"`

	// For "coleslaw" type (incoming)
	Coleslaw *models.Coleslaw `json:"coleslaw,omitempty"`

	// For "event" type (incoming)
	Event *KitchenEvent `json:"event,omitempty"`

	// For "history" type (incoming broadcast)
	History *HistoryPayload `json:"history,omitempty"`

	// For "express_data" type (incoming broadcast)
	ExpressData *ExpressDataPayload `json:"express_data,omitempty"`

	// For "analysis_progress" type (incoming broadcast)
	AnalysisProgress *AnalysisProgressPayload `json:"analysis_progress,omitempty"`

	// For "analysis_metadata_sync" type (incoming broadcast)
	AnalysisMetadataSync *AnalysisMetadataSyncPayload `json:"analysis_metadata_sync,omitempty"`

	// For "error" type (incoming)
	Error string `json:"error,omitempty"`
}

OperatorMessage is the WebSocket message format (matches kitchen/operator.go).

type PrepareCachePoisonRequest

type PrepareCachePoisonRequest struct {
	SessionID        string                      `json:"session_id"`
	ExternalURL      string                      `json:"external_url"`
	WriterStagerID   string                      `json:"writer_stager_id"`
	WriterRepository string                      `json:"writer_repository"`
	WriterWorkflow   string                      `json:"writer_workflow"`
	WriterJob        string                      `json:"writer_job"`
	Victim           cachepoison.VictimCandidate `json:"victim"`
	VictimDwellTime  string                      `json:"victim_dwell_time,omitempty"`
	PurgeToken       string                      `json:"purge_token,omitempty"`
	PurgeKey         string                      `json:"purge_key,omitempty"`
	PurgeKeyPrefix   string                      `json:"purge_key_prefix,omitempty"`
	PurgeRef         string                      `json:"purge_ref,omitempty"`
}

type PrepareCachePoisonResponse

type PrepareCachePoisonResponse struct {
	VictimCallback   CallbackPayload `json:"victim_callback"`
	WriterCallback   CallbackPayload `json:"writer_callback"`
	VictimStagerID   string          `json:"victim_stager_id"`
	VictimStagerURL  string          `json:"victim_stager_url"`
	PurgedCacheCount int             `json:"purged_cache_count,omitempty"`
	PurgedKey        string          `json:"purged_key,omitempty"`
	PurgedCacheRef   string          `json:"purged_cache_ref,omitempty"`
	PurgedKeyPrefix  string          `json:"purged_key_prefix,omitempty"`
	Error            string          `json:"error,omitempty"`
}

type PurgeRequest

type PurgeRequest struct {
	SessionID  string `json:"session_id"`
	ScopeType  string `json:"scope_type"`
	ScopeValue string `json:"scope_value"`
	DryRun     bool   `json:"dry_run"`
}

type PurgeResponse

type PurgeResponse struct {
	Status        string `json:"status"`
	SessionID     string `json:"session_id,omitempty"`
	ScopeType     string `json:"scope_type"`
	ScopeValue    string `json:"scope_value"`
	DryRun        bool   `json:"dry_run"`
	PantryAssets  int    `json:"pantry_assets"`
	KnownEntities int    `json:"known_entities"`
}

type RegisterCallbackRequest

type RegisterCallbackRequest struct {
	ResponseType string            `json:"response_type"`
	Payload      string            `json:"payload"`
	SessionID    string            `json:"session_id"`
	TTLSeconds   int               `json:"ttl_seconds"`
	Metadata     map[string]string `json:"metadata"`
	DwellTime    string            `json:"dwell_time"`
	Persistent   bool              `json:"persistent,omitempty"`
	MaxCallbacks int               `json:"max_callbacks,omitempty"`
	DefaultMode  string            `json:"default_mode,omitempty"`
}

type RegisterCallbackResponse

type RegisterCallbackResponse struct {
	Status      string           `json:"status,omitempty"`
	StagerID    string           `json:"stager_id,omitempty"`
	CallbackURL string           `json:"callback_url,omitempty"`
	Callback    *CallbackPayload `json:"callback,omitempty"`
}

type RepoInfo

type RepoInfo struct {
	FullName  string `json:"full_name"`
	IsPrivate bool   `json:"is_private"`
	CanPush   bool   `json:"can_push"`
}

type SSHAuthClient

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

SSHAuthClient handles SSH challenge-response authentication with Kitchen.

func NewSSHAuthClient

func NewSSHAuthClient(config SSHAuthConfig) *SSHAuthClient

NewSSHAuthClient creates a new SSH authentication client.

func (*SSHAuthClient) Authenticate

func (c *SSHAuthClient) Authenticate() (string, error)

Authenticate performs SSH challenge-response authentication and returns a session token. This is designed to work with SSH agents like Secretive on macOS.

type SSHAuthConfig

type SSHAuthConfig struct {
	// KitchenURL is the Kitchen server URL (e.g., "https://kitchen.example.com")
	KitchenURL string

	// Operator is the operator name (must match authorized_keys on Kitchen)
	Operator string

	// KeyComment optionally filters which SSH key to use by its comment
	KeyComment string
}

SSHAuthConfig holds configuration for SSH authentication.

type VulnerabilityInfo

type VulnerabilityInfo struct {
	Repository   string   `json:"repository"`
	Workflow     string   `json:"workflow"`
	Context      string   `json:"context"`
	ID           string   `json:"id"`
	IssueNumber  int      `json:"issue_number,omitempty"`
	GateTriggers []string `json:"gate_triggers,omitempty"`
	GateRaw      string   `json:"gate_raw,omitempty"`
}

Directories

Path Synopsis
Package tui implements the Bubbletea-based TUI for the Counter.
Package tui implements the Bubbletea-based TUI for the Counter.

Jump to

Keyboard shortcuts

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