admin

package
v1.57.0 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2026 License: Apache-2.0 Imports: 43 Imported by: 0

Documentation

Overview

Package admin provides REST API endpoints for administrative operations.

Index

Constants

This section is empty.

Variables

View Source
var ErrPKCEStateCollision = errors.New("admin: pkce state token collision")

ErrPKCEStateCollision is returned by PKCEStore.Put when a state token already exists in the store. State tokens are 256 bits of entropy so a genuine collision is statistically impossible — in practice this means generatePKCEState is broken or someone is replaying a state. Either way, the second oauth-start must fail loudly rather than silently overwriting the first.

View Source
var ErrPKCEStateNotFound = errors.New("admin: pkce state not found")

ErrPKCEStateNotFound is returned by PKCEStore.Take when no state row matches (or the row had already expired). Callers use errors.Is to distinguish "no such pending flow" from a transport/IO error.

View Source
var ErrPKCEStorePut = errors.New("admin: pkce store put failed")

ErrPKCEStorePut wraps any DB-side failure from Put. Tests assert with errors.Is rather than coupling to a specific message.

Functions

func RequireAdmin

func RequireAdmin(auth Authenticator) func(http.Handler) http.Handler

RequireAdmin creates middleware that enforces admin authentication.

func RequirePersona added in v0.17.0

func RequirePersona(auth Authenticator) func(http.Handler) http.Handler

RequirePersona creates middleware that enforces authentication via an Authenticator (which already includes persona validation).

Types

type APIKeyAuthenticator

type APIKeyAuthenticator struct {
	Keys map[string]User // key -> user info
}

APIKeyAuthenticator validates admin access via API keys.

func (*APIKeyAuthenticator) Authenticate

func (a *APIKeyAuthenticator) Authenticate(r *http.Request) (*User, error)

Authenticate checks the X-API-Key or Authorization header.

type APIKeyManager added in v0.17.0

type APIKeyManager interface {
	ListKeys() []auth.APIKeySummary
	GenerateKey(def auth.APIKey) (string, error)
	RemoveByName(name string) bool
}

APIKeyManager manages API keys at runtime.

type AuditMetricsQuerier added in v0.17.1

type AuditMetricsQuerier interface {
	Timeseries(ctx context.Context, filter audit.TimeseriesFilter) ([]audit.TimeseriesBucket, error)
	Breakdown(ctx context.Context, filter audit.BreakdownFilter) ([]audit.BreakdownEntry, error)
	Overview(ctx context.Context, filter audit.MetricsFilter) (*audit.Overview, error)
	Performance(ctx context.Context, filter audit.MetricsFilter) (*audit.PerformanceStats, error)
	Enrichment(ctx context.Context, startTime, endTime *time.Time) (*audit.EnrichmentStats, error)
	Discovery(ctx context.Context, startTime, endTime *time.Time) (*audit.DiscoveryStats, error)
}

AuditMetricsQuerier provides aggregate audit metrics.

type AuditQuerier added in v0.17.0

type AuditQuerier interface {
	Query(ctx context.Context, filter audit.QueryFilter) ([]audit.Event, error)
	Count(ctx context.Context, filter audit.QueryFilter) (int, error)
	Distinct(ctx context.Context, column string, startTime, endTime *time.Time) ([]string, error)
	DistinctPairs(ctx context.Context, col1, col2 string, startTime, endTime *time.Time) (map[string]string, error)
}

AuditQuerier queries audit events.

type Authenticator

type Authenticator interface {
	Authenticate(r *http.Request) (*User, error)
}

Authenticator validates admin credentials.

type ConfigStore added in v0.17.0

type ConfigStore interface {
	Get(ctx context.Context, key string) (*configstore.Entry, error)
	Set(ctx context.Context, key, value, author string) error
	Delete(ctx context.Context, key, author string) error
	List(ctx context.Context) ([]configstore.Entry, error)
	Changelog(ctx context.Context, limit int) ([]configstore.ChangelogEntry, error)
	Mode() string
}

