Documentation
¶
Index ¶
- Variables
- type APIQueryData
- type ActivityBucket
- type ContextKey
- type ContextValue
- type EnvStats
- type HandlersApi
- func (h *HandlersApi) ActiveNodesHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) AllNodesHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) AllQueriesShowHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) AllTagsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) AuditLogsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) CarveArchiveHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) CarveListHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) CarveQueriesHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) CarveSamplesHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) CarveShowHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) CarvesActionHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) CarvesRunHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) CheckHandlerAuth(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) CheckHandlerNoAuth(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) DeleteNodeHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) DeleteUserTokenHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvActionsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvActivityHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvEnrollActionsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvEnrollHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvRemoveActionsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvRemoveHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvironmentConfigHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvironmentConfigPatchHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvironmentCreateHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvironmentDeleteHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvironmentExpirationPatchHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvironmentHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvironmentIntervalsPatchHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvironmentMapHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvironmentUpdateHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) EnvironmentsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) ErrorHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) ForbiddenHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) HealthHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) InactiveNodesHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) LoginEnvironmentsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) LoginHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) LookupNodeHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) MeHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) MePasswordHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) MePatchHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) NodeActivityBatchHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) NodeActivityHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) NodeHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) NodeLogsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) NodesPagedHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) OsqueryTablesHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) OsqueryVersionsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) PlatformsEnvHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) PlatformsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) QueriesActionHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) QueriesRunHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) QueryListHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) QueryResultsCSVHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) QueryResultsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) QuerySamplesHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) QueryShowHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) RefreshUserTokenHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) RootHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) SavedQueriesListHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) SavedQueryCreateHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) SavedQueryDeleteHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) SavedQueryUpdateHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) SetUserPermissionsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) SettingPatchHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) SettingsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) SettingsServiceEnvHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) SettingsServiceEnvJSONHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) SettingsServiceHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) SettingsServiceJSONHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) StatsHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) TagEnvHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) TagNodeHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) TagsActionHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) TagsEnvHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) UserActionHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) UserHandler(w http.ResponseWriter, r *http.Request)
- func (h *HandlersApi) UsersHandler(w http.ResponseWriter, r *http.Request)
- type HandlersOption
- func WithAuditLog(auditLog *auditlog.AuditLogManager) HandlersOption
- func WithCache(rds *cache.RedisManager) HandlersOption
- func WithCarves(carves *carves.Carves) HandlersOption
- func WithDB(db *gorm.DB) HandlersOption
- func WithDebugHTTP(cfg *config.YAMLConfigurationDebug) HandlersOption
- func WithEnvs(envs *environments.EnvManager) HandlersOption
- func WithName(name string) HandlersOption
- func WithNodes(nodes *nodes.NodeManager) HandlersOption
- func WithOsqueryTables(tables []types.OsqueryTable) HandlersOption
- func WithOsqueryValues(values config.YAMLConfigurationOsquery) HandlersOption
- func WithQueries(queries *queries.Queries) HandlersOption
- func WithSettings(settings *settings.Settings) HandlersOption
- func WithTags(tags *tags.TagManager) HandlersOption
- func WithUsers(users *users.UserManager) HandlersOption
- func WithVersion(version string) HandlersOption
- type NodeActivityBucket
- type NodeLogsResponse
- type StatsResponse
Constants ¶
This section is empty.
Variables ¶
Define targets to be used to retrieve an environment map
var QueryTargets = map[string]bool{ queries.TargetAll: true, queries.TargetAllFull: true, queries.TargetActive: true, queries.TargetCompleted: true, queries.TargetExpired: true, queries.TargetSaved: true, queries.TargetHiddenCompleted: true, queries.TargetDeleted: true, queries.TargetHidden: true, }
QueryTargets enumerates the target filters accepted by QueryListHandler. TargetHiddenActive is intentionally excluded: no UI tab references it and GetByEnvTargetPaged has no branch for it (mirrors Gets() which returns nothing).
Functions ¶
This section is empty.
Types ¶
type ActivityBucket ¶ added in v0.5.2
type ActivityBucket struct {
BucketStart time.Time `json:"bucket_start"`
Config int `json:"config"`
Query int `json:"query"`
Carve int `json:"carve"`
Enroll int `json:"enroll"`
}
ActivityBucket is one cell of the 24-hour activity heatmap. BucketStart is the start of the 15-minute window (UTC, RFC3339); the four counters are the audit-log entry counts that fell into that window for each category.
Categories (audit log_type → category):
- config ← Setting (8) + Environment (7)
- query ← Query (4)
- carve ← Carve (5)
- enroll ← Node (3) — covers enroll, archive, deletion
type ContextKey ¶
type ContextKey string
ContextKey to help with the context key, to pass session data
type ContextValue ¶
ContextValue to hold session data in the context
type EnvStats ¶ added in v0.5.2
type EnvStats struct {
UUID string `json:"uuid"`
Name string `json:"name"`
Active int64 `json:"active"`
Inactive int64 `json:"inactive"`
Total int64 `json:"total"`
ActiveQueries int `json:"active_queries"`
ActiveCarves int `json:"active_carves"`
// PlatformCounts buckets the env's nodes by OS family (linux / darwin /
// windows / other). Drives the Nodes-table QuickFilters chip row. Counts
// are total (active + inactive), since the filter chip lists all nodes
// of that platform regardless of staleness — the Active/Inactive toggle
// is independent.
PlatformCounts nodes.PlatformCounts `json:"platform_counts"`
}
EnvStats is one row in the per-env breakdown returned by /api/v1/stats.
type HandlersApi ¶
type HandlersApi struct {
DB *gorm.DB
Users *users.UserManager
Tags *tags.TagManager
Envs *environments.EnvManager
Nodes *nodes.NodeManager
Queries *queries.Queries
Carves *carves.Carves
Settings *settings.Settings
RedisCache *cache.RedisManager
ServiceVersion string
ServiceName string
AuditLog *auditlog.AuditLogManager
ApiConfig *config.APIConfiguration
DebugHTTP *zerolog.Logger
DebugHTTPConfig *config.YAMLConfigurationDebug
OsqueryTables []types.OsqueryTable
OsqueryValues config.YAMLConfigurationOsquery
}
func CreateHandlersApi ¶
func CreateHandlersApi(opts ...HandlersOption) *HandlersApi
CreateHandlersApi to initialize the Admin handlers struct
func (*HandlersApi) ActiveNodesHandler ¶
func (h *HandlersApi) ActiveNodesHandler(w http.ResponseWriter, r *http.Request)
ActiveNodesHandler - GET Handler for active JSON nodes
func (*HandlersApi) AllNodesHandler ¶
func (h *HandlersApi) AllNodesHandler(w http.ResponseWriter, r *http.Request)
AllNodesHandler - GET Handler for all JSON nodes
func (*HandlersApi) AllQueriesShowHandler ¶
func (h *HandlersApi) AllQueriesShowHandler(w http.ResponseWriter, r *http.Request)
AllQueriesShowHandler - GET Handler to return all queries in JSON
func (*HandlersApi) AllTagsHandler ¶
func (h *HandlersApi) AllTagsHandler(w http.ResponseWriter, r *http.Request)
AllTagsHandler - GET Handler for all JSON tags
func (*HandlersApi) AuditLogsHandler ¶ added in v0.4.8
func (h *HandlersApi) AuditLogsHandler(w http.ResponseWriter, r *http.Request)
AuditLogsHandler - GET /api/v1/audit-logs
Query params:
?service=... exact match on service name ?username=... case-insensitive partial match on username ?type=... log type integer (1..10), see pkg/auditlog.LogType* ?env_uuid=... filter to one environment (resolved to internal ID) ?since=RFC3339 created_at >= since ?until=RFC3339 created_at <= until ?page=N 1-indexed page; default 1 ?page_size=N default 50, max 500
Returns the SPA-canonical paginated envelope. The handler audit-logs the visit on success.
func (*HandlersApi) CarveArchiveHandler ¶ added in v0.5.2
func (h *HandlersApi) CarveArchiveHandler(w http.ResponseWriter, r *http.Request)
CarveArchiveHandler - GET /api/v1/carves/{env}/archive/{name}
(The literal `archive` lives in segment 2 — not as a `/{name}/archive` suffix — because Go's ServeMux refuses to register patterns that ambiguously overlap with `/{env}/queries/{target}` registered on the same prefix.)
Streams (or redirects to) the reassembled carve archive blob.
Resolution rules:
- The carve query identified by {name} must exist and be type=carve.
- If exactly one CarvedFile exists for the query, it is served.
- If multiple exist, an explicit ?session=<session-id> must select one. A missing/ambiguous session selector returns 409 Conflict.
- If the underlying file is not yet archived, it is archived on demand (local or DB carver: written to a temp dir, then served; S3: a presigned download URL is returned via 302 redirect).
Content-Disposition is set to attachment with the carve archive filename.
func (*HandlersApi) CarveListHandler ¶
func (h *HandlersApi) CarveListHandler(w http.ResponseWriter, r *http.Request)
CarveListHandler - GET /api/v1/carves/{env}
Paginated, sorted, searchable list of carve queries (DistributedQuery rows with type=carve). Query params: page, page_size, q, sort, dir, target. Empty result → HTTP 200 with items: [].
func (*HandlersApi) CarveQueriesHandler ¶
func (h *HandlersApi) CarveQueriesHandler(w http.ResponseWriter, r *http.Request)
CarveQueriesHandler - GET /api/v1/carves/{env}/queries/{target}
Returns carve queries by target. Retained from the legacy contract; the canonical list endpoint is now CarveListHandler at /api/v1/carves/{env}.
func (*HandlersApi) CarveSamplesHandler ¶ added in v0.5.2
func (h *HandlersApi) CarveSamplesHandler(w http.ResponseWriter, r *http.Request)
CarveSamplesHandler - GET /api/v1/carves/samples
Returns the static starter library of common carve-target file paths (e.g., /etc/passwd, C:\Windows\System32\config\SAM). Same auth posture as QuerySamplesHandler: pre-auth, rate-limited.
func (*HandlersApi) CarveShowHandler ¶
func (h *HandlersApi) CarveShowHandler(w http.ResponseWriter, r *http.Request)
CarveShowHandler - GET /api/v1/carves/{env}/{name}
Returns the carve query metadata plus the array of per-node CarvedFile rows produced by the carve. Returns 404 when the carve query name does not exist in the environment.
func (*HandlersApi) CarvesActionHandler ¶
func (h *HandlersApi) CarvesActionHandler(w http.ResponseWriter, r *http.Request)
CarvesActionHandler - POST /api/v1/carves/{env}/{action}/{name}
func (*HandlersApi) CarvesRunHandler ¶
func (h *HandlersApi) CarvesRunHandler(w http.ResponseWriter, r *http.Request)
CarvesRunHandler - POST /api/v1/carves/{env}
func (*HandlersApi) CheckHandlerAuth ¶ added in v0.4.6
func (h *HandlersApi) CheckHandlerAuth(w http.ResponseWriter, r *http.Request)
CheckHandlerAuth - Handle authenticated check requests
func (*HandlersApi) CheckHandlerNoAuth ¶ added in v0.4.6
func (h *HandlersApi) CheckHandlerNoAuth(w http.ResponseWriter, r *http.Request)
CheckHandlerNoAuth - Handle unauthenticated check requests
func (*HandlersApi) DeleteNodeHandler ¶
func (h *HandlersApi) DeleteNodeHandler(w http.ResponseWriter, r *http.Request)
DeleteNodeHandler - POST Handler to delete single node
func (*HandlersApi) DeleteUserTokenHandler ¶ added in v0.5.2
func (h *HandlersApi) DeleteUserTokenHandler(w http.ResponseWriter, r *http.Request)
DeleteUserTokenHandler - DELETE /api/v1/users/{username}/token
Clears the user's APIToken so any existing JWT for them stops working. Requires super-admin OR the user themselves.
func (*HandlersApi) EnvActionsHandler ¶ added in v0.5.2
func (h *HandlersApi) EnvActionsHandler(w http.ResponseWriter, r *http.Request)
EnvActionsHandler - POST Handler to perform actions (create, delete, edit) on environments
func (*HandlersApi) EnvActivityHandler ¶ added in v0.5.2
func (h *HandlersApi) EnvActivityHandler(w http.ResponseWriter, r *http.Request)
EnvActivityHandler — GET /api/v1/stats/activity/{env}?interval=KEY
Returns audit-log activity for one env over the requested interval, bucketed at a fixed size per interval (see activityIntervalPresets). `interval` accepts 3h / 6h / 12h / 1d / 2d / 3d / 7d (default 1d, falls back to 1d on any unknown value rather than 400ing — the SPA picker is the only allowed source).
Buckets are emitted contiguously — empty windows return zero rows for that bucket — so the SPA can render the grid without densifying client-side.
func (*HandlersApi) EnvEnrollActionsHandler ¶
func (h *HandlersApi) EnvEnrollActionsHandler(w http.ResponseWriter, r *http.Request)
EnvEnrollActionsHandler - POST Handler to perform actions (extend, expire) in enroll values
func (*HandlersApi) EnvEnrollHandler ¶
func (h *HandlersApi) EnvEnrollHandler(w http.ResponseWriter, r *http.Request)
EnvEnrollHandler - GET Handler to return node enrollment values (secret, certificate, one-liner) for an environment as JSON
func (*HandlersApi) EnvRemoveActionsHandler ¶
func (h *HandlersApi) EnvRemoveActionsHandler(w http.ResponseWriter, r *http.Request)
EnvRemoveActionsHandler - POST Handler to perform actions (extend, expire) in remove values
func (*HandlersApi) EnvRemoveHandler ¶
func (h *HandlersApi) EnvRemoveHandler(w http.ResponseWriter, r *http.Request)
EnvRemoveHandler - GET Handler to return node removal values for an environment as JSON
func (*HandlersApi) EnvironmentConfigHandler ¶ added in v0.5.2
func (h *HandlersApi) EnvironmentConfigHandler(w http.ResponseWriter, r *http.Request)
EnvironmentConfigHandler - GET /api/v1/environments/config/{env}
Returns the env's JSON-shaped config sections (options/schedule/packs/ decorators/atc/flags) so the SPA's Monaco editor can render each section.
func (*HandlersApi) EnvironmentConfigPatchHandler ¶ added in v0.5.2
func (h *HandlersApi) EnvironmentConfigPatchHandler(w http.ResponseWriter, r *http.Request)
EnvironmentConfigPatchHandler - PATCH /api/v1/environments/config/{env}
Body: optional options/schedule/packs/decorators/atc/flags string fields. Each non-nil field is validated as JSON before persisting; an invalid payload is rejected with 400 (no partial writes).
func (*HandlersApi) EnvironmentCreateHandler ¶ added in v0.5.2
func (h *HandlersApi) EnvironmentCreateHandler(w http.ResponseWriter, r *http.Request)
EnvironmentCreateHandler - POST /api/v1/environments
Body: { name, hostname, type? }. Generates a UUID, defaults config / schedule / packs / decorators / ATC to "{}", and persists the env. Returns 201 with the created TLSEnvironment. Super-admin only.
func (*HandlersApi) EnvironmentDeleteHandler ¶ added in v0.5.2
func (h *HandlersApi) EnvironmentDeleteHandler(w http.ResponseWriter, r *http.Request)
EnvironmentDeleteHandler - DELETE /api/v1/environments/{env}
Removes the environment. Super-admin only. Returns 200 with a message.
func (*HandlersApi) EnvironmentExpirationPatchHandler ¶ added in v0.5.2
func (h *HandlersApi) EnvironmentExpirationPatchHandler(w http.ResponseWriter, r *http.Request)
EnvironmentExpirationPatchHandler - PATCH /api/v1/environments/expiration/{env}
Convenience wrapper around the existing enrollment lifecycle actions (extend / expire / rotate / not-expire), accepting one of those actions via JSON body instead of as a path segment. Mirrors the legacy EnvEnrollActionsHandler semantics for both enroll and remove paths.
func (*HandlersApi) EnvironmentHandler ¶
func (h *HandlersApi) EnvironmentHandler(w http.ResponseWriter, r *http.Request)
EnvironmentHandler - GET Handler to return one environment by UUID as JSON
func (*HandlersApi) EnvironmentIntervalsPatchHandler ¶ added in v0.5.2
func (h *HandlersApi) EnvironmentIntervalsPatchHandler(w http.ResponseWriter, r *http.Request)
EnvironmentIntervalsPatchHandler - PATCH /api/v1/environments/intervals/{env}
Body: { config_interval?, log_interval?, query_interval? }. Updates the three node-pull intervals atomically. Unsupplied fields are kept.
func (*HandlersApi) EnvironmentMapHandler ¶
func (h *HandlersApi) EnvironmentMapHandler(w http.ResponseWriter, r *http.Request)
EnvironmentMapHandler - GET Handler to return one environment as JSON
func (*HandlersApi) EnvironmentUpdateHandler ¶ added in v0.5.2
func (h *HandlersApi) EnvironmentUpdateHandler(w http.ResponseWriter, r *http.Request)
EnvironmentUpdateHandler - PATCH /api/v1/environments/{env}
Updates name / hostname / type / icon / debug_http / accept_enrolls. Other env fields go through the per-section endpoints. Super-admin only.
func (*HandlersApi) EnvironmentsHandler ¶
func (h *HandlersApi) EnvironmentsHandler(w http.ResponseWriter, r *http.Request)
EnvironmentsHandler - GET Handler to return all environments as JSON
func (*HandlersApi) ErrorHandler ¶
func (h *HandlersApi) ErrorHandler(w http.ResponseWriter, r *http.Request)
ErrorHandler - Handle error requests
func (*HandlersApi) ForbiddenHandler ¶
func (h *HandlersApi) ForbiddenHandler(w http.ResponseWriter, r *http.Request)
ForbiddenHandler - Handle forbidden error requests
func (*HandlersApi) HealthHandler ¶
func (h *HandlersApi) HealthHandler(w http.ResponseWriter, r *http.Request)
HealthHandler - Handle health requests
func (*HandlersApi) InactiveNodesHandler ¶
func (h *HandlersApi) InactiveNodesHandler(w http.ResponseWriter, r *http.Request)
InactiveNodesHandler - GET Handler for inactive JSON nodes
func (*HandlersApi) LoginEnvironmentsHandler ¶ added in v0.5.2
func (h *HandlersApi) LoginEnvironmentsHandler(w http.ResponseWriter, r *http.Request)
LoginEnvironmentsHandler - GET /api/v1/login/environments
Pre-auth endpoint that returns the list of environments the user may attempt to log into. Surface is intentionally minimal: only the env UUID and name. No enroll secrets, no certificates, no settings, no hostnames — those all stay behind auth on /api/v1/environments and its CRUD siblings.
Rationale: forcing the user to type the env name on the login screen is bad UX (you don't know it until you've logged in once, and single-env installs only ever have one option). The legacy admin shows env names pre-auth in its login form, so we're not changing the security posture — just exposing the same identifiers that the URL space already commits to using post-auth.
Like POST /login/{env}, this lives behind the per-IP rate limit registered in main.go so the endpoint can't be turned into an env-enumeration oracle for brute-force prep beyond the limit.
func (*HandlersApi) LoginHandler ¶
func (h *HandlersApi) LoginHandler(w http.ResponseWriter, r *http.Request)
LoginHandler - POST Handler for API login request
func (*HandlersApi) LookupNodeHandler ¶ added in v0.4.5
func (h *HandlersApi) LookupNodeHandler(w http.ResponseWriter, r *http.Request)
LookupNodeHandler - POST Handler to lookup a node by identifier
func (*HandlersApi) MeHandler ¶ added in v0.5.2
func (h *HandlersApi) MeHandler(w http.ResponseWriter, r *http.Request)
MeHandler - GET /api/v1/users/me
Returns the currently authenticated user's profile (sans password hash and API token). Useful for the SPA's Profile page.
func (*HandlersApi) MePasswordHandler ¶ added in v0.5.2
func (h *HandlersApi) MePasswordHandler(w http.ResponseWriter, r *http.Request)
MePasswordHandler - POST /api/v1/users/me/password
Changes the currently authenticated user's password. Verifies the current password (bcrypt) before persisting the new hash.
func (*HandlersApi) MePatchHandler ¶ added in v0.5.2
func (h *HandlersApi) MePatchHandler(w http.ResponseWriter, r *http.Request)
MePatchHandler - PATCH /api/v1/users/me
Updates email and/or fullname for the currently authenticated user. Sends each empty field through unchanged. Returns the updated profile.
func (*HandlersApi) NodeActivityBatchHandler ¶ added in v0.5.2
func (h *HandlersApi) NodeActivityBatchHandler(w http.ResponseWriter, r *http.Request)
NodeActivityBatchHandler — GET /api/v1/stats/activity/node-batch/{env}?uuids=A,B,C&interval=KEY
Returns activity buckets for up to 100 nodes in one call. The response is a map keyed by node UUID so the SPA can render a sparkline per row in the Nodes table without firing N parallel requests.
Cap is 100 to bound the per-request DB load — each node still requires 4 timestamp queries. The SPA's pagination is already <=500 page size; for pages above 100 nodes the SPA fans out 2-3 batch requests instead.
Unknown / unauthorized UUIDs are silently omitted from the response (they're treated as "no data"), not 404'd — that lets a single bad UUID in the list not break the whole page render.
func (*HandlersApi) NodeActivityHandler ¶ added in v0.5.2
func (h *HandlersApi) NodeActivityHandler(w http.ResponseWriter, r *http.Request)
NodeActivityHandler — GET /api/v1/stats/activity/node/{env}/{uuid}?interval=KEY
Per-node version of EnvActivityHandler. Same bucketing rules (see activityIntervalPresets). The four categories partition different DB tables (see NodeActivityBucket) keyed by the node's UUID — except node_queries which keys by numeric NodeID, looked up once from the resolved node.
func (*HandlersApi) NodeHandler ¶
func (h *HandlersApi) NodeHandler(w http.ResponseWriter, r *http.Request)
NodeHandler - GET Handler for single JSON nodes
func (*HandlersApi) NodeLogsHandler ¶ added in v0.5.2
func (h *HandlersApi) NodeLogsHandler(w http.ResponseWriter, r *http.Request)
NodeLogsHandler returns recent log entries for a node.
Path: /api/v1/logs/{type}/{env}/{uuid}
type: "status" | "result" env: UUID or name uuid: node UUID
Query params:
since: RFC3339 timestamp; entries strictly after this point only limit: 1..1000 (default 100)
func (*HandlersApi) NodesPagedHandler ¶ added in v0.5.2
func (h *HandlersApi) NodesPagedHandler(w http.ResponseWriter, r *http.Request)
NodesPagedHandler returns paginated, sorted, searchable nodes for an env. This is the canonical endpoint consumed by the React admin SPA.
Query params:
status: "all" | "active" | "inactive" (default "all")
q: free-text search (case-insensitive partial match on uuid,
hostname, localname, ip, username, osquery_user, platform, version)
sort: one of nodes.SortableColumns keys (default "lastseen")
dir: "asc" | "desc" (default "desc" for lastseen, "asc" otherwise)
page: 1-indexed page number (default 1)
page_size: 1..500 (default 50)
func (*HandlersApi) OsqueryTablesHandler ¶ added in v0.5.2
func (h *HandlersApi) OsqueryTablesHandler(w http.ResponseWriter, r *http.Request)
OsqueryTablesHandler - GET Handler to return the osquery schema tables
Path: /api/v1/osquery/tables The schema is global (not env-scoped). Requires any authenticated user. Responses are cache-able for one hour since the schema rarely changes.
func (*HandlersApi) OsqueryVersionsHandler ¶ added in v0.5.2
func (h *HandlersApi) OsqueryVersionsHandler(w http.ResponseWriter, r *http.Request)
OsqueryVersionsHandler — GET /api/v1/stats/osquery-versions.
Returns fleet-wide osquery agent version breakdown for the dashboard's "fleet hygiene" panel. Operators use this to spot stale agents that need upgrading. Cross-env (no env filter); the dashboard already surfaces the per-env breakdown in its env tiles.
Counts include both active and inactive nodes — a node sitting at an old osquery version is still "stale" even if it's offline today, because once it comes back online it'll come back stale.
func (*HandlersApi) PlatformsEnvHandler ¶
func (h *HandlersApi) PlatformsEnvHandler(w http.ResponseWriter, r *http.Request)
PlatformsEnvHandler - GET Handler to return platforms for one environment as JSON
func (*HandlersApi) PlatformsHandler ¶
func (h *HandlersApi) PlatformsHandler(w http.ResponseWriter, r *http.Request)
PlatformsHandler - GET Handler for multiple JSON platforms
func (*HandlersApi) QueriesActionHandler ¶
func (h *HandlersApi) QueriesActionHandler(w http.ResponseWriter, r *http.Request)
QueriesActionHandler - POST Handler to delete/expire a query
func (*HandlersApi) QueriesRunHandler ¶
func (h *HandlersApi) QueriesRunHandler(w http.ResponseWriter, r *http.Request)
QueriesRunHandler - POST Handler to run a query
func (*HandlersApi) QueryListHandler ¶
func (h *HandlersApi) QueryListHandler(w http.ResponseWriter, r *http.Request)
QueryListHandler - GET Handler to return queries in JSON by target and environment (paginated)
Query params: page, page_size, q (free-text search), sort (column key), dir (asc|desc)
func (*HandlersApi) QueryResultsCSVHandler ¶ added in v0.5.2
func (h *HandlersApi) QueryResultsCSVHandler(w http.ResponseWriter, r *http.Request)
QueryResultsCSVHandler - GET Handler to stream query results as CSV
Path: /api/v1/queries/{env}/results/csv/{name}
(The `.csv` lives as a literal path segment before `{name}` because Go's ServeMux grammar requires wildcards to end at `/` or end-of-pattern, so `{name}.csv` is a parse error at registration time.)
func (*HandlersApi) QueryResultsHandler ¶
func (h *HandlersApi) QueryResultsHandler(w http.ResponseWriter, r *http.Request)
QueryResultsHandler - GET Handler to return paginated query results in JSON
Path: /api/v1/queries/{env}/results/{name} Params: page, page_size, since (RFC3339 timestamp; unparseable → ignored)
Empty results are a valid state and return HTTP 200 with items: [].
func (*HandlersApi) QuerySamplesHandler ¶ added in v0.5.2
func (h *HandlersApi) QuerySamplesHandler(w http.ResponseWriter, r *http.Request)
QuerySamplesHandler - GET /api/v1/queries/samples
Returns the static starter library of osquery SQL templates so the SPA's queries/new form can populate its QuickTemplates row. Intentionally unauthenticated: the samples are read-only data shipped with the binary, they aren't tenant- or env-scoped, and exposing them pre-auth lets the login screen lazy-load them without circular dependencies.
Shares the per-IP loginRateLimit registered in main.go so this endpoint can't be turned into a low-effort scanning probe.
func (*HandlersApi) QueryShowHandler ¶
func (h *HandlersApi) QueryShowHandler(w http.ResponseWriter, r *http.Request)
QueryShowHandler - GET Handler to return a single query in JSON
func (*HandlersApi) RefreshUserTokenHandler ¶ added in v0.5.2
func (h *HandlersApi) RefreshUserTokenHandler(w http.ResponseWriter, r *http.Request)
RefreshUserTokenHandler - POST /api/v1/users/{username}/token/refresh
Generates a new JWT for the target user, persists it as the user's APIToken (invalidating the previous token), and returns the new token + expiry. Requires super-admin OR the request author asking for their own token. Audit-logged on success.
func (*HandlersApi) RootHandler ¶
func (h *HandlersApi) RootHandler(w http.ResponseWriter, r *http.Request)
RootHandler - Handle root requests
func (*HandlersApi) SavedQueriesListHandler ¶ added in v0.5.2
func (h *HandlersApi) SavedQueriesListHandler(w http.ResponseWriter, r *http.Request)
SavedQueriesListHandler - GET /api/v1/saved-queries/{env}
Paginated, sorted, searchable list of saved queries for an environment. Query params: page, page_size, q (free-text), sort (column key), dir (asc|desc).
func (*HandlersApi) SavedQueryCreateHandler ¶ added in v0.5.2
func (h *HandlersApi) SavedQueryCreateHandler(w http.ResponseWriter, r *http.Request)
SavedQueryCreateHandler - POST /api/v1/saved-queries/{env}
Body: { "name": string, "query": string }. Returns 201 with the created view, 409 if a saved query with that name already exists in the environment.
func (*HandlersApi) SavedQueryDeleteHandler ¶ added in v0.5.2
func (h *HandlersApi) SavedQueryDeleteHandler(w http.ResponseWriter, r *http.Request)
SavedQueryDeleteHandler - DELETE /api/v1/saved-queries/{env}/{name}
func (*HandlersApi) SavedQueryUpdateHandler ¶ added in v0.5.2
func (h *HandlersApi) SavedQueryUpdateHandler(w http.ResponseWriter, r *http.Request)
SavedQueryUpdateHandler - PATCH /api/v1/saved-queries/{env}/{name}
Body: { "query": string }. Updates the SQL body only; the original creator is preserved. Returns the updated view.
func (*HandlersApi) SetUserPermissionsHandler ¶ added in v0.5.2
func (h *HandlersApi) SetUserPermissionsHandler(w http.ResponseWriter, r *http.Request)
SetUserPermissionsHandler - POST /api/v1/users/{username}/permissions
Body: { env_uuid, access: { user, query, carve, admin } }. Replaces the target user's per-env access rows. Returns 200 with the new EnvAccess. Requires super-admin (AdminLevel, NoEnvironment) — env-scoped admins can not grant permissions for their environment from this endpoint.
func (*HandlersApi) SettingPatchHandler ¶ added in v0.5.2
func (h *HandlersApi) SettingPatchHandler(w http.ResponseWriter, r *http.Request)
SettingPatchHandler — PATCH /api/v1/settings/{service}/{name}
Body shape (one of String, Boolean, Integer):
{ "string": "value" }
{ "boolean": true }
{ "integer": 42 }
The handler reads the existing setting first to determine its type, then applies the matching typed setter. Mismatched payloads return 400. The setting must already exist (creation is the legacy admin's job); a missing setting → 404. Audit-log on success only.
func (*HandlersApi) SettingsHandler ¶
func (h *HandlersApi) SettingsHandler(w http.ResponseWriter, r *http.Request)
SettingsHandler - GET Handler for all settings including JSON
func (*HandlersApi) SettingsServiceEnvHandler ¶
func (h *HandlersApi) SettingsServiceEnvHandler(w http.ResponseWriter, r *http.Request)
SettingsServiceEnvHandler - GET Handler for service and environment specific settings excluding JSON
func (*HandlersApi) SettingsServiceEnvJSONHandler ¶
func (h *HandlersApi) SettingsServiceEnvJSONHandler(w http.ResponseWriter, r *http.Request)
GET Handler for service and environment specific settings including JSON
func (*HandlersApi) SettingsServiceHandler ¶
func (h *HandlersApi) SettingsServiceHandler(w http.ResponseWriter, r *http.Request)
SettingsServiceHandler - GET Handler for service specific settings excluding JSON
func (*HandlersApi) SettingsServiceJSONHandler ¶
func (h *HandlersApi) SettingsServiceJSONHandler(w http.ResponseWriter, r *http.Request)
SettingsServiceJSONHandler - GET Handler for service specific settings including JSON
func (*HandlersApi) StatsHandler ¶ added in v0.5.2
func (h *HandlersApi) StatsHandler(w http.ResponseWriter, r *http.Request)
StatsHandler returns cross-env totals + per-env counts, filtered to the envs the calling user has UserLevel access to. Used by the SPA dashboard.
No query params. The response is small (one entry per accessible env) and cacheable for 30s on the client (Cache-Control: private, max-age=30).
NOTE on query/carve counting:
- GetActive(envID) returns ALL active rows regardless of type (union).
- To avoid double-counting we call GetQueries("active", envID) for standard queries and GetCarves("active", envID) for carves separately.
- Unit test for this handler is deferred: the underlying pkg/queries functions are exercised by existing tests in pkg/queries; a full integration test would require DB fixture setup that is out of scope for Track 2.
func (*HandlersApi) TagEnvHandler ¶
func (h *HandlersApi) TagEnvHandler(w http.ResponseWriter, r *http.Request)
TagEnvHandler - GET Handler to return one tag for one environment as JSON. Permission is scoped to env.UUID admin so non-super operators with admin rights on this specific environment can view its tags.
func (*HandlersApi) TagNodeHandler ¶ added in v0.4.6
func (h *HandlersApi) TagNodeHandler(w http.ResponseWriter, r *http.Request)
TagNodeHandler - POST Handler to tag a node
func (*HandlersApi) TagsActionHandler ¶
func (h *HandlersApi) TagsActionHandler(w http.ResponseWriter, r *http.Request)
TagsActionHandler - POST Handler to create / update / delete tags. The action arrives as a URL path segment (legacy contract retained because Track 6 doesn't introduce new tag routes); body validation surfaces 400 on parse error and 409 on duplicate-name conflicts.
func (*HandlersApi) TagsEnvHandler ¶
func (h *HandlersApi) TagsEnvHandler(w http.ResponseWriter, r *http.Request)
TagsEnvHandler - GET Handler to return tags for one environment as JSON. Permission is scoped to env.UUID admin (see TagEnvHandler note).
func (*HandlersApi) UserActionHandler ¶ added in v0.4.6
func (h *HandlersApi) UserActionHandler(w http.ResponseWriter, r *http.Request)
UserActionHandler - POST Handler to take actions on a user by username and environment
func (*HandlersApi) UserHandler ¶
func (h *HandlersApi) UserHandler(w http.ResponseWriter, r *http.Request)
UserHandler - GET Handler for environment users
func (*HandlersApi) UsersHandler ¶
func (h *HandlersApi) UsersHandler(w http.ResponseWriter, r *http.Request)
UsersHandler - GET Handler for multiple JSON nodes
type HandlersOption ¶
type HandlersOption func(*HandlersApi)
func WithAuditLog ¶ added in v0.4.8
func WithAuditLog(auditLog *auditlog.AuditLogManager) HandlersOption
func WithCache ¶
func WithCache(rds *cache.RedisManager) HandlersOption
func WithCarves ¶
func WithCarves(carves *carves.Carves) HandlersOption
func WithDB ¶
func WithDB(db *gorm.DB) HandlersOption
func WithDebugHTTP ¶ added in v0.4.5
func WithDebugHTTP(cfg *config.YAMLConfigurationDebug) HandlersOption
func WithEnvs ¶
func WithEnvs(envs *environments.EnvManager) HandlersOption
func WithName ¶
func WithName(name string) HandlersOption
func WithNodes ¶
func WithNodes(nodes *nodes.NodeManager) HandlersOption
func WithOsqueryTables ¶ added in v0.5.2
func WithOsqueryTables(tables []types.OsqueryTable) HandlersOption
func WithOsqueryValues ¶ added in v0.5.2
func WithOsqueryValues(values config.YAMLConfigurationOsquery) HandlersOption
func WithQueries ¶
func WithQueries(queries *queries.Queries) HandlersOption
func WithSettings ¶
func WithSettings(settings *settings.Settings) HandlersOption
func WithTags ¶
func WithTags(tags *tags.TagManager) HandlersOption
func WithUsers ¶
func WithUsers(users *users.UserManager) HandlersOption
func WithVersion ¶
func WithVersion(version string) HandlersOption
type NodeActivityBucket ¶ added in v0.5.2
type NodeActivityBucket struct {
BucketStart time.Time `json:"bucket_start"`
Status int `json:"status"`
Result int `json:"result"`
Query int `json:"query"`
Carve int `json:"carve"`
}
NodeActivityBucket is one cell of the per-node 24h activity heatmap. Categories pivot from the env-scoped variant — node-scoped activity is about what THIS device has been doing, not what operators have done to the env. So:
- status ← osquery_status_data row count (status logs received from this node)
- result ← osquery_result_data row count (query results returned by this node)
- query ← node_queries row count (distributed queries scheduled against this node)
- carve ← carved_files row count (carves this node has produced)
All four are joinable by node uuid (or numeric node id for node_queries).
type NodeLogsResponse ¶ added in v0.5.2
type NodeLogsResponse struct {
Items []map[string]any `json:"items"`
Type string `json:"type"`
UUID string `json:"uuid"`
Env string `json:"env"`
Since string `json:"since,omitempty"`
Limit int `json:"limit"`
}
NodeLogsResponse is the SPA-canonical response for GET /api/v1/logs/{type}/{env}/{uuid}.
type StatsResponse ¶ added in v0.5.2
type StatsResponse struct {
// Cross-env totals (the user's allowed envs only).
TotalNodes int64 `json:"total_nodes"`
ActiveNodes int64 `json:"active_nodes"`
InactiveNodes int64 `json:"inactive_nodes"`
// TotalActiveQueries counts standard query-type active queries (excludes carves).
TotalActiveQueries int `json:"total_active_queries"`
// TotalActiveCarves counts active carve-type queries.
TotalActiveCarves int `json:"total_active_carves"`
// Cross-env platform breakdown — sum of every accessible env's PlatformCounts.
PlatformCounts nodes.PlatformCounts `json:"platform_counts"`
// Per-env breakdown, in stable alphabetical order by name.
Environments []EnvStats `json:"environments"`
}
StatsResponse is the canonical /api/v1/stats shape consumed by the dashboard.