service

package
v1.0.0-rc1 Latest Latest
Warning

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

Go to latest
Published: Aug 9, 2026 License: AGPL-3.0 Imports: 48 Imported by: 0

Documentation

Overview

Package service defines the transport-facing Web service contract and the service-owned authentication component.

Index

Constants

View Source
const (
	SysNoRunningTask     = "no_running_task"
	SysPaused            = "paused"
	SysFileUploaded      = "file_uploaded"
	SysNoAgentsConnected = "no_agents_connected"
	SysAgentsList        = "agents_list"
	SysAgentNotConnected = "agent_not_connected"
)

Stable system-message codes mirrored by the frontend i18n catalog.

View Source
const (
	ApplicationWebSocketPath = web.ApplicationWebSocketPath
	NodeWebSocketPath        = web.NodeWebSocketPath
)
View Source
const (
	SessionStateOpen   = managementapi.SessionStateOpen
	SessionStateClosed = managementapi.SessionStateClosed
)
View Source
const CookieName = "aiscan_session"

Variables

View Source
var (
	ErrScanNotFound      = managementapi.ErrScanNotFound
	ErrScanNotCancelable = managementapi.ErrScanNotCancelable
)
View Source
var (
	ErrSessionNotFound = errors.New("session not found")
	ErrTurnNotFound    = managementapi.ErrTurnNotFound
)

Functions

func AccessKeyMatches

func AccessKeyMatches(key, candidate string) bool

func BearerToken

func BearerToken(header string) (string, bool)

func RequestIsHTTPS

func RequestIsHTTPS(r *http.Request) bool

func SessionMatches

func SessionMatches(key, candidate string) bool

func SessionValue

func SessionValue(key string) string

func ValidateMode

func ValidateMode(mode string) (string, error)

func ValidateTarget

func ValidateTarget(raw string) (string, error)

Types

type AgentPool

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

AgentPool manages connected aiscan agent nodes. Every member is a node that registered over the application WebSocket — including the hub's own embedded agent, which connects over loopback like any other node.

func NewAgentPool

func NewAgentPool(hub *Hub, allowedOrigins ...string) *AgentPool

func (*AgentPool) BroadcastConfigReload

func (p *AgentPool) BroadcastConfigReload(config *types.DistributeConfig) int

BroadcastConfigReload sends the committed protobuf config on the same FIFO as every other application message. Agents never fetch a second REST DTO.

func (*AgentPool) CancelPTY

func (p *AgentPool) CancelPTY(nodeID, terminalID string)

func (*AgentPool) CancelTask

func (p *AgentPool) CancelTask(nodeID, taskID string, sessionID ...string) error

func (*AgentPool) ClosePTY

func (p *AgentPool) ClosePTY(nodeID, terminalID string)

func (*AgentPool) Count

func (p *AgentPool) Count() int

func (*AgentPool) DispatchCloseSession

func (p *AgentPool) DispatchCloseSession(nodeID, requestID string, request *aop.CloseSessionRequest) (<-chan taskResult, error)

func (*AgentPool) DispatchCommand

func (p *AgentPool) DispatchCommand(nodeID, taskID string, command *types.CommandRequest) (<-chan taskResult, error)

func (*AgentPool) DispatchOpenSession

func (p *AgentPool) DispatchOpenSession(nodeID, requestID string, request *aop.OpenSessionRequest) (<-chan taskResult, error)

func (*AgentPool) DispatchRun

func (p *AgentPool) DispatchRun(nodeID string, request *aop.RunTurnRequest) (<-chan taskResult, error)

func (*AgentPool) DispatchToolCall

func (p *AgentPool) DispatchToolCall(nodeID, taskID string, call *aop.ToolCall) (<-chan taskResult, error)

DispatchToolCall sends a canonical AOP tool.call to a tool-capable node. The task completes only on the matching AOP tool.result.

func (*AgentPool) ForwardPTY

func (p *AgentPool) ForwardPTY(nodeID string, message *ptypb.ProtocolMessage) error

func (*AgentPool) HandleNodeWebSocket

func (p *AgentPool) HandleNodeWebSocket(w http.ResponseWriter, r *http.Request)

func (*AgentPool) List

func (p *AgentPool) List() []*types.AgentView

func (*AgentPool) Pick

func (p *AgentPool) Pick() *remoteAgent

Pick selects an idle agent, or any agent if none idle.

func (*AgentPool) ServeNode