ConfigStore abstracts configstore.Store for testability.

type ConnectionStore added in v1.48.0

type ConnectionStore interface {
	List(ctx context.Context) ([]platform.ConnectionInstance, error)
	Get(ctx context.Context, kind, name string) (*platform.ConnectionInstance, error)
	Set(ctx context.Context, inst platform.ConnectionInstance) error
	Delete(ctx context.Context, kind, name string) error
}

ConnectionStore abstracts platform.ConnectionStore for testability.

type Deps added in v0.17.0

type Deps struct {
	Config              *platform.Config
	ConfigStore         ConfigStore
	FileDefaults        map[string]string
	PersonaRegistry     PersonaRegistry
	ToolkitRegistry     ToolkitRegistry
	MCPServer           *mcp.Server
	AuditQuerier        AuditQuerier
	AuditMetricsQuerier AuditMetricsQuerier
	Knowledge           *KnowledgeHandler
	Memory              *MemoryHandler
	APIKeyManager       APIKeyManager
	BrowserAuth         *browsersession.Authenticator
	DatabaseAvailable   bool
	PlatformTools       []platform.ToolInfo
	AssetStore          portal.AssetStore
	ShareStore          portal.ShareStore
	VersionStore        portal.VersionStore
	S3Client            portal.S3Client
	S3Bucket            string
	ConnectionStore     ConnectionStore
	ConnectionSources   *platform.ConnectionSourceMap
	ToolkitsConfig      map[string]any
	PersonaStore        platform.PersonaStore
	APIKeyStore         platform.APIKeyStore
	PromptStore         prompt.Store
	PromptRegistrar     PromptRegistrar
	PromptInfoProvider  PromptInfoProvider
	FilePersonaNames    map[string]bool
	EnrichmentStore     EnrichmentStore
	EnrichmentEngine    EnrichmentEngine
	// PKCEStore holds in-flight authorization_code+PKCE state. When nil,
	// the handler falls back to a process-singleton in-memory store
	// (single-replica only). Set this to a PostgresPKCEStore for HA
	// deployments where oauth-start and the callback may land on
	// different replicas.
	PKCEStore PKCEStore
}

Deps holds dependencies for the admin handler.

type EnrichmentEngine added in v1.57.0

type EnrichmentEngine interface {
	Sources() *enrichment.SourceRegistry
}

EnrichmentEngine is the admin-facing surface of an enrichment.Engine. Defined as a small interface here so tests don't need to construct a real Engine.

type EnrichmentStore added in v1.57.0

type EnrichmentStore interface {
	List(ctx context.Context, connection, tool string, enabledOnly bool) ([]enrichment.Rule, error)
	Get(ctx context.Context, id string) (*enrichment.Rule, error)
	Create(ctx context.Context, r enrichment.Rule) (enrichment.Rule, error)
	Update(ctx context.Context, r enrichment.Rule) (enrichment.Rule, error)
	Delete(ctx context.Context, id string) error
}

EnrichmentStore abstracts enrichment.Store for the admin handler, so tests can swap in a stub without pulling in a real database.

type Handler

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

Handler provides admin REST API endpoints.

func NewHandler

func NewHandler(deps Deps, authMiddle func(http.Handler) http.Handler) *Handler

NewHandler creates a new admin API handler.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler.

type KnowledgeHandler

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

KnowledgeHandler provides admin REST endpoints for knowledge management.

func NewKnowledgeHandler

func NewKnowledgeHandler(
	insightStore knowledge.InsightStore,
	changesetStore knowledge.ChangesetStore,
	writer knowledge.DataHubWriter,
) *KnowledgeHandler

NewKnowledgeHandler creates a new knowledge admin handler.

func (*KnowledgeHandler) GetChangeset

