Documentation
¶
Index ¶
- Constants
- func ConvertAPIActivity(a APIActivity) types2.APIActivity
- func ConvertDevice(d Device) types2.Device
- func ConvertDeviceScan(s DeviceScan) types2.DeviceScan
- func ConvertDeviceScanClient(c DeviceScanClient) types2.DeviceScanClient
- func ConvertDeviceScanFile(f DeviceScanFile) types2.DeviceScanFile
- func ConvertDeviceScanMCPServer(m DeviceScanMCPServer) types2.DeviceScanMCPServer
- func ConvertDeviceScanPlugin(p DeviceScanPlugin) types2.DeviceScanPlugin
- func ConvertDeviceScanSkill(s DeviceScanSkill) types2.DeviceScanSkill
- func ConvertLLMAuditLog(a LLMAuditLog) types2.LLMAuditLog
- func ConvertMCPUsageStats(s MCPUsageStatItem) types2.MCPUsageStatItem
- func ConvertRemainingTokenUsage(userID string, r *RemainingTokenUsage) types2.RemainingTokenUsage
- func ConvertTokenActivity(a RunTokenActivity) types2.TokenUsage
- func ConvertUser(u *User, roleFixed bool, authProviderName string) *types2.User
- func ConvertUserWithEffectiveRole(u *User, roleFixed bool, authProviderName string, effectiveRole types2.Role) *types2.User
- func DevicePrincipalName(deviceID string) string
- func MDMConfigurationPrincipalName(id uint) string
- type APIActivity
- type APIKey
- type APIKeyCreateResponse
- type APIKeyScopes
- type AuthToken
- type ClientStat
- type Credential
- type Device
- type DeviceEnrollmentKey
- type DeviceEnrollmentKeyCreateResponse
- type DeviceScan
- type DeviceScanClient
- type DeviceScanFile
- type DeviceScanMCPServer
- type DeviceScanPlugin
- type DeviceScanSkill
- type EnforcementDecisionLog
- type Group
- type GroupMemberships
- type GroupRoleAssignment
- type Identity
- type Image
- type LLMAuditLog
- type LocalAgentToolCallAuditLogFields
- type LocalAuthSession
- type LocalAuthUser
- type MCPAuditLog
- type MCPAuditLogFields
- type MCPOAuthPendingState
- type MCPOAuthToken
- type MCPPromptReadStats
- type MCPResourceReadStats
- type MCPServerDetail
- type MCPServerOccurrence
- type MCPServerStat
- type MCPToolCallStats
- type MCPToolCallStatsItem
- type MCPUsageStatItem
- type MCPUsageStatsList
- type MCPWebhookStatus
- type MDMAssetBundle
- type MDMConfiguration
- type MDMConfigurationArtifact
- type MDMConfigurationEnforcement
- type MessagePolicyViolation
- type Migration
- type Property
- type RemainingTokenUsage
- type RunTokenActivity
- type ServiceAccountAPIKey
- type SkillDetail
- type SkillOccurrence
- type SkillStat
- type TempSetupUser
- type TokenRequest
- type TokenUsage
- type User
- type UserQuery
Constants ¶
const ( LLMAuditOutcomeSuccess = "success" LLMAuditOutcomeCanceled = "canceled" LLMAuditOutcomeError = "error" )
const DevicePrincipalPrefix = "device"
DevicePrincipalPrefix namespaces the principal identity (Name/UID) of an enrolled device so it never collides with user UIDs or configuration principals.
const MDMConfigurationPrincipalPrefix = "mdm-configuration"
MDMConfigurationPrincipalPrefix namespaces the principal identity (Name/UID) of a MDM configuration so it never collides with user UIDs or device principals. An enrollment credential authenticates as its configuration.
Variables ¶
This section is empty.
Functions ¶
func ConvertAPIActivity ¶ added in v0.7.1
func ConvertAPIActivity(a APIActivity) types2.APIActivity
func ConvertDevice ¶ added in v0.24.0
ConvertDevice maps a gateway device record to its API representation, dropping the registered public key.
func ConvertDeviceScan ¶ added in v0.22.0
func ConvertDeviceScan(s DeviceScan) types2.DeviceScan
ConvertDeviceScan converts internal DeviceScan to API type. Children must already be loaded (via Preload) for them to appear in the result.
func ConvertDeviceScanClient ¶ added in v0.22.0
func ConvertDeviceScanClient(c DeviceScanClient) types2.DeviceScanClient
func ConvertDeviceScanFile ¶ added in v0.22.0
func ConvertDeviceScanFile(f DeviceScanFile) types2.DeviceScanFile
ConvertDeviceScanFile converts a stored file row to its wire form. Content is included only when the file wasn't flagged as oversized.
func ConvertDeviceScanMCPServer ¶ added in v0.22.0
func ConvertDeviceScanMCPServer(m DeviceScanMCPServer) types2.DeviceScanMCPServer
func ConvertDeviceScanPlugin ¶ added in v0.22.0
func ConvertDeviceScanPlugin(p DeviceScanPlugin) types2.DeviceScanPlugin
func ConvertDeviceScanSkill ¶ added in v0.22.0
func ConvertDeviceScanSkill(s DeviceScanSkill) types2.DeviceScanSkill
func ConvertLLMAuditLog ¶ added in v0.24.0
func ConvertLLMAuditLog(a LLMAuditLog) types2.LLMAuditLog
func ConvertMCPUsageStats ¶ added in v0.8.0
func ConvertMCPUsageStats(s MCPUsageStatItem) types2.MCPUsageStatItem
ConvertMCPUsageStats converts internal MCPUsageStatItem to API type
func ConvertRemainingTokenUsage ¶ added in v0.8.0
func ConvertRemainingTokenUsage(userID string, r *RemainingTokenUsage) types2.RemainingTokenUsage
func ConvertTokenActivity ¶ added in v0.8.0
func ConvertTokenActivity(a RunTokenActivity) types2.TokenUsage
func ConvertUserWithEffectiveRole ¶ added in v0.15.0
func DevicePrincipalName ¶ added in v0.24.0
DevicePrincipalName returns the stable principal identity for an enrolled device, e.g. "device:abc-123". This is what a device authenticates as when submitting a scan; the scan itself is identified by DeviceScan.DeviceID (device submissions leave SubmittedBy empty).
func MDMConfigurationPrincipalName ¶ added in v0.24.0
MDMConfigurationPrincipalName returns the stable principal identity for a configuration, e.g. "mdm-configuration:12".
Types ¶
type APIKey ¶ added in v0.16.0
type APIKey struct {
APIKeyScopes `json:",inline"`
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
UserID uint `json:"userId" gorm:"index"`
Name string `json:"name"` // User-provided name for the key
Description string `json:"description,omitempty"` // Optional description
HashedSecret string `json:"-"` // bcrypt hash of the secret portion only
CreatedAt time.Time `json:"createdAt"`
LastUsedAt *time.Time `json:"lastUsedAt,omitempty"`
ExpiresAt *time.Time `json:"expiresAt,omitempty"` // nil means no expiration
}
APIKey represents an API key for a user to access the Obot API. The key format is: ok1-<user_id>-<key_id>-<secret> Lookups are done by key ID (extracted from the token), then bcrypt.CompareHashAndPassword is used to verify the secret portion.
type APIKeyCreateResponse ¶ added in v0.16.0
type APIKeyCreateResponse struct {
APIKey
Key string `json:"key"` // The full key, only shown once
}
APIKeyCreateResponse is returned when creating an API key. This is the only time the full key is visible.
type APIKeyScopes ¶ added in v0.23.0
type APIKeyScopes struct {
CanAccessAPI bool `json:"canAccessAPI" gorm:"default:false;not null"`
CanAccessSkills bool `json:"canAccessSkills" gorm:"default:false;not null"`
CanAccessLLMProxy bool `json:"canAccessLLMProxy" gorm:"default:false;not null"`
CanAccessDeviceScans bool `json:"canAccessDeviceScans" gorm:"default:false;not null"`
CanAccessPublishedArtifacts bool `json:"canAccessPublishedArtifacts" gorm:"default:false;not null"`
// MCPServerIDs contains Kubernetes resource names of MCPServers this key can access.
// Supports all server types: single-user, multi-user, remote, and composite.
// Use "*" as a wildcard to grant access to all servers the user can access.
// This may be empty for skills-only API keys.
MCPServerIDs []string `json:"mcpServerIds,omitempty" gorm:"serializer:json"`
}
func (APIKeyScopes) Groups ¶ added in v0.23.0
func (as APIKeyScopes) Groups(u *User) []string
func (APIKeyScopes) HasSomeScope ¶ added in v0.23.0
func (as APIKeyScopes) HasSomeScope() bool
type AuthToken ¶
type AuthToken struct {
ID string `json:"id" gorm:"index:idx_id_hashed_token"`
UserID uint `json:"-" gorm:"index"`
AuthProviderNamespace string `json:"-" gorm:"index"`
AuthProviderName string `json:"-" gorm:"index"`
AuthProviderUserID string `json:"-"`
HashedToken string `json:"-" gorm:"index:idx_id_hashed_token"`
CreatedAt time.Time `json:"createdAt"`
ExpiresAt time.Time `json:"expiresAt,omitzero"`
NoExpiration bool `json:"noExpiration"`
}
type ClientStat ¶ added in v0.22.0
type ClientStat struct {
Name string `gorm:"column:name"`
DeviceCount int64 `gorm:"column:device_count"`
UserCount int64 `gorm:"column:user_count"`
ObservationCount int64 `gorm:"column:observation_count"`
}
ClientStat is one row of the per-client rollup.
type Credential ¶ added in v0.23.0
type Credential struct {
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
CreatedAt time.Time `json:"createdAt"`
Context string `json:"context" gorm:"uniqueIndex:idx_credentials_context_name;not null"`
Name string `json:"name" gorm:"uniqueIndex:idx_credentials_context_name;not null"`
Secrets map[string]string `json:"secrets" gorm:"serializer:json"`
Encrypted bool `json:"-"`
}
Credential stores secret environment variables for an Obot resource. List operations intentionally return Secrets keys with blank values; use RevealCredential to read values.
type Device ¶ added in v0.24.0
type Device struct {
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
DeviceID string `json:"deviceID" gorm:"uniqueIndex;not null"` // client-computed, stable
MDMConfigurationID uint `json:"mdmConfigurationID" gorm:"index:idx_devices_configuration_enrolled,priority:1;not null"` // the configuration this device belongs to
PublicKey []byte `json:"-"` // DER SubjectPublicKeyInfo (PKIX) of the identity key
Hostname string `json:"hostname,omitempty"`
OS string `json:"os,omitempty"`
OSVersion string `json:"osVersion,omitempty"`
EnrolledAt time.Time `json:"enrolledAt" gorm:"index:idx_devices_configuration_enrolled,priority:2"`
LastSeenAt *time.Time `json:"lastSeenAt,omitempty"`
}
Device is one machine that belongs to a MDMConfiguration, identified by a stable, client-computed DeviceID.
PublicKey is the device's identity key, registered trust-on-first-use at enrollment. The device proves possession of it by signing short-lived JWTs that it presents directly when submitting scans; a request to bind a different key to an existing DeviceID is rejected (anti-takeover).
type DeviceEnrollmentKey ¶ added in v0.24.0
type DeviceEnrollmentKey struct {
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
MDMConfigurationID uint `json:"mdmConfigurationID" gorm:"index;not null"`
Name string `json:"name,omitempty"` // optional, admin-provided
HashedSecret string `json:"-"` // bcrypt hash of the secret portion only
CreatedBy uint `json:"createdBy"`
CreatedAt time.Time `json:"createdAt"`
LastUsedAt *time.Time `json:"lastUsedAt,omitempty"`
ExpiresAt *time.Time `json:"expiresAt,omitempty"` // nil means no expiration
}
DeviceEnrollmentKey is one credential that authorizes enrolling a device into its configuration. A configuration can have several at once, added and removed independently. Deleting a key only stops it from enrolling new devices — it never affects already-enrolled devices (they authenticate with their own keys). Rotation is therefore: add a new key, distribute it, delete the old.
The credential format is: ode1-<configuration_id>-<key_id>-<secret> Lookup is by key ID (scoped to the configuration), then bcrypt verifies the secret.
type DeviceEnrollmentKeyCreateResponse ¶ added in v0.24.0
type DeviceEnrollmentKeyCreateResponse struct {
DeviceEnrollmentKey
EnrollmentCredential string `json:"enrollmentCredential"` // ode1-..., shown once
}
DeviceEnrollmentKeyCreateResponse is returned when minting a key. The full enrollment credential is only visible here.
type DeviceScan ¶ added in v0.22.0
type DeviceScan struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"createdAt" gorm:"index:idx_ds_user_time,priority:2;index:idx_ds_device_time,priority:2"`
SubmittedBy string `json:"submittedBy" gorm:"index:idx_ds_user_time,priority:1"`
DeviceID string `json:"deviceID" gorm:"index:idx_ds_device_time,priority:1"`
Hostname string `json:"hostname"`
Username string `json:"username"`
OS string `json:"os"`
Arch string `json:"arch"`
ScannerVersion string `json:"scannerVersion"`
ScannedAt time.Time `json:"scannedAt" gorm:"index"`
MCPServers []DeviceScanMCPServer `json:"mcpServers,omitempty" gorm:"foreignKey:DeviceScanID;constraint:OnDelete:CASCADE"`
Skills []DeviceScanSkill `json:"skills,omitempty" gorm:"foreignKey:DeviceScanID;constraint:OnDelete:CASCADE"`
Plugins []DeviceScanPlugin `json:"plugins,omitempty" gorm:"foreignKey:DeviceScanID;constraint:OnDelete:CASCADE"`
Files []DeviceScanFile `json:"files,omitempty" gorm:"foreignKey:DeviceScanID;constraint:OnDelete:CASCADE"`
Clients []DeviceScanClient `json:"clients,omitempty" gorm:"foreignKey:DeviceScanID;constraint:OnDelete:CASCADE"`
}
DeviceScan is the parent envelope. Children (MCPServers, Skills, Plugins, Files) are GORM associations — db.Create(&scan) inserts everything atomically; db.Preload(...).First(...) loads them back.
Composite indexes:
- idx_ds_user_time (submitted_by, created_at) — list scans for a user
- idx_ds_device_time (device_id, created_at) — list scans for a device
func DeviceScanFromManifest ¶ added in v0.22.0
func DeviceScanFromManifest(p types2.DeviceScanManifest) DeviceScan
DeviceScanFromManifest builds a gateway DeviceScan + its children from a submission manifest. Caller is responsible for setting SubmittedBy on the returned struct before passing it to InsertDeviceScan.
type DeviceScanClient ¶ added in v0.22.0
type DeviceScanClient struct {
ID uint `json:"id" gorm:"primaryKey"`
DeviceScanID uint `json:"deviceScanID" gorm:"index;not null"`
CreatedAt time.Time `json:"createdAt" gorm:"index"`
Name string `json:"name" gorm:"index"`
Version string `json:"version"`
BinaryPath string `json:"binaryPath"`
InstallPath string `json:"installPath"`
ConfigPath string `json:"configPath"`
HasMCPServers bool `json:"hasMCPServers"`
HasSkills bool `json:"hasSkills"`
HasPlugins bool `json:"hasPlugins"`
}
DeviceScanClient is a per-scan record for an AI client observed on the device. Presence facts (BinaryPath, InstallPath, StateDir, Version) come from generic per-client detection. Has{MCPServers, Skills,Plugins} are roll-ups derived from observations attributed to this client name in the same scan.
type DeviceScanFile ¶ added in v0.22.0
type DeviceScanFile struct {
ID uint `json:"id" gorm:"primaryKey"`
DeviceScanID uint `json:"deviceScanID" gorm:"index;not null"`
CreatedAt time.Time `json:"createdAt" gorm:"index"`
Path string `json:"path" gorm:"index"`
SizeBytes int64 `json:"sizeBytes"`
Oversized bool `json:"oversized"`
Content string `json:"content" gorm:"type:text"`
}
type DeviceScanMCPServer ¶ added in v0.22.0
type DeviceScanMCPServer struct {
ID uint `json:"id" gorm:"primaryKey"`
DeviceScanID uint `json:"deviceScanID" gorm:"index;not null"`
CreatedAt time.Time `json:"createdAt" gorm:"index"`
Client string `json:"client" gorm:"index"`
Scope string `json:"scope" gorm:"index"`
ProjectPath string `json:"projectPath" gorm:"index"`
File string `json:"file"`
Name string `json:"name" gorm:"index"`
Transport string `json:"transport" gorm:"index"`
Command string `json:"command"`
Args datatypes.JSONSlice[string] `json:"args"`
URL string `json:"url"`
EnvKeys datatypes.JSONSlice[string] `json:"envKeys"`
HeaderKeys datatypes.JSONSlice[string] `json:"headerKeys"`
ConfigHash string `json:"configHash" gorm:"index"`
}
DeviceScanMCPServer is one MCP server observation. Scope is derived at insert time from ProjectPath ("" → "global", non-empty → "project") and persisted denormalized so list queries hit a single table.
type DeviceScanPlugin ¶ added in v0.22.0
type DeviceScanPlugin struct {
ID uint `json:"id" gorm:"primaryKey"`
DeviceScanID uint `json:"deviceScanID" gorm:"index;not null"`
CreatedAt time.Time `json:"createdAt" gorm:"index"`
Client string `json:"client" gorm:"index"`
Scope string `json:"scope" gorm:"index"`
ProjectPath string `json:"projectPath" gorm:"index"`
ConfigPath string `json:"configPath"`
Name string `json:"name" gorm:"index"`
PluginType string `json:"pluginType" gorm:"index"`
Version string `json:"version"`
Description string `json:"description"`
Author string `json:"author"`
Enabled bool `json:"enabled"`
Marketplace string `json:"marketplace"`
Files datatypes.JSONSlice[string] `json:"files"`
HasMCPServers bool `json:"hasMCPServers"`
HasSkills bool `json:"hasSkills"`
HasRules bool `json:"hasRules"`
HasCommands bool `json:"hasCommands"`
HasHooks bool `json:"hasHooks"`
}
type DeviceScanSkill ¶ added in v0.22.0
type DeviceScanSkill struct {
ID uint `json:"id" gorm:"primaryKey"`
DeviceScanID uint `json:"deviceScanID" gorm:"index;not null"`
CreatedAt time.Time `json:"createdAt" gorm:"index"`
Client string `json:"client" gorm:"index"`
Scope string `json:"scope" gorm:"index"`
ProjectPath string `json:"projectPath" gorm:"index"`
File string `json:"file"`
Name string `json:"name" gorm:"index"`
Description string `json:"description"`
HasScripts bool `json:"hasScripts"`
GitRemoteURL string `json:"gitRemoteURL" gorm:"index"`
Files datatypes.JSONSlice[string] `json:"files"`
}
type EnforcementDecisionLog ¶ added in v0.25.0
type EnforcementDecisionLog struct {
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
CreatedAt time.Time `json:"createdAt" gorm:"index"`
// Fields describing the device:
MDMConfigurationID uint `json:"mdmConfigurationID" gorm:"index"`
DeviceID string `json:"deviceID,omitempty" gorm:"index"`
ClientIP string `json:"clientIP,omitempty" gorm:"index"`
// Fields describing the tool call:
Agent string `json:"agent,omitempty" gorm:"index"`
Tool string `json:"tool,omitempty" gorm:"index"`
Kind string `json:"kind,omitempty" gorm:"index"`
ServerName string `json:"serverName,omitempty" gorm:"index"`
ObotHosted bool `json:"obotHosted,omitempty"`
// Resolved server identity.
ServerURL string `json:"serverURL,omitempty"`
ServerHostname string `json:"serverHostname,omitempty"`
ServerCommand string `json:"serverCommand,omitempty"`
ServerPackageSource string `json:"serverPackageSource,omitempty"`
ServerPackageName string `json:"serverPackageName,omitempty"`
ServerPackageVersion string `json:"serverPackageVersion,omitempty"`
ServerConnector string `json:"serverConnector,omitempty"`
// Unresolved records that the device could not establish what the call
// targeted, with UnresolvedReason naming the cause it reported. The row is
// always a deny; these distinguish "we could not identify this" from "this
// is identified and not allowlisted".
Unresolved bool `json:"unresolved,omitempty"`
UnresolvedReason string `json:"unresolvedReason,omitempty"`
// Decision is the evaluator verdict: types.EnforcementDecisionAllow or
// types.EnforcementDecisionDeny. Reason is the evaluator's human-readable
// justification.
Decision string `json:"decision" gorm:"index"`
Reason string `json:"reason,omitempty"`
}
EnforcementDecisionLog is one recorded allow/deny decision made by the enforcement decision endpoint for a device's tool call.
type Group ¶ added in v0.9.0
type Group struct {
// ID is the globally unique identifier for the group.
// Each auth provider should use a different prefix for their groups to avoid collisions with other providers.
ID string `json:"id" gorm:"primaryKey;unique"`
// AuthProviderName is the name of the auth provider that the group belongs to.
// This is used to identify the auth provider that the group belongs to.
AuthProviderName string `json:"authProviderName" gorm:"primaryKey;index:idx_group_auth_provider"`
// AuthProviderNamespace is the namespace of the auth provider that the group belongs to.
// Note: This is pretty much always "default", but we're keeping it here for parity with the Identity type.
AuthProviderNamespace string `json:"authProviderNamespace" gorm:"primaryKey;index:idx_group_auth_provider"`
// Name is the display name of the group.
Name string `json:"name"`
// IconURL is the URL of the group's icon.
IconURL *string `json:"iconURL"`
}
Group represents a group that users can belong to in an auth provider.
type GroupMemberships ¶ added in v0.9.0
type GroupMemberships struct {
// UserID is the ID of the user that is a member of the group.
UserID uint `json:"userID" gorm:"primaryKey"`
// GroupID is the globally unique identifier for the group.
GroupID string `json:"groupID" gorm:"primaryKey"`
// CreatedAt is when the group membership was created.
CreatedAt time.Time `json:"createdAt" gorm:"autoCreateTime"`
}
GroupMemberships represents a user's membership in a group.
type GroupRoleAssignment ¶ added in v0.15.0
type GroupRoleAssignment struct {
// GroupName is the name of the auth provider group (used as primary key)
GroupName string `json:"groupName" gorm:"primaryKey"`
// CreatedAt is when the assignment was created
CreatedAt time.Time `json:"createdAt" gorm:"autoCreateTime"`
// UpdatedAt is when the assignment was last modified
UpdatedAt time.Time `json:"updatedAt" gorm:"autoUpdateTime"`
// Role is the role to assign to all members of the group
Role types2.Role `json:"role" gorm:"not null"`
// Description is an optional description of why this assignment exists
Description string `json:"description"`
}
GroupRoleAssignment assigns a role to all members of an auth provider group.
type Identity ¶
type Identity struct {
AuthProviderName string `json:"authProviderName" gorm:"primaryKey;index:idx_user_auth_id"`
AuthProviderNamespace string `json:"authProviderNamespace" gorm:"primaryKey;index:idx_user_auth_id"`
ProviderUsername string `json:"providerUsername"`
ProviderUserID string `json:"providerUserID"`
HashedProviderUserID string `json:"hashedProviderUserID" gorm:"primaryKey"`
ProviderGroupLookupID string `json:"providerGroupLookupID"`
Email string `json:"email"`
HashedEmail string `json:"hashedEmail"`
UserID uint `json:"userID" gorm:"index:idx_user_auth_id"`
IconURL string `json:"iconURL"`
IconLastChecked time.Time `json:"iconLastChecked"`
Encrypted bool `json:"encrypted"`
// AuthProviderGroupsLastChecked is the last time the identity's auth provider groups were checked.
AuthProviderGroupsLastChecked time.Time `json:"authProviderGroupsLastChecked"`
// AuthProviderGroups is the set of auth provider groups that the identity is a member of.
AuthProviderGroups []Group `json:"groups" gorm:"-"`
}
func (Identity) GetAuthProviderGroupIDs ¶ added in v0.9.0
func (Identity) GroupLookupID ¶ added in v0.18.0
type Image ¶ added in v0.7.0
type LLMAuditLog ¶ added in v0.24.0
type LLMAuditLog struct {
ID string `gorm:"primaryKey;type:text"`
CreatedAt time.Time `` /* 526-byte string literal not displayed */
Duration int64
UserID string `gorm:"type:text;index:idx_llm_audit_user_created,priority:1"`
ModelProvider string `gorm:"type:text;index:idx_llm_audit_provider_created,priority:1"`
ModelID string `gorm:"type:text"`
TargetModel string `gorm:"type:text;index:idx_llm_audit_target_model_created,priority:1"`
ReasoningEffort string `gorm:"type:text"`
RequestPath string `gorm:"type:text;index:idx_llm_audit_request_path_created,priority:1"`
RequestMethod string `gorm:"type:text"`
RequestHeaders json.RawMessage
RequestBody json.RawMessage
PolicyModifiedRequestBody json.RawMessage
MessagePolicyTriggered bool `gorm:"not null;default:false;index:idx_llm_audit_message_policy_triggered_created,priority:1"`
ResponseHeaders json.RawMessage
ResponseBody json.RawMessage
ResponseID string `gorm:"type:text;index:idx_llm_audit_response_created,priority:1"`
ResponseStatus int `gorm:"index:idx_llm_audit_response_status_created,priority:1"`
Outcome string `gorm:"type:text;index:idx_llm_audit_outcome_created,priority:1"`
Error string `gorm:"type:text"`
InputTokens int
OutputTokens int
RequestID string `gorm:"type:text"`
UserAgent string `gorm:"type:text;index:idx_llm_audit_user_agent_created,priority:1"`
ClientSessionID string `gorm:"type:text;index:idx_llm_audit_client_session_created,priority:1"`
ClientIP string `gorm:"type:text"`
Encrypted bool
}
func (LLMAuditLog) TableName ¶ added in v0.24.0
func (LLMAuditLog) TableName() string
type LocalAgentToolCallAuditLogFields ¶ added in v0.24.0
type LocalAgentToolCallAuditLogFields struct {
OccurredAt time.Time `json:"occurredAt" gorm:"index"`
StartedAt *time.Time `json:"startedAt,omitempty" gorm:"index"`
// ActorType and ActorID are stamped from authenticated request context. They are never copied
// from the client-reported event.
ActorType types2.AuditLogActorType `json:"actorType" gorm:"index"`
ActorID string `json:"actorID,omitempty" gorm:"index"`
ActionName string `json:"actionName" gorm:"index"`
ActionKind string `json:"actionKind,omitempty" gorm:"index"`
TargetType types2.AuditLogTargetType `json:"targetType" gorm:"index"`
TargetName string `json:"targetName" gorm:"index"`
TargetParentType types2.AuditLogTargetType `json:"targetParentType,omitempty" gorm:"index"`
TargetParentName string `json:"targetParentName,omitempty" gorm:"index"`
OutcomeStatus types2.AuditLogOutcomeStatus `json:"outcomeStatus" gorm:"index"`
OutcomeReason string `json:"outcomeReason,omitempty" gorm:"index"`
OutcomeError string `json:"outcomeError,omitempty" gorm:"column:local_agent_error"`
DurationMs int64 `json:"durationMs,omitempty" gorm:"index"`
// IdempotencyKey deduplicates repeated submissions of the same completed audit entry.
IdempotencyKey string `json:"idempotencyKey" gorm:"uniqueIndex"`
// ToolUseID is the tool-use identifier from the agent runtime, when available.
ToolUseID string `json:"toolUseID,omitempty" gorm:"index"`
SessionID string `json:"sessionID,omitempty" gorm:"index"`
// TurnID identifies the conversation turn that produced this tool call.
TurnID string `json:"turnID,omitempty" gorm:"index"`
AgentProvider types2.LocalAgentProvider `json:"agentProvider" gorm:"index"`
AgentVersion string `json:"agentVersion,omitempty" gorm:"index"`
CLIName string `json:"cliName,omitempty"`
CLIVersion string `json:"cliVersion" gorm:"index"`
Model string `json:"model,omitempty" gorm:"index"`
ModelID string `json:"modelID,omitempty" gorm:"index"`
PermissionMode string `json:"permissionMode,omitempty" gorm:"index"`
DeviceID string `json:"deviceID,omitempty" gorm:"index"`
DeviceDeploymentID uint `json:"deviceDeploymentID,omitempty" gorm:"index"`
Hostname string `json:"hostname,omitempty"`
OS string `json:"os,omitempty" gorm:"index"`
Architecture string `json:"architecture,omitempty" gorm:"index"`
LocalUsername string `json:"localUsername,omitempty"`
CWD string `json:"cwd,omitempty"`
GitRoot string `json:"gitRoot,omitempty"`
GitRemotes datatypes.JSONSlice[string] `json:"gitRemotes,omitempty"`
GitBranch string `json:"gitBranch,omitempty"`
GitCommit string `json:"gitCommit,omitempty" gorm:"index"`
ReportedUserEmail string `json:"reportedUserEmail,omitempty"`
// TranscriptPath is the local path to the agent transcript, if the client reported one.
TranscriptPath string `json:"transcriptPath,omitempty"`
RequestBody json.RawMessage `json:"requestBody,omitempty" gorm:"column:local_agent_request_body"`
ResponseBody json.RawMessage `json:"responseBody,omitempty" gorm:"column:local_agent_response_body"`
// RawEvent preserves the original hook payload for debugging and future parsers.
RawEvent json.RawMessage `json:"rawEvent,omitempty" gorm:"column:local_agent_raw_event"`
}
type LocalAuthSession ¶ added in v0.24.0
type LocalAuthSession struct {
ID string `json:"-" gorm:"primaryKey"`
CreatedAt time.Time `json:"createdAt"`
ExpiresAt time.Time `json:"expiresAt" gorm:"index"`
UserID uint `json:"userID" gorm:"index"`
}
LocalAuthSession is a login session created by the local auth provider. ID is the SHA-256 hash of the session token that is handed to the browser, so a database leak does not hand out usable sessions.
type LocalAuthUser ¶ added in v0.24.0
type LocalAuthUser struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Email string `json:"email"`
HashedEmail string `json:"-" gorm:"uniqueIndex"`
PasswordHash string `json:"-"`
Encrypted bool `json:"-"`
}
LocalAuthUser is a username/password user managed by the local auth provider. The email address is the login name and is also what identifies the user to the rest of Obot, so it is immutable: to change it, delete the user and create a new one.
type MCPAuditLog ¶ added in v0.8.0
type MCPAuditLog struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"createdAt" gorm:"index"`
SourceType types2.AuditLogSourceType `json:"sourceType" gorm:"index;default:mcp"`
UserID string `json:"userID" gorm:"index"`
ClientIP string `json:"clientIP" gorm:"index"`
MCPFields *MCPAuditLogFields `json:"mcpFields,omitempty" gorm:"embedded"`
LocalAgentToolCallFields *LocalAgentToolCallAuditLogFields `json:"localAgentToolCallFields,omitempty" gorm:"embedded"`
Encrypted bool `json:"encrypted"`
}
MCPAuditLog represents an audit log entry for MCP API calls
func NewLocalAgentToolCallAuditLogFromInput ¶ added in v0.24.0
func NewLocalAgentToolCallAuditLogFromInput(input types2.LocalAgentToolCallAuditLogInput, actorType types2.AuditLogActorType, actorID, clientIP string, deviceDeploymentID uint, createdAt time.Time) MCPAuditLog
func (*MCPAuditLog) MCP ¶ added in v0.24.0
func (a *MCPAuditLog) MCP() *MCPAuditLogFields
func (*MCPAuditLog) NormalizeMCPFields ¶ added in v0.24.0
func (a *MCPAuditLog) NormalizeMCPFields()
func (*MCPAuditLog) ValidateSourceFields ¶ added in v0.24.0
func (a *MCPAuditLog) ValidateSourceFields() error
type MCPAuditLogFields ¶ added in v0.24.0
type MCPAuditLogFields struct {
APIKey string `json:"apiKey,omitempty"`
MCPID string `json:"mcpID" gorm:"index"`
PowerUserWorkspaceID string `json:"powerUserWorkspaceID,omitempty" gorm:"index"`
MCPServerDisplayName string `json:"mcpServerDisplayName" gorm:"index"`
MCPServerCatalogEntryName string `json:"mcpServerCatalogEntryName" gorm:"index"`
ClientName string `json:"clientName" gorm:"index"`
ClientVersion string `json:"clientVersion" gorm:"index"`
CallType string `json:"callType" gorm:"index"`
CallIdentifier string `json:"callIdentifier,omitempty" gorm:"index"`
RequestMutated bool `json:"requestMutated"`
RequestBody json.RawMessage `json:"requestBody,omitempty"`
MutatedRequestBody json.RawMessage `json:"mutatedRequestBody,omitempty"`
ResponseMutated bool `json:"responseMutated"`
ResponseBody json.RawMessage `json:"responseBody,omitempty"`
OriginalResponseBody json.RawMessage `json:"originalResponseBody,omitempty"`
ResponseStatus int `json:"responseStatus" gorm:"index"`
Error string `json:"error,omitempty"`
ProcessingTimeMs int64 `json:"processingTimeMs" gorm:"index"`
SessionID string `json:"sessionID,omitempty" gorm:"index"`
WebhookStatuses datatypes.JSONSlice[MCPWebhookStatus] `json:"webhookStatuses,omitempty"`
ResponseReceived bool `json:"responseReceived"`
// Additional metadata
RequestID string `json:"requestID,omitempty" gorm:"index"`
UserAgent string `json:"userAgent,omitempty"`
RequestHeaders json.RawMessage `json:"requestHeaders,omitempty"`
ResponseHeaders json.RawMessage `json:"responseHeaders,omitempty"`
}
type MCPOAuthPendingState ¶ added in v0.17.0
type MCPOAuthPendingState struct {
HashedState string `gorm:"primaryKey"`
State string
Verifier string
UserID string `gorm:"index:idx_pending_user_mcp"`
MCPID string `gorm:"index:idx_pending_user_mcp"`
URL string
OAuthAuthRequestID string
ClientID string
ClientSecret string
AuthURL string
TokenURL string
AuthStyle oauth2.AuthStyle
RedirectURL string
Scopes string
Encrypted bool
CreatedAt time.Time
}
type MCPOAuthToken ¶ added in v0.8.0
type MCPOAuthToken struct {
oauth2.Endpoint
ClientID string
ClientSecret string
RedirectURL string
Scopes string
MCPID string `gorm:"primaryKey"`
UserID string `gorm:"primaryKey"`
URL string
OAuthAuthRequestID string `gorm:"index"`
AccessToken string
TokenType string
RefreshToken string
Expiry time.Time
ExpiresIn int64
Encrypted bool
}
type MCPPromptReadStats ¶ added in v0.8.0
type MCPPromptReadStats struct {
PromptName string `json:"promptName"`
ReadCount int64 `json:"readCount"`
}
MCPPromptReadStats represents statistics for individual prompt reads
type MCPResourceReadStats ¶ added in v0.8.0
type MCPResourceReadStats struct {
ResourceURI string `json:"resourceUri"`
ReadCount int64 `json:"readCount"`
}
MCPResourceReadStats represents statistics for individual resource reads
type MCPServerDetail ¶ added in v0.22.0
type MCPServerDetail struct {
MCPServerStat
EnvKeys []string
HeaderKeys []string
}
MCPServerDetail is the per-hash detail payload: an aggregated row plus the union of EnvKeys / HeaderKeys observed across every occurrence (those are deliberately excluded from the hash).
type MCPServerOccurrence ¶ added in v0.22.0
type MCPServerOccurrence struct {
DeviceScanID uint `gorm:"column:device_scan_id"`
DeviceID string `gorm:"column:device_id"`
Client string `gorm:"column:client"`
Scope string `gorm:"column:scope"`
ScannedAt time.Time `gorm:"column:scanned_at"`
ID uint `gorm:"column:id"`
}
MCPServerOccurrence is one device's latest-scan instance of a given ConfigHash.
type MCPServerStat ¶ added in v0.22.0
type MCPServerStat struct {
ConfigHash string `gorm:"column:config_hash"`
Name string `gorm:"column:name"`
Transport string `gorm:"column:transport"`
Command string `gorm:"column:command"`
Args datatypes.JSONSlice[string] `gorm:"-"`
URL string `gorm:"column:url"`
DeviceCount int64 `gorm:"column:device_count"`
UserCount int64 `gorm:"column:user_count"`
ClientCount int64 `gorm:"column:client_count"`
ObservationCount int64 `gorm:"column:observation_count"`
}
MCPServerStat is one row of the device-fleet MCP aggregation: every DeviceScanMCPServer with the same ConfigHash, observed in any device's latest scan within the requested time window, collapses into a single entity. Identity fields (Name, Transport, Command, URL, Args) are constant within a ConfigHash group by construction. Args is loaded post-hoc because JSONB has no MAX() in Postgres.
type MCPToolCallStats ¶ added in v0.8.0
type MCPToolCallStats struct {
ToolName string `json:"-"`
CallCount int64 `json:"callCount"`
Items []MCPToolCallStatsItem `json:"items"`
}
MCPToolCallStats represents statistics for individual tool calls
type MCPToolCallStatsItem ¶ added in v0.8.0
type MCPUsageStatItem ¶ added in v0.8.0
type MCPUsageStatItem struct {
MCPID string `json:"mcpID"`
MCPServerDisplayName string `json:"mcpServerDisplayName"`
MCPServerCatalogEntryName string `json:"mcpServerCatalogEntryName"`
ToolCalls []MCPToolCallStats `json:"toolCalls,omitempty"`
ResourceReads []MCPResourceReadStats `json:"resourceReads,omitempty"`
PromptReads []MCPPromptReadStats `json:"promptReads,omitempty"`
}
MCPUsageStatItem represents usage statistics for MCP servers
type MCPUsageStatsList ¶ added in v0.8.0
type MCPWebhookStatus ¶ added in v0.8.0
type MDMAssetBundle ¶ added in v0.24.0
type MDMAssetBundle struct {
Digest string `json:"digest" gorm:"primaryKey;size:64"`
Content []byte `json:"-" gorm:"not null"`
}
MDMAssetBundle is one immutable validated source snapshot, addressed by the lowercase SHA-256 of Content. Rendered configuration artifacts are stored in their own table rather than sharing a generic blob abstraction.
type MDMConfiguration ¶ added in v0.24.0
type MDMConfiguration struct {
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
// There may be no default before device management is configured, but there
// can never be more than one. The backend assigns the first configuration as
// the default; clients cannot change this field.
IsDefault bool `json:"-" gorm:"not null;default:false;uniqueIndex:idx_mdm_configurations_default,where:is_default = true"`
CreatedBy uint `json:"createdBy"`
CreatedAt time.Time `json:"createdAt"`
// Name is a vestigial column retained so the pre-existing NOT NULL "name"
// column keeps accepting inserts on databases created before the
// configuration rework. It is not part of the public API and is stored
// empty. The nullable "description" column from that same schema is left in
// place; it is harmless and never read.
Name string `json:"-" gorm:"not null"`
// AssetDigest identifies the bundle against which Values were validated.
// ObotSentryVersion is copied from that bundle's manifest when artifacts are
// rendered, so the generated version is known without reopening the bundle.
// Artifacts are loaded separately from their explicit table. ZIP bytes never
// pass through the public configuration API.
AssetDigest string `json:"-" gorm:"size:64;index"`
ObotSentryVersion string `json:"-" gorm:"size:64"`
Values string `json:"-" gorm:"type:text"`
Artifacts []MDMConfigurationArtifact `json:"-" gorm:"-"`
EnforcementEnabled bool `json:"enforcementEnabled,omitempty"`
EnforcementAllowlist types2.EnforcementAllowlist `json:"-" gorm:"serializer:json"`
}
MDMConfiguration is a fleet grouping that devices enroll into. Enrollment is authorized by one or more DeviceEnrollmentKeys attached to it; a device belongs to the configuration itself, not to any particular key.
type MDMConfigurationArtifact ¶ added in v0.24.0
type MDMConfigurationArtifact struct {
ID uint `json:"id" gorm:"primaryKey;autoIncrement"`
MDMConfigurationID uint `json:"mdmConfigurationID" gorm:"not null;index;uniqueIndex:idx_mdm_configuration_artifact_slug,priority:1"`
Slug string `json:"slug" gorm:"not null;uniqueIndex:idx_mdm_configuration_artifact_slug,priority:2"`
Platform string `json:"platform"`
OS string `json:"os"`
Instructions string `json:"instructions"`
Digest string `json:"digest" gorm:"size:64;not null"`
Content []byte `json:"-" gorm:"not null"`
}
MDMConfigurationArtifact stores one rendered download. The configuration relationship is maintained explicitly by the gateway client without a database foreign-key constraint.
type MDMConfigurationEnforcement ¶ added in v0.25.0
type MDMConfigurationEnforcement struct {
Enabled bool
Allowlist types2.EnforcementAllowlist
}
type MessagePolicyViolation ¶ added in v0.19.0
type MessagePolicyViolation struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"createdAt" gorm:"index"`
UserID string `json:"userID" gorm:"index"`
PolicyID string `json:"policyID" gorm:"index"`
PolicyName string `json:"policyName" gorm:"index"`
PolicyDefinition string `json:"policyDefinition"`
Direction string `json:"direction" gorm:"index"`
ViolationExplanation string `json:"violationExplanation"`
BlockedContent json.RawMessage `json:"blockedContent,omitempty"`
ProjectID string `json:"projectID" gorm:"index"`
ThreadID string `json:"threadID" gorm:"index"`
Encrypted bool `json:"encrypted"`
}
MessagePolicyViolation represents a record of a message policy violation.
type RemainingTokenUsage ¶ added in v0.8.0
type RemainingTokenUsage struct {
InputTokens int
OutputTokens int
UnlimitedInputTokens bool
UnlimitedOutputTokens bool
}
func (RemainingTokenUsage) IsDepleted ¶ added in v0.24.0
func (r RemainingTokenUsage) IsDepleted() bool
type RunTokenActivity ¶ added in v0.8.0
type ServiceAccountAPIKey ¶ added in v0.21.0
type ServiceAccountAPIKey struct {
ID uint `gorm:"primaryKey;autoIncrement"`
ServiceAccountName string `gorm:"index;not null"`
HashedSecret string `json:"-"`
Token string `gorm:"-" json:"-"`
CreatedAt time.Time `json:"createdAt"`
ValidAfter time.Time `json:"validAfter"`
RetireAfter *time.Time `json:"retireAfter,omitempty"`
}
func (*ServiceAccountAPIKey) PlaintextToken ¶ added in v0.21.0
func (k *ServiceAccountAPIKey) PlaintextToken() string
type SkillDetail ¶ added in v0.22.0
type SkillDetail struct {
SkillStat
Description string
HasScripts bool
GitRemoteURL string
Files []string
}
SkillDetail is the per-skill detail payload: an aggregated row plus representative metadata pulled from a single canonical row in the latest-scan-per-device subset. Description / HasScripts / GitRemoteURL / Files come from one observation and are not guaranteed to be stable across observations sharing the same name.
type SkillOccurrence ¶ added in v0.22.0
type SkillOccurrence struct {
DeviceScanID uint `gorm:"column:device_scan_id"`
DeviceID string `gorm:"column:device_id"`
Client string `gorm:"column:client"`
Scope string `gorm:"column:scope"`
ProjectPath string `gorm:"column:project_path"`
ScannedAt time.Time `gorm:"column:scanned_at"`
ID uint `gorm:"column:id"`
}
SkillOccurrence is one device's latest-scan instance of a given skill name.
type SkillStat ¶ added in v0.22.0
type SkillStat struct {
Name string `gorm:"column:name"`
DeviceCount int64 `gorm:"column:device_count"`
UserCount int64 `gorm:"column:user_count"`
ObservationCount int64 `gorm:"column:observation_count"`
}
SkillStat is one row of the per-skill rollup.
type TempSetupUser ¶ added in v0.13.0
type TempSetupUser struct {
ID uint `json:"id" gorm:"primaryKey"`
UserID uint `json:"userID" gorm:"index"`
Username string `json:"username"`
Email string `json:"email"`
Role types2.Role `json:"role"`
IconURL string `json:"iconURL"`
AuthProviderName string `json:"authProviderName"`
AuthProviderNamespace string `json:"authProviderNamespace"`
CreatedAt time.Time `json:"createdAt"`
}
type TokenRequest ¶
type TokenRequest struct {
ID string `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
State string `gorm:"index"`
Nonce string
Name string
Description string
Scopes APIKeyScopes `gorm:"embedded"`
Token string
NoExpiration bool
ExpiresAt time.Time
CompletionRedirectURL string
Error string
TokenRetrieved bool
}
type TokenUsage ¶ added in v0.24.0
type TokenUsage struct {
// InputTokens is the total input: CacheReadTokens + CacheWriteTokens + uncached input.
InputTokens int
// CacheReadTokens is the cache-hit input tokens; a subset of InputTokens.
CacheReadTokens int
// CacheWriteTokens is the cache-write input tokens (5m + 1h); a subset of InputTokens
// (Anthropic only).
CacheWriteTokens int
// OutputTokens is the total output, including ThinkingTokens.
OutputTokens int
// ThinkingTokens is the thinking/reasoning output tokens; a subset of OutputTokens.
ThinkingTokens int
// TotalTokens is InputTokens + OutputTokens.
TotalTokens int
// InputSpend is the total USD on InputTokens (each bucket at its own rate):
// CacheReadSpend + CacheWriteSpend + uncached-input spend. 0 when unpriced.
InputSpend float64
// CacheReadSpend is the USD on CacheReadTokens; a subset of InputSpend.
CacheReadSpend float64
// CacheWriteSpend is the USD on CacheWriteTokens; a subset of InputSpend.
CacheWriteSpend float64
// OutputSpend is the USD on OutputTokens.
OutputSpend float64
// TotalSpend is InputSpend + OutputSpend.
TotalSpend float64
}
TokenUsage is normalized token usage and spend.
type User ¶
type User struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"createdAt"`
DisplayName string `json:"displayName"`
Username string `json:"username"`
HashedUsername string `json:"-" gorm:"unique"`
Email string `json:"email"`
HashedEmail string `json:"-"`
VerifiedEmail *bool `json:"verifiedEmail,omitempty"`
Role types2.Role `json:"role"`
IconURL string `json:"iconURL"`
Timezone string `json:"timezone"`
// LastActiveDay is the time of the last request made by this user, currently at the 24 hour granularity.
LastActiveDay time.Time `json:"lastActiveDay"`
Internal bool `json:"internal" gorm:"default:false"`
DailyInputTokensLimit int `json:"dailyInputTokensLimit"`
DailyOutputTokensLimit int `json:"dailyOutputTokensLimit"`
Encrypted bool `json:"encrypted"`
// Soft delete fields
DeletedAt *time.Time `json:"deletedAt,omitempty"`
OriginalEmail string `json:"-"`
OriginalUsername string `json:"-"`
}