func (p *AgentPool) ServeNode(parent context.Context, stream aop.EnvelopeStream) error

ServeNode owns the Node Endpoint handshake and AgentPool registration. Once initialized, node traffic uses the same Connection runtime as applications.

func (*AgentPool) SessionOpen

func (p *AgentPool) SessionOpen(nodeID, sessionID string) bool

func (*AgentPool) SetArtifactIngestor

func (p *AgentPool) SetArtifactIngestor(ingestor ArtifactIngestor)

func (*AgentPool) SetSessionLookup

func (p *AgentPool) SetSessionLookup(sl SessionLookup)

func (*AgentPool) SubscribePTY

func (p *AgentPool) SubscribePTY(nodeID, terminalID string) (<-chan *ptypb.ProtocolMessage, bool, func())

type ArtifactIngestor

type ArtifactIngestor interface {
	IngestArtifact(context.Context, *toolpb.Artifact) error
	NormalizeArtifact(context.Context, string, string, []byte) (uint64, uint64, error)
	SupportedArtifacts() []string
	Close() error
}

ArtifactIngestor is the server-side normalization boundary. Agent nodes send scanner-native records; implementations convert and persist canonical SCO.

func NewArtifactIngestor

func NewArtifactIngestor(store SCOStore) (ArtifactIngestor, error)

type Auth

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

Auth owns the access-key policy shared by HTTP, ConnectRPC, WebSocket and the IOA browser bridge.

func NewAuth

func NewAuth(accessKey string) *Auth

func (*Auth) Authenticate

func (a *Auth) Authenticate(r *http.Request) bool

Authenticate resolves an explicit bearer credential or browser session. An invalid explicit bearer never falls back to the cookie.

func (*Auth) Enabled

func (a *Auth) Enabled() bool

Enabled reports whether authentication is enforced.

func (*Auth) Middleware

func (a *Auth) Middleware(next http.Handler) http.Handler

Middleware gates API requests while leaving health, login and static routes available to browsers.

func (*Auth) RegisterRoutes

func (a *Auth) RegisterRoutes(mux *http.ServeMux)

RegisterRoutes installs the browser session endpoints owned by Auth.

func (*Auth) ShareWithIOA

func (a *Auth) ShareWithIOA(ioaToken string, next http.Handler) http.Handler

ShareWithIOA maps an authenticated AIScan browser request to IOA's reserved browser token while preserving native IOA bearer identities.

type ConfigStore

type ConfigStore = managementapi.ConfigStore

ConfigStore and PreparedConfig are the host integration surface for config persistence; the business semantics live in web/api.

type Hub

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

Hub is a typed in-process broker. Durable replay remains the responsibility of the event stores; live protobuf values never pass through JSON envelopes.

func NewHub

func NewHub() *Hub

func (*Hub) BroadcastAOP

func (h *Hub) BroadcastAOP(sessionID string, delivery *aop.EventDelivery, reliable bool)

func (*Hub) BroadcastScan

func (h *Hub) BroadcastScan(event *types.ScanEvent, reliable bool)

func (*Hub) SubscribeAOP

func (h *Hub) SubscribeAOP(sessionID string) (<-chan *aop.EventDelivery, func())

func (*Hub) SubscribeScan

func (h *Hub) SubscribeScan(scanID string) (<-chan *types.ScanEvent, uint64, func())

SubscribeScan registers a live subscriber and returns the sequence that was current at the subscription boundary. A caller can stamp its initial snapshot with this value, then safely ignore queued events at or below it.

type PreparedConfig

type PreparedConfig = managementapi.PreparedConfig

type SCOStore

type SCOStore interface {
	UpsertSCONodes(ctx context.Context, operationID string, nodes []json.RawMessage) error
}

SCOStore persists server-normalized nodes and records which AOP operation observed them. Node identity is global; operation membership is many-to-many.

type SQLiteStore

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

func NewSQLiteStore

func NewSQLiteStore(dbPath string) (*SQLiteStore, error)

func (*SQLiteStore) AddAOPEvent

func (s *SQLiteStore) AddAOPEvent(ctx context.Context, sessionID string, event *aop.Event) error

func (*SQLiteStore) AppendAOPEvent

func (s *SQLiteStore) AppendAOPEvent(ctx context.Context, sessionID string, event *aop.Event) (cursor int64, persisted bool, err error)

func (*SQLiteStore) Close

func (s *SQLiteStore) Close() error

func (*SQLiteStore) Create

func (s *SQLiteStore) Create(ctx context.Context, scan *types.Scan) error