func (h *KnowledgeHandler) GetChangeset(w http.ResponseWriter, r *http.Request)

GetChangeset handles GET /api/v1/admin/knowledge/changesets/{id}.

@Summary Get changeset @Description Returns a single changeset by ID. @Tags Knowledge @Produce json @Param id path string true "Changeset ID" @Success 200 {object} knowledge.Changeset @Failure 404 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/knowledge/changesets/{id} [get]

func (*KnowledgeHandler) GetInsight

func (h *KnowledgeHandler) GetInsight(w http.ResponseWriter, r *http.Request)

GetInsight handles GET /api/v1/admin/knowledge/insights/{id}.

@Summary Get insight @Description Returns a single insight by ID. @Tags Knowledge @Produce json @Param id path string true "Insight ID" @Success 200 {object} knowledge.Insight @Failure 404 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/knowledge/insights/{id} [get]

func (*KnowledgeHandler) GetStats

func (h *KnowledgeHandler) GetStats(w http.ResponseWriter, r *http.Request)

GetStats handles GET /api/v1/admin/knowledge/insights/stats.

@Summary Get insight stats @Description Returns aggregated insight statistics by entity, category, confidence, and status. @Tags Knowledge @Produce json @Param status query string false "Filter by status" @Param category query string false "Filter by category" @Param entity_urn query string false "Filter by entity URN" @Param captured_by query string false "Filter by capturer" @Param confidence query string false "Filter by confidence level" @Param since query string false "Insights after this time (RFC 3339)" @Param until query string false "Insights before this time (RFC 3339)" @Success 200 {object} knowledge.InsightStats @Failure 500 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/knowledge/insights/stats [get]

func (*KnowledgeHandler) ListChangesets

func (h *KnowledgeHandler) ListChangesets(w http.ResponseWriter, r *http.Request)

ListChangesets handles GET /api/v1/admin/knowledge/changesets.

@Summary List changesets @Description Returns paginated changesets with optional filtering. @Tags Knowledge @Produce json @Param entity_urn query string false "Filter by entity URN" @Param applied_by query string false "Filter by applier" @Param rolled_back query boolean false "Filter by rollback state" @Param since query string false "Changesets after this time (RFC 3339)" @Param until query string false "Changesets before this time (RFC 3339)" @Param page query integer false "Page number, 1-based (default: 1)" @Param per_page query integer false "Results per page (default: 20)" @Success 200 {object} changesetListResponse @Failure 500 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/knowledge/changesets [get]

func (*KnowledgeHandler) ListInsights

func (h *KnowledgeHandler) ListInsights(w http.ResponseWriter, r *http.Request)

ListInsights handles GET /api/v1/admin/knowledge/insights.

@Summary List insights @Description Returns paginated insights with optional filtering. @Tags Knowledge @Produce json @Param status query string false "Filter by status" @Param category query string false "Filter by category" @Param entity_urn query string false "Filter by entity URN" @Param captured_by query string false "Filter by capturer" @Param confidence query string false "Filter by confidence level" @Param since query string false "Insights after this time (RFC 3339)" @Param until query string false "Insights before this time (RFC 3339)" @Param page query integer false "Page number, 1-based (default: 1)" @Param per_page query integer false "Results per page (default: 20)" @Success 200 {object} insightListResponse @Failure 500 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/knowledge/insights [get]

func (*KnowledgeHandler) RollbackChangeset

func (h *KnowledgeHandler) RollbackChangeset(w http.ResponseWriter, r *http.Request)

RollbackChangeset handles POST /api/v1/admin/knowledge/changesets/{id}/rollback.

@Summary Rollback changeset @Description Rolls back a changeset, restoring previous values to DataHub. @Tags Knowledge @Produce json @Param id path string true "Changeset ID" @Success 200 {object} statusResponse @Failure 404 {object} problemDetail @Failure 409 {object} problemDetail @Failure 500 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/knowledge/changesets/{id}/rollback [post]

func (*KnowledgeHandler) UpdateInsight

func (h *KnowledgeHandler) UpdateInsight(w http.ResponseWriter, r *http.Request)

UpdateInsight handles PUT /api/v1/admin/knowledge/insights/{id}.

@Summary Update insight @Description Update insight text, category, or confidence. Cannot edit an applied insight. @Tags Knowledge @Accept json @Produce json @Param id path string true "Insight ID" @Param body body insightUpdateRequest true "Fields to update" @Success 200 {object} statusResponse @Failure 400 {object} problemDetail @Failure 404 {object} problemDetail @Failure 409 {object} problemDetail @Failure 500 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/knowledge/insights/{id} [put]

func (*KnowledgeHandler) UpdateInsightStatus

func (h *KnowledgeHandler) UpdateInsightStatus(w http.ResponseWriter, r *http.Request)

UpdateInsightStatus handles PUT /api/v1/admin/knowledge/insights/{id}/status.

@Summary Update insight status @Description Approve or reject an insight. Status must be 'approved' or 'rejected'. @Tags Knowledge @Accept json @Produce json @Param id path string true "Insight ID" @Param body body statusUpdateRequest true "Status update" @Success 200 {object} statusResponse @Failure 400 {object} problemDetail @Failure 404 {object} problemDetail @Failure 409 {object} problemDetail @Failure 500 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/knowledge/insights/{id}/status [put]

type MemoryHandler added in v1.52.0

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

MemoryHandler provides admin REST endpoints for memory record management.

func NewMemoryHandler added in v1.52.0

func NewMemoryHandler(store memory.Store) *MemoryHandler

NewMemoryHandler creates a new memory admin handler.

func (*MemoryHandler) DeleteRecord added in v1.52.0

func (h *MemoryHandler) DeleteRecord(w http.ResponseWriter, r *http.Request)

DeleteRecord handles DELETE /api/v1/admin/memory/records/{id}.

@Summary Archive memory record @Description Soft-deletes a memory record by setting its status to archived. @Tags Memory @Produce json @Param id path string true "Record ID" @Success 200 {object} statusResponse @Failure 404 {object} problemDetail @Failure 500 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/memory/records/{id} [delete]

func (*MemoryHandler) GetRecord added in v1.52.0

func (h *MemoryHandler) GetRecord(w http.ResponseWriter, r *http.Request)

GetRecord handles GET /api/v1/admin/memory/records/{id}.

@Summary Get memory record @Description Returns a single memory record by ID. @Tags Memory @Produce json @Param id path string true "Record ID" @Success 200 {object} memory.Record @Failure 404 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/memory/records/{id} [get]

func (*MemoryHandler) GetStats added in v1.52.0

func (h *MemoryHandler) GetStats(w http.ResponseWriter, r *http.Request)

GetStats handles GET /api/v1/admin/memory/records/stats.

@Summary Get memory record stats @Description Returns aggregated memory record statistics by dimension, category, and status. @Tags Memory @Produce json @Param persona query string false "Filter by persona" @Param dimension query string false "Filter by dimension" @Param category query string false "Filter by category" @Param status query string false "Filter by status" @Param source query string false "Filter by source" @Param entity_urn query string false "Filter by entity URN" @Param created_by query string false "Filter by creator" @Param since query string false "Records after this time (RFC 3339)" @Param until query string false "Records before this time (RFC 3339)" @Success 200 {object} memoryStatsResponse @Failure 500 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/memory/records/stats [get]

func (*MemoryHandler) ListRecords added in v1.52.0

func (h *MemoryHandler) ListRecords(w http.ResponseWriter, r *http.Request)

ListRecords handles GET /api/v1/admin/memory/records.