func (*SQLiteStore) CreateSession

func (s *SQLiteStore) CreateSession(ctx context.Context, session *types.SessionRecord) error

func (*SQLiteStore) Delete

func (s *SQLiteStore) Delete(ctx context.Context, id string) error

func (*SQLiteStore) DeleteSCONodesByScan

func (s *SQLiteStore) DeleteSCONodesByScan(ctx context.Context, scanID string) error

func (*SQLiteStore) DeleteSession

func (s *SQLiteStore) DeleteSession(ctx context.Context, id string) error

func (*SQLiteStore) Get

func (s *SQLiteStore) Get(ctx context.Context, id string) (*types.Scan, error)

func (*SQLiteStore) GetSCONode

func (s *SQLiteStore) GetSCONode(ctx context.Context, cstxID string) (json.RawMessage, error)

func (*SQLiteStore) GetSession

func (s *SQLiteStore) GetSession(ctx context.Context, id string) (*types.SessionRecord, error)

func (*SQLiteStore) LinkScanToSession

func (s *SQLiteStore) LinkScanToSession(ctx context.Context, sessionID, scanID string) error

func (*SQLiteStore) List

func (s *SQLiteStore) List(ctx context.Context, limit int) ([]*types.Scan, error)

func (*SQLiteStore) ListAOPEventPage

func (s *SQLiteStore) ListAOPEventPage(ctx context.Context, sessionID string, before int64, limit int) ([]*aop.EventDelivery, int64, error)

func (*SQLiteStore) ListAOPEvents

func (s *SQLiteStore) ListAOPEvents(ctx context.Context, sessionID string, limit int) ([]*aop.Event, error)

func (*SQLiteStore) ListAOPEventsAfter

func (s *SQLiteStore) ListAOPEventsAfter(ctx context.Context, sessionID string, after int64, limit int) ([]*aop.EventDelivery, error)

func (*SQLiteStore) ListSCONodes

func (s *SQLiteStore) ListSCONodes(ctx context.Context, nodeType string, limit int) ([]json.RawMessage, error)

func (*SQLiteStore) ListSCONodesByScanID

func (s *SQLiteStore) ListSCONodesByScanID(ctx context.Context, scanID, nodeType string, limit int) ([]json.RawMessage, error)

func (*SQLiteStore) ListSessionPage

func (s *SQLiteStore) ListSessionPage(ctx context.Context, offset, limit int, includeClosed bool) ([]*types.SessionRecord, bool, error)

func (*SQLiteStore) ListSessions

func (s *SQLiteStore) ListSessions(ctx context.Context, limit int) ([]*types.SessionRecord, error)

func (*SQLiteStore) LoadAOPRequest

func (s *SQLiteStore) LoadAOPRequest(ctx context.Context, requestID, method string, requestHash []byte, response protobuf.Message) (found, conflict bool, err error)

func (*SQLiteStore) MaxAOPEventSeq

func (s *SQLiteStore) MaxAOPEventSeq(ctx context.Context, sessionID string) (uint64, error)

func (*SQLiteStore) SCONodeStats

func (s *SQLiteStore) SCONodeStats(ctx context.Context) (map[string]int, error)

func (*SQLiteStore) SaveAOPRequest

func (s *SQLiteStore) SaveAOPRequest(ctx context.Context, requestID, method string, requestHash []byte, response protobuf.Message) error

func (*SQLiteStore) SessionScanIDs

func (s *SQLiteStore) SessionScanIDs(ctx context.Context, sessionID string) ([]string, error)

func (*SQLiteStore) TransitionScan

func (s *SQLiteStore) TransitionScan(ctx context.Context, scan *types.Scan, expected ...types.ScanStatus) (bool, error)

func (*SQLiteStore) Update

func (s *SQLiteStore) Update(ctx context.Context, scan *types.Scan) error

func (*SQLiteStore) UpdateSession

func (s *SQLiteStore) UpdateSession(ctx context.Context, session *types.SessionRecord) error

func (*SQLiteStore) UpsertSCONodes

func (s *SQLiteStore) UpsertSCONodes(ctx context.Context, operationID string, nodes []json.RawMessage) error

type Service

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

func NewService

func NewService(cfg ServiceConfig) *Service

func (*Service) API

func (s *Service) API() *managementapi.API

API exposes the existing business service composition to transport adapters.

func (*Service) AgentInfo

func (s *Service) AgentInfo(nodeID string) (string, bool)