@Summary List memory records @Description Returns paginated memory records with optional filtering. @Tags Memory @Produce json @Param persona query string false "Filter by persona" @Param dimension query string false "Filter by dimension" @Param category query string false "Filter by category" @Param status query string false "Filter by status" @Param source query string false "Filter by source" @Param entity_urn query string false "Filter by entity URN" @Param created_by query string false "Filter by creator" @Param since query string false "Records after this time (RFC 3339)" @Param until query string false "Records before this time (RFC 3339)" @Param page query integer false "Page number, 1-based (default: 1)" @Param per_page query integer false "Results per page (default: 20)" @Success 200 {object} memoryListResponse @Failure 500 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/memory/records [get]

func (*MemoryHandler) UpdateRecord added in v1.52.0

func (h *MemoryHandler) UpdateRecord(w http.ResponseWriter, r *http.Request)

UpdateRecord handles PUT /api/v1/admin/memory/records/{id}.

@Summary Update memory record @Description Update content, category, confidence, dimension, or metadata on a record. @Tags Memory @Accept json @Produce json @Param id path string true "Record ID" @Param body body memoryUpdateRequest true "Fields to update" @Success 200 {object} statusResponse @Failure 400 {object} problemDetail @Failure 404 {object} problemDetail @Failure 409 {object} problemDetail @Failure 500 {object} problemDetail @Security ApiKeyAuth @Security BearerAuth @Router /admin/memory/records/{id} [put]

type MemoryPKCEStore added in v1.57.0

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

MemoryPKCEStore is an in-process map keyed by state token. Sweeps expired entries on every put/take AND on a background ticker so an idle server still releases stranded oauth-start records.

Single-replica deployments and tests use this directly. Production multi-replica deployments use PostgresPKCEStore.

func NewMemoryPKCEStore added in v1.57.0

func NewMemoryPKCEStore() *MemoryPKCEStore

NewMemoryPKCEStore returns a store with a background GC goroutine running on pkceGCInterval. Callers MUST Close() it to release the goroutine — typically via t.Cleanup() in tests or a deferred close in production process teardown.

func (*MemoryPKCEStore) Close added in v1.57.0

func (s *MemoryPKCEStore) Close() error

Close stops the background GC goroutine. Idempotent.

func (*MemoryPKCEStore) Put added in v1.57.0

func (s *MemoryPKCEStore) Put(_ context.Context, state string, val *PKCEState) error

Put stores a state under the given token, sweeping expired entries opportunistically.

func (*MemoryPKCEStore) Take added in v1.57.0

func (s *MemoryPKCEStore) Take(_ context.Context, state string) (*PKCEState, error)

Take returns and deletes the matching state, or ErrPKCEStateNotFound if absent. Expired entries are GC'd before lookup so callers don't need to check pkceTTL themselves.

type PKCEState added in v1.57.0

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

PKCEState is the server-side hold for one pending OAuth flow. Maps the random state token to the data the callback handler needs.

Exported so the PKCEStore interface (MemoryPKCEStore / PostgresPKCEStore) can carry pointers to it across implementations without revive flagging the methods as exported-but-returning- unexported. Fields stay package-private; consumers from outside admin should not need to introspect a state in flight.

type PKCEStore added in v1.57.0

type PKCEStore interface {
	// Put stores a state record. Implementations may evict entries that
	// have outlived the platform's pkceTTL on every Put.
	Put(ctx context.Context, state string, val *PKCEState) error

	// Take atomically reads-and-deletes a state record. Returns
	// ErrPKCEStateNotFound when no row matches (or the row had
	// already expired). Other errors indicate transport/IO failure.
	Take(ctx context.Context, state string) (*PKCEState, error)

	// Close releases any background goroutines or DB resources. Safe
	// to call multiple times.
	Close() error
}

PKCEStore holds in-flight PKCE state across the oauth-start → /oauth/callback round trip. Implementations must be safe for concurrent use.

Two implementations ship: an in-memory map (single-replica, default) and a Postgres-backed store (multi-replica safe). The Handler picks based on whether a database is configured.