func (*Service) ApplicationWebSocketHandler

func (s *Service) ApplicationWebSocketHandler() http.Handler

func (*Service) Auth

func (s *Service) Auth() web.Auth

Auth returns the authentication mechanism shared by HTTP, ConnectRPC and WebSocket bindings.

func (*Service) BroadcastAOPEvent

func (s *Service) BroadcastAOPEvent(sessionID string, event *aop.Event)

func (*Service) CancelScan

func (s *Service) CancelScan(id string) error

func (*Service) CancelTurn

func (s *Service) CancelTurn(ctx context.Context, sessionID, turnID string) error

func (*Service) Close

func (s *Service) Close()

func (*Service) CloseAgentSession

func (s *Service) CloseAgentSession(ctx context.Context, requestID, nodeID string, request *aop.CloseSessionRequest) (bool, error)

func (*Service) DeleteSession

func (s *Service) DeleteSession(ctx context.Context, id string) error

func (*Service) ExecuteSessionCommand

func (s *Service) ExecuteSessionCommand(sessionID, line string) (string, error)

func (*Service) GetReport

func (s *Service) GetReport(ctx context.Context, id, lang string) (string, error)

GetReport returns the report frozen when the scan completed. Canonical scan artifacts live in the libcstx SCO store, not inside Scan.

func (*Service) GetScan

func (s *Service) GetScan(ctx context.Context, id string) (*types.Scan, error)

func (*Service) HandleApplicationWebSocket

func (s *Service) HandleApplicationWebSocket(w http.ResponseWriter, r *http.Request)

func (*Service) Hub

func (s *Service) Hub() *Hub

func (*Service) ListScans

func (s *Service) ListScans(ctx context.Context) ([]*types.Scan, error)

func (*Service) NodeWebSocketHandler

func (s *Service) NodeWebSocketHandler() http.Handler

func (*Service) OpenAgentSession

func (s *Service) OpenAgentSession(ctx context.Context, requestID string, request *aop.OpenSessionRequest) error

func (*Service) PublishUserMessage

func (s *Service) PublishUserMessage(sessionID, turnID string, message *aop.Message)

PublishUserMessage records the operator input in the durable AOP timeline. Node delivery remains the caller's RunTurn/Command request; this function does not create a second transport path.

func (*Service) ServeApplication

func (s *Service) ServeApplication(ctx context.Context, stream aop.EnvelopeStream) error

ServeApplication performs the Application Endpoint initialization and then hands the unified Connection to the api business dispatcher.

func (*Service) SessionMenu

func (s *Service) SessionMenu(sessionID string) []*types.CommandSpec

SessionMenu is the web "/" command catalog for a session: the hub-scope commands plus the bound agent's reported agent-scope commands (its skills included). It falls back to the static agent-scope menu when no agent is bound, so the menu is populated even before an agent connects. This is the single source both SessionService/ListCommands and /help render from.

func (*Service) SetAgentPool

func (s *Service) SetAgentPool(pool *AgentPool)

func (*Service) StartAgentTurn

func (s *Service) StartAgentTurn(sessionID string, request *aop.RunTurnRequest)

func (*Service) Status

func (s *Service) Status() *types.SystemStatus

func (*Service) SubmitScan

func (s *Service) SubmitScan(ctx context.Context, target, mode string, verify, sniper, deep bool) (*types.Scan, error)

func (*Service) SubscribeSessionEvents

func (s *Service) SubscribeSessionEvents(sessionID string) (<-chan *aop.EventDelivery, func())

func (*Service) TaskSession

func (s *Service) TaskSession(taskID string) (string, bool)

func (*Service) Upload

func (s *Service) Upload(ctx context.Context, sessionID, filename string, data []byte) (*filepb.Result, error)

type ServiceConfig

type ServiceConfig struct {
	Store         *SQLiteStore
	App           *runner.App
	ConfigStore   ConfigStore
	AppFactory    func(ctx context.Context, prepared *PreparedConfig) (*runner.App, error)
	AgentPool     *AgentPool
	Artifacts     ArtifactIngestor
	MaxConcurrent int
	ScanTimeout   time.Duration
	AccessKey     string
}

type SessionLookup

type SessionLookup interface {
	TaskSession(taskID string) (sessionID string, ok bool)
	BroadcastAOPEvent(sessionID string, event *aop.Event)
}

SessionLookup resolves a task ID to its owning chat session.

Jump to

Keyboard shortcuts

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