type PersonaRegistry added in v0.17.0

type PersonaRegistry interface {
	All() []*persona.Persona
	Get(name string) (*persona.Persona, bool)
	Register(p *persona.Persona) error
	Unregister(name string) error
	DefaultName() string
}

PersonaRegistry abstracts persona.Registry for testability.

type PlatformAuthOption added in v0.32.0

type PlatformAuthOption func(*PlatformAuthenticator)

PlatformAuthOption configures the PlatformAuthenticator.

func WithBrowserSessionAuth added in v0.32.0

func WithBrowserSessionAuth(ba *browsersession.Authenticator) PlatformAuthOption

WithBrowserSessionAuth adds cookie-based authentication.

type PlatformAuthenticator added in v0.17.0

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

PlatformAuthenticator wraps the platform's middleware.Authenticator chain for HTTP admin requests, validating that the resolved persona matches the configured admin persona.

func NewPlatformAuthenticator added in v0.17.0

func NewPlatformAuthenticator(
	auth middleware.Authenticator,
	adminPersona string,
	registry *persona.Registry,
	opts ...PlatformAuthOption,
) *PlatformAuthenticator

NewPlatformAuthenticator creates a PlatformAuthenticator that bridges the platform's MCP auth chain to HTTP admin requests.

func (*PlatformAuthenticator) Authenticate added in v0.17.0

func (pa *PlatformAuthenticator) Authenticate(r *http.Request) (*User, error)

Authenticate extracts credentials from the HTTP request, delegates to the platform authenticator, then checks that the resolved persona matches the admin persona. It checks browser session cookies first, then falls back to token-based authentication.

type PostgresPKCEStore added in v1.57.0

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

PostgresPKCEStore persists in-flight PKCE state to the oauth_pkce_states table. Used in multi-replica deployments where oauth-start may run on a different pod than /oauth/callback.

code_verifier is encrypted at rest via the platform's gatewaykit.FieldEncryptor — verifiers are short-lived (≤pkceTTL) but they are paired secrets, so a DB read of them while still in flight is roughly equivalent to leaking a short-window OAuth refresh token.

We reuse gatewaykit's encryptor interface rather than declaring a duplicate to keep one canonical interface for at-rest field encryption across sub-package stores.

func NewPostgresPKCEStore added in v1.57.0

func NewPostgresPKCEStore(db *sql.DB, enc gatewaykit.FieldEncryptor) *PostgresPKCEStore

NewPostgresPKCEStore returns a Postgres-backed PKCE store that runs a background sweeper to delete expired rows. Pass nil for enc to skip at-rest encryption (dev-only).

func (*PostgresPKCEStore) Close added in v1.57.0

func (s *PostgresPKCEStore) Close() error

Close stops the background sweeper. Idempotent.

func (*PostgresPKCEStore) Put added in v1.57.0

func (s *PostgresPKCEStore) Put(ctx context.Context, state string, val *PKCEState) error

Put inserts a state row. The expires_at column is computed server-side (NOW() + interval matching pkceTTL) so the take-side filter NOW() comparison can't be defeated by Go-process / Postgres clock drift. ON CONFLICT (state) DO NOTHING rejects collisions loudly via ErrPKCEStateCollision.

func (*PostgresPKCEStore) Take added in v1.57.0

func (s *PostgresPKCEStore) Take(ctx context.Context, state string) (*PKCEState, error)

Take atomically reads-and-deletes the matching row using DELETE … RETURNING so two concurrent callbacks (a real one and a replay) race-cleanly: only one wins. Returns ErrPKCEStateNotFound for missing or expired rows.

type PromptInfoProvider added in v1.51.0

type PromptInfoProvider interface {
	AllPromptInfos() []registry.PromptInfo
}

PromptInfoProvider returns metadata about platform-registered prompts (auto, workflow, toolkit, custom config). These are system prompts not stored in the database.

type PromptRegistrar added in v1.51.0

type PromptRegistrar interface {
	RegisterRuntimePrompt(p *prompt.Prompt)
	UnregisterRuntimePrompt(name string)
}

PromptRegistrar registers/unregisters prompts with the live MCP server.

type ToolActivityAggregate added in v1.57.0

type ToolActivityAggregate struct {
	WindowSeconds int64   `json:"window_seconds"`
	CallCount     int     `json:"call_count"`
	SuccessRate   float64 `json:"success_rate"`
	AvgDurationMs float64 `json:"avg_duration_ms"`
}

ToolActivityAggregate is the per-tool audit summary surfaced on the Activity tab. We use the existing Breakdown(by tool_name) aggregator rather than a new percentile query — Count, SuccessRate, and AvgDurationMS are what the breakdown returns natively.

type ToolDetail added in v1.57.0

type ToolDetail struct {
	Name        string `json:"name"`
	Title       string `json:"title,omitempty"`
	Description string `json:"description"`

	ToolkitKind string `json:"toolkit_kind"`
	ToolkitName string `json:"toolkit_name,omitempty"`
	Connection  string `json:"connection,omitempty"`

	// JSON Schema for the tool's input parameters.
	InputSchema any `json:"input_schema,omitempty"`

	// Persona allow/deny matrix — one entry per database-managed
	// persona, with the matched pattern and source recorded.
	Personas []ToolPersonaAccess `json:"personas"`

	// HiddenByGlobalDeny is true when the platform-level tools.deny
	// list matches this tool. GlobalDenyPattern is the matching glob.
	HiddenByGlobalDeny bool   `json:"hidden_by_global_deny"`
	GlobalDenyPattern  string `json:"global_deny_pattern,omitempty"`

	// HiddenByPersona maps persona name → true for any persona where
	// this tool is denied.
	HiddenByPersona map[string]bool `json:"hidden_by_persona,omitempty"`

	// Description-override status (populated when a
	// tool.<name>.description config-entry exists).
	DescriptionOverridden bool   `json:"description_overridden"`
	OverrideAuthor        string `json:"override_author,omitempty"`

	Activity *ToolActivityAggregate `json:"activity,omitempty"`

	// Number of cross-enrichment rules attached to this tool. Only
	// meaningful for proxied tools (kind=mcp); zero for native.
	EnrichmentRuleCount int `json:"enrichment_rule_count"`
}

ToolDetail is the aggregating response for GET /api/v1/admin/tools/{name}. It joins data scattered across the registry, the description-override middleware, persona definitions, the gateway enrichment store, and the audit aggregator so the admin Tools page can render everything for a tool from a single round-trip.

type ToolPersonaAccess added in v1.57.0

type ToolPersonaAccess struct {
	Persona           string               `json:"persona"`
	Allowed           bool                 `json:"allowed"`
	MatchedPattern    string               `json:"matched_pattern,omitempty"`
	Source            persona.AccessSource `json:"source"`
	ConnectionAllowed bool                 `json:"connection_allowed"`
}

ToolPersonaAccess records one persona's end-to-end decision for the tool.

Allowed reflects (tool allow/deny) AND (connection allow/deny). The MatchedPattern / Source fields describe the tool-rule decision; when the tool rule allows but the connection rule denies, ConnectionAllowed is false and Allowed is false — surfaced separately so operators can see both halves of the gate.

type ToolkitRegistry added in v0.17.0

type ToolkitRegistry interface {
	All() []registry.Toolkit
	AllTools() []string
	GetToolkitForTool(toolName string) registry.ToolkitMatch
}

ToolkitRegistry abstracts registry.Registry for testability.

type User

type User struct {
	UserID string
	Email  string
	Roles  []string
}

User holds information about the authenticated admin user.

func GetUser

func GetUser(ctx context.Context) *User

GetUser returns the User from context, or nil if not set.

Jump to

Keyboard shortcuts

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