types

package
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: Jul 23, 2026 License: AGPL-3.0 Imports: 8 Imported by: 0

Documentation

Overview

Package types contains API DTOs (data transfer objects) used by the API service to receive requests and return responses to clients.

These types are intentionally NOT Kubernetes CRD types. CRD types live in pkg/apis/llmsafespaces/v1; this package converts to/from them at the service boundary. Types here use plain Go types (e.g. *time.Time, not *metav1.Time) so the JSON contract returned to clients is free of Kubernetes-isms (kind, apiVersion, metadata).

Types are organized by domain (one file per area):

  • errors.go — cross-cutting sentinel errors
  • context.go — context-key types and the WorkspaceMetaFromCtx accessor
  • auth.go — user, registration/login, API keys, auth config
  • workspace.go — workspace API DTOs (create/list/status/metadata)
  • container.go — pod/resource/security/network config types
  • session.go — sessions, WebSocket connections, agent health
  • pagination.go — pagination metadata and list options
  • event.go — Kubernetes events, resource status, file info
  • orgs.go — organizations, members, invitations
  • orgs_policy.go — org policies and audit log entries
  • billing.go — usage events, reports, quota

Index

Constants

View Source
const ContextKeyUserID contextKey = "userID"

ContextKeyUserID is the context key used to store the authenticated user ID. Both the auth middleware and service layer use this constant so the key is always in sync.

View Source
const ContextKeyUserRole contextKey = "userRole"

ContextKeyUserRole is the context key used to store the authenticated user's role.

View Source
const ContextKeyWorkspaceMeta contextKey = "workspaceMeta"

ContextKeyWorkspaceMeta is the context key under which WorkspaceAccessMiddleware stores the resolved *WorkspaceMetadata for the current /:id workspace route. Service-layer methods (workspace.Service. verifyOwner, SecretService methods that previously re-checked ownership) read the metadata from here so they can short-circuit the redundant ResolveWorkspace + CheckOwnership round-trip the middleware has already performed. Lives in pkg/types — not api/internal/middleware — so the service layer can read it without importing the HTTP middleware package (which would invert the dependency direction).

View Source
const RoleConfigVersion = 1

RoleConfigVersion is the current config schema version.

Variables

View Source
var (
	ErrNotFound         = errors.New("resource not found")
	ErrPermissionDenied = errors.New("permission denied")
	ErrInvalidInput     = errors.New("invalid input")
	ErrAlreadyExists    = errors.New("resource already exists")
)

Common sentinel errors used across service-layer methods. Callers use errors.Is to branch on these without coupling to a specific service.

Functions

func MarshalRoleConfig

func MarshalRoleConfig(cfg *RoleConfig) ([]byte, error)

MarshalRoleConfig encodes a RoleConfig back to JSONB, including Raw keys.

func MaxPromptPerLevel

func MaxPromptPerLevel() int

MaxPromptPerLevel is the character limit for each prompt tier.

Types

type APIKey

type APIKey struct {
	ID        string     `json:"id"`
	UserID    string     `json:"-" db:"user_id"`
	Name      string     `json:"name"`
	Key       string     `json:"key,omitempty"`
	Prefix    string     `json:"prefix"`
	Active    bool       `json:"active"`
	CreatedAt time.Time  `json:"createdAt"`
	ExpiresAt *time.Time `json:"expiresAt,omitempty"`
	Legacy    bool       `json:"legacy,omitempty" db:"key_legacy"`

	DecryptAccess bool     `json:"decryptAccess"`
	DekSynced     bool     `json:"dekSynced"`
	AllowedCIDRs  []string `json:"allowedCidrs,omitempty"`
	KekSalt       []byte   `json:"-" db:"kek_salt"`
	WrappedDEK    []byte   `json:"-" db:"wrapped_dek"`
	KeyCiphertext []byte   `json:"-" db:"key_ciphertext"`
	KeyVersion    int      `json:"-" db:"key_version"`
}

APIKey represents an API key record returned in list responses.

type ActivateWorkspaceResponse

type ActivateWorkspaceResponse struct {
	Resumed   string `json:"resumed"`
	Suspended string `json:"suspended,omitempty"`
}

ActivateWorkspaceResponse is returned by POST /workspaces/:id/activate.

type ActiveSessionsResponse

type ActiveSessionsResponse struct {
	Active    []string `json:"active"`
	MaxActive int      `json:"maxActive"`
}

ActiveSessionsResponse is returned by GET /workspaces/:id/sessions/active.

type AddOrgMemberRequest

type AddOrgMemberRequest struct {
	UserID string  `json:"userId" binding:"required"`
	Role   OrgRole `json:"role"   binding:"required"`
}

AddOrgMemberRequest is the request body for adding an org member.

type AgentHealthResult

type AgentHealthResult struct {
	Status              string   `json:"status"`
	ProvidersConfigured int      `json:"providersConfigured"`
	AgentVersion        string   `json:"agentVersion,omitempty"`
	Connected           []string `json:"connected,omitempty"`
	Message             string   `json:"message,omitempty"`
	LastCheckedAt       string   `json:"lastCheckedAt,omitempty"`
}

type AgentRole

type AgentRole struct {
	ID          string     `json:"id"`
	Scope       string     `json:"scope"`
	OrgID       *string    `json:"orgId,omitempty"`
	Name        string     `json:"name"`
	Slug        string     `json:"slug"`
	Description string     `json:"description"`
	Extends     *string    `json:"extends,omitempty"`
	IsDefault   bool       `json:"isDefault"`
	Config      RoleConfig `json:"config"`
	CreatedAt   time.Time  `json:"createdAt"`
	UpdatedAt   time.Time  `json:"updatedAt"`
}

AgentRole is the database row representation.

type AuditEntry

type AuditEntry struct {
	ID        int64          `json:"id"`
	ActorID   string         `json:"actorId"`
	Domain    string         `json:"domain"`
	Action    string         `json:"action"`
	TargetID  string         `json:"targetId,omitempty"`
	OrgID     string         `json:"orgId,omitempty"`
	Metadata  map[string]any `json:"metadata,omitempty"`
	CreatedAt time.Time      `json:"createdAt"`
}

AuditEntry is one row of the audit_log, scoped to an org when OrgID is non-empty.

type AuditFilters

type AuditFilters struct {
	OrgID   *string
	ActorID *string
	Domain  *string
	Limit   int
	Offset  int
}

AuditFilters holds optional filters for cross-org audit queries.

type AuthConfig

type AuthConfig struct {
	RegistrationEnabled bool     `json:"registrationEnabled"`
	OIDCEnabled         bool     `json:"oidcEnabled"`
	SSOProviders        []string `json:"ssoProviders,omitempty"`
	InstanceName        string   `json:"instanceName"`
	MOTD                string   `json:"motd,omitempty"`
}

AuthConfig is returned by GET /auth/config for feature-flag discovery.

type AuthResponse

type AuthResponse struct {
	Token       string        `json:"token"`
	User        User          `json:"user"`
	RecoveryKey string        `json:"recoveryKey,omitempty"`
	TokenTTL    time.Duration `json:"-"` // router-internal: not serialized
}

AuthResponse is returned after successful registration or login.

RecoveryKey is populated only on registration (one-time display). It is the user's sole opportunity to retrieve it; the API does not store it anywhere recoverable. Login responses omit this field entirely.

TokenTTL is the effective JWT lifetime used for this session. It is tagged json:"-" so it never appears in the HTTP response body — clients already receive the exp claim inside the JWT. This field carries the TTL from the auth service to the router handler for cookie Max-Age calculation without requiring an interface change.

type BillingOwner

type BillingOwner struct {
	ID   string    `json:"id"`
	Type OwnerType `json:"type"`
}

type CachedSession

type CachedSession struct {
	SessionID   string `json:"sessionId"`
	UserID      string `json:"userId"`
	WorkspaceID string `json:"workspaceId"`
}

CachedSession is the typed representation of a WebSocket session stored in the cache. It replaces the previous map[string]interface{} bag.

type ChangeOrgMemberRoleRequest

type ChangeOrgMemberRoleRequest struct {
	Role OrgRole `json:"role" binding:"required"`
}

ChangeOrgMemberRoleRequest is the request body for changing a member's role.

type ContainerStateValue

type ContainerStateValue string

ContainerStateValue represents the state of a container

const (
	ContainerStateRunning    ContainerStateValue = "Running"
	ContainerStateTerminated ContainerStateValue = "Terminated"
	ContainerStateWaiting    ContainerStateValue = "Waiting"
	ContainerStateUnknown    ContainerStateValue = "Unknown"
)

type ContainerStatus

type ContainerStatus struct {
	// Container name
	Name string `json:"name"`

	// Whether the container is ready
	Ready bool `json:"ready"`

	// Number of times the container has been restarted
	RestartCount int32 `json:"restartCount"`

	// Container state
	State ContainerStateValue `json:"state"`

	// Time when the container started
	StartedAt *time.Time `json:"startedAt,omitempty"`

	// Time when the container finished
	FinishedAt *time.Time `json:"finishedAt,omitempty"`

	// Exit code if terminated
	ExitCode int32 `json:"exitCode,omitempty"`

	// Reason for current state
	Reason string `json:"reason,omitempty"`

	// Message regarding current state
	Message string `json:"message,omitempty"`
}

ContainerStatus represents the status of a container

type CreateAPIKeyRequest

type CreateAPIKeyRequest struct {
	Name          string   `json:"name" binding:"required,min=1,max=128"`
	DecryptAccess bool     `json:"decryptAccess"`
	AllowedCIDRs  []string `json:"allowedCidrs,omitempty"`
}

CreateAPIKeyRequest is the request body for creating an API key.

type CreateInvitationsRequest

type CreateInvitationsRequest struct {
	Emails []string `json:"emails" binding:"required,min=1,max=100,dive,email"`
	Role   OrgRole  `json:"role"   binding:"required"`
}

CreateInvitationsRequest is the body for POST /orgs/:id/invitations.

type CreateOrgRequest

type CreateOrgRequest struct {
	Name       string  `json:"name"       binding:"required,min=2,max=100"`
	Slug       string  `json:"slug"       binding:"required,min=2,max=50,slug"`
	OwnerEmail string  `json:"ownerEmail" binding:"required,email"`
	PlanID     OrgPlan `json:"planId"     binding:"omitempty"`
}

CreateOrgRequest is the request body for creating an organization. The slug is lowercased by the service before insert and uniqueness check.

Per design 0031 D1, org creation is platform-admin only. The admin supplies the intended owner's email; the backend resolves it to a user ID. This is a single lookup, not a search/list endpoint (account-enumeration prevention).

Slug format: lowercase letters, digits, and single hyphens between segments (e.g. "my-org", "team-1"). The `slug` validator is registered in pkg/types/validators.go. Hyphens are required because the frontend's slugify() produces them from multi-word names; rejecting hyphens would produce an unreachable 400 for any user-friendly name.

type CreateOrgResponse

type CreateOrgResponse struct {
	OrgResponse
}

CreateOrgResponse is returned by POST /api/v1/orgs. Org creation is platform-admin only (design 0031 D1).

type CreateWorkspaceRequest

type CreateWorkspaceRequest struct {
	Name         string            `json:"name"`
	Runtime      string            `json:"runtime"`
	StorageSize  string            `json:"storageSize"`
	StorageClass string            `json:"storageClass,omitempty"`
	Labels       map[string]string `json:"labels,omitempty"`
	OrgID        *string           `json:"orgId,omitempty"`
}

CreateWorkspaceRequest is the request body for creating a workspace.

type CredentialStateResult

type CredentialStateResult struct {
	Available bool   `json:"available"`
	Reason    string `json:"reason,omitempty"`
	Message   string `json:"message,omitempty"`
}

type EffectiveAgentRole

type EffectiveAgentRole struct {
	AgentRole
	EffectiveConfig  RoleConfig `json:"effectiveConfig"`
	InheritanceChain []string   `json:"inheritanceChain"`
}

EffectiveAgentRole is the fully resolved role after walking the inheritance chain and merging all configs from root to leaf.

type EffectivePrompt

type EffectivePrompt struct {
	PlatformPrompt string `json:"platformPrompt,omitempty"`
	OrgPrompt      string `json:"orgPrompt,omitempty"`
	RolePrompt     string `json:"rolePrompt,omitempty"`
	UserPrompt     string `json:"userPrompt,omitempty"`

	// Resolved is the merged text written to the admin prompt file.
	Resolved string `json:"resolved"`

	// AllowUserPrompt reports whether user customization is enabled for
	// this workspace's org. Delivered so the frontend can show lock state.
	AllowUserPrompt bool `json:"allowUserPrompt"`
}

EffectivePrompt is the fully resolved system prompt delivered to the pod via the bootstrap endpoint and materialized into agentd.AdminPromptPath (/sandbox-runtime/admin-prompt.md).

type EgressRule

type EgressRule struct {
	// Domain name for egress filtering
	Domain string `json:"domain"`

	// Ports allowed for this domain
	Ports []PortRule `json:"ports,omitempty"`
}

EgressRule defines an egress rule

type EmailToken

type EmailToken struct {
	ID         string     `json:"id" db:"id"`
	UserID     string     `json:"userId" db:"user_id"`
	Kind       string     `json:"kind" db:"kind"` // "password_reset" | "email_verify"
	TokenHash  string     `json:"-" db:"token_hash"`
	ExpiresAt  time.Time  `json:"expiresAt" db:"expires_at"`
	ConsumedAt *time.Time `json:"consumedAt,omitempty" db:"consumed_at"`
}

EmailToken is a single-use token for password reset or email verification. Only the sha256 hash is stored; the raw token is presented to the user via email and consumed on first POST (never via GET — scanner defense, US-49.9).

type EnsureSessionResponse

type EnsureSessionResponse struct {
	WorkspaceID    string `json:"workspaceId"`
	WorkspacePhase string `json:"workspacePhase"`
	SessionID      string `json:"sessionId"`
	Resumed        bool   `json:"resumed"`
}

EnsureSessionResponse is returned by POST /workspaces/:id/sessions/new. It guarantees the workspace is active with a running pod, returning the workspace ID and session ID for immediate use.

type Event

type Event struct {
	// Event type (Normal, Warning)
	Type string `json:"type"`

	// Event reason
	Reason string `json:"reason"`

	// Event message
	Message string `json:"message"`

	// Event count
	Count int32 `json:"count"`

	// Event time
	Time *time.Time `json:"time,omitempty"`

	// Event source (Pod, Sandbox, etc.)
	Source string `json:"source,omitempty"`
}

Event represents a Kubernetes event

type ExecutionResult

type ExecutionResult struct {
	// Stdout output
	Stdout string `json:"stdout"`

	// Stderr output
	Stderr string `json:"stderr"`

	// Exit code
	ExitCode int `json:"exitCode"`

	// Execution time in milliseconds
	ExecutionTime int64 `json:"executionTime"`

	// Error message if any
	Error string `json:"error,omitempty"`
}

ExecutionResult represents the result of an execution

type FileInfo

type FileInfo struct {
	// File name
	Name string `json:"name"`

	// File path
	Path string `json:"path"`

	// File size in bytes
	Size int64 `json:"size"`

	// File mode
	Mode string `json:"mode"`

	// Last modified time
	ModTime time.Time `json:"modTime"`

	// Whether it's a directory
	IsDir bool `json:"isDir"`
}

FileInfo represents information about a file

type FilesystemConfig

type FilesystemConfig struct {
	// Mount root filesystem as read-only
	ReadOnlyRoot bool `json:"readOnlyRoot,omitempty"`

	// Paths that should be writable
	WritablePaths []string `json:"writablePaths,omitempty"`
}

FilesystemConfig defines filesystem configuration

type InvitationDetail

type InvitationDetail struct {
	OrgName     string    `json:"orgName"`
	OrgSlug     string    `json:"orgSlug"`
	InviterName string    `json:"inviterName"`
	Role        OrgRole   `json:"role"`
	ExpiresAt   time.Time `json:"expiresAt"`
}

InvitationDetail is the public response for GET /invitations/:token. It does not expose the token hash or internal IDs beyond what the recipient needs to decide whether to accept.

type LastAdminOrg

type LastAdminOrg struct {
	OrgID   string `json:"orgId"`
	OrgName string `json:"orgName"`
}

LastAdminOrg identifies an org where a user is the sole active admin.

type ListOptions

type ListOptions struct {
	Limit  int `json:"limit"`
	Offset int `json:"offset"`
}

ListOptions carries pagination and filtering parameters.

type LoginRequest

type LoginRequest struct {
	Email      string `json:"email"      binding:"required,email"`
	Password   string `json:"password"   binding:"required"`
	RememberMe bool   `json:"rememberMe"`
}

LoginRequest is the request body for user login.

type Message

type Message struct {
	Type    string `json:"type"`
	Content string `json:"content"`
}

type NetworkAccess

type NetworkAccess struct {
	// Egress rules
	Egress []EgressRule `json:"egress,omitempty"`

	// Allow ingress traffic to sandbox
	Ingress bool `json:"ingress,omitempty"`
}

NetworkAccess defines network access configuration

type NetworkInfo

type NetworkInfo struct {
	// Pod IP address
	PodIP string `json:"podIP,omitempty"`

	// Host IP address
	HostIP string `json:"hostIP,omitempty"`

	// Whether ingress is allowed
	Ingress bool `json:"ingress"`

	// Allowed egress domains
	EgressDomains []string `json:"egressDomains,omitempty"`
}

NetworkInfo represents network information for a sandbox

type OrgInvitation

type OrgInvitation struct {
	ID         string     `json:"id"`
	OrgID      string     `json:"orgId"`
	Email      string     `json:"email"`
	Role       OrgRole    `json:"role"`
	InvitedBy  string     `json:"invitedBy"`
	TokenHash  string     `json:"-"`
	ExpiresAt  time.Time  `json:"expiresAt"`
	AcceptedAt *time.Time `json:"acceptedAt,omitempty"`
	DeclinedAt *time.Time `json:"declinedAt,omitempty"`
	BounceType string     `json:"bounceType,omitempty"`
	BouncedAt  *time.Time `json:"bouncedAt,omitempty"`
	CreatedAt  time.Time  `json:"createdAt"`

	// InviteeUserExists is true when a `users` row exists with this
	// invitation's email (case-folded match). Surfaced so the org admin
	// UI can render the per-row Verify button only when force-verify is
	// actionable. Pointer so a missing-from-payload value is
	// distinguishable from a definite false on older API responses.
	InviteeUserExists *bool `json:"inviteeUserExists,omitempty"`

	// InviteeEmailVerified mirrors users.email_verified for the row
	// matched by InviteeUserExists. Nil when no users row exists. The
	// org admin UI hides the Verify button when this is true (the
	// override has already been applied or the user verified through
	// the normal flow).
	InviteeEmailVerified *bool `json:"inviteeEmailVerified,omitempty"`
}

OrgInvitation is the API DTO for an org invitation row.

type OrgMember

type OrgMember struct {
	OrgID         string    `json:"orgId"`
	UserID        string    `json:"userId"`
	Username      string    `json:"username"`
	Email         string    `json:"email"`
	Role          OrgRole   `json:"role"`
	EmailVerified bool      `json:"emailVerified"`
	CreatedAt     time.Time `json:"createdAt"`
}

OrgMember is the API DTO for an organization membership.

EmailVerified mirrors users.email_verified for the member's user account. It is exposed so org admins can see which members have not yet completed the email-verification flow, and offers a "Verify" action to bypass it (POST /orgs/:id/members/:userID/verify). Verification state lives on the user row (not the membership) — there is exactly one user account per member, and a single user belongs to at most one org under single-org enforcement (D8).

type OrgPlan

type OrgPlan string

OrgPlan is the product plan identifier stored in organizations.plan_id and used locally for feature gating. The plan is set at org creation (enterprise for platform-admin orgs; the selected checkout plan on checkout.session.completed for self-service orgs). Per-event plan syncing from Stripe is planned for US-43.15.

const (
	PlanFree       OrgPlan = "free"
	PlanTeam       OrgPlan = "team"
	PlanBusiness   OrgPlan = "business"
	PlanEnterprise OrgPlan = "enterprise"
)

type OrgPolicy

type OrgPolicy struct {
	OrgID     string          `json:"-"`
	Key       OrgPolicyKey    `json:"key"`
	Value     json.RawMessage `json:"value"`
	UpdatedBy string          `json:"-"`
	UpdatedAt time.Time       `json:"updatedAt"`
}

OrgPolicy is one row of org_policies. The Value is the raw JSONB payload; the interpretation depends on the Key (see OrgPolicyValues).

type OrgPolicyKey

type OrgPolicyKey string

OrgPolicyKey identifies a single org-scoped policy. Per D15, Phase 2 ships exactly these four; the migration CHECK constraint enforces the same set.

const (
	PolicyAllowedModels             OrgPolicyKey = "allowed_models"
	PolicyAllowedProviders          OrgPolicyKey = "allowed_providers"
	PolicyMaxWorkspacesPerMember    OrgPolicyKey = "max_workspaces_per_member"
	PolicyMaxActiveWorkspacesPerMem OrgPolicyKey = "max_active_workspaces_per_member"

	// Agent customization policies
	PolicySysPromptOrg    OrgPolicyKey = "sys_prompt_org"
	PolicyAllowUserPrompt OrgPolicyKey = "allow_user_prompt"
)

type OrgPolicyValues

type OrgPolicyValues struct {
	AllowedModels             *[]string `json:"allowedModels,omitempty"`
	AllowedProviders          *[]string `json:"allowedProviders,omitempty"`
	MaxWorkspacesPerMember    *int      `json:"maxWorkspacesPerMember,omitempty"`
	MaxActiveWorkspacesPerMem *int      `json:"maxActiveWorkspacesPerMember,omitempty"`

	// Agent customization
	SysPromptOrg    *string `json:"sysPromptOrg,omitempty"`
	AllowUserPrompt *bool   `json:"allowUserPrompt,omitempty"`
}

OrgPolicyValues is the typed view of all four Phase 2 policies for one org. Fields are pointers so nil means "not set / unrestricted"; the zero value of the dereferenced type is never confused with "unset".

func (*OrgPolicyValues) IsModelAllowed

func (p *OrgPolicyValues) IsModelAllowed(modelID string) bool

IsModelAllowed reports whether modelID is permitted under the allowed-models policy. Returns true when no policy is set (unrestricted).

func (*OrgPolicyValues) IsProviderAllowed

func (p *OrgPolicyValues) IsProviderAllowed(providerID string) bool

IsProviderAllowed reports whether providerID is permitted.

func (*OrgPolicyValues) IsUserPromptAllowed

func (p *OrgPolicyValues) IsUserPromptAllowed() bool

IsUserPromptAllowed reports whether org members can customize their agent prompts. Defaults to false (locked) when no policy is set.

func (*OrgPolicyValues) MaxActive

func (p *OrgPolicyValues) MaxActive() int

MaxActive returns the per-member concurrent active workspace limit, or -1.

func (*OrgPolicyValues) MaxWorkspaces

func (p *OrgPolicyValues) MaxWorkspaces() int

MaxWorkspaces returns the per-member workspace creation limit, or -1 (unlimited) when unset.

func (*OrgPolicyValues) OrgPrompt

func (p *OrgPolicyValues) OrgPrompt() string

OrgPrompt returns the org-level system prompt overlay, or "" when unset.

type OrgResponse

type OrgResponse struct {
	Organization
	UserRole    OrgRole `json:"userRole,omitempty"`
	MemberCount int     `json:"memberCount"`
}

OrgResponse extends Organization with the calling user's membership context. UserRole is omitempty so that an empty string (caller is not a member — e.g. platform admin creating an org for someone else) is omitted from JSON rather than appearing as `"userRole": ""`.

type OrgRole

type OrgRole string

OrgRole represents a user's role within an organization.

const (
	OrgRoleAdmin  OrgRole = "admin"
	OrgRoleMember OrgRole = "member"
)

type OrgSSOConfig

type OrgSSOConfig struct {
	OrgID             string             `json:"-"`
	DiscoveryURL      string             `json:"discoveryUrl"`
	ClientID          string             `json:"clientId"`
	ClientSecret      []byte             `json:"-"`
	ClaimedDomains    []string           `json:"claimedDomains"`
	VerifiedDomains   []string           `json:"verifiedDomains"`
	VerificationToken string             `json:"verificationToken"`
	AutoProvision     bool               `json:"autoProvision"`
	GroupRoleMapping  map[string]OrgRole `json:"groupRoleMapping"`
	CreatedAt         time.Time          `json:"createdAt"`
	UpdatedAt         time.Time          `json:"updatedAt"`
}

OrgSSOConfig is the per-org OIDC SSO configuration. ClientSecret is the encrypted blob stored in the DB; it is never serialized to JSON. VerifiedDomains is a subset of ClaimedDomains that have passed DNS verification (D17 Q-S2); only verified domains auto-route on the login page. VerificationToken is the per-org random token the org admin places as a TXT record at _llmsafespaces-verify.<domain> to prove ownership.

type OrgSSOConfigResponse

type OrgSSOConfigResponse struct {
	OrgID             string             `json:"orgId"`
	DiscoveryURL      string             `json:"discoveryUrl"`
	ClientID          string             `json:"clientId"`
	HasSecret         bool               `json:"hasSecret"`
	ClaimedDomains    []string           `json:"claimedDomains"`
	VerifiedDomains   []string           `json:"verifiedDomains"`
	VerificationToken string             `json:"verificationToken"`
	AutoProvision     bool               `json:"autoProvision"`
	GroupRoleMapping  map[string]OrgRole `json:"groupRoleMapping"`
	UpdatedAt         time.Time          `json:"updatedAt"`
}

OrgSSOConfigResponse is the API response shape — omits the encrypted secret.

type OrgStatus

type OrgStatus string

OrgStatus is the operational status of an organization. It gates access: only non-suspended orgs are usable via OrgMemberGuard/OrgAdminGuard. Both 'active' and 'pending_activation' allow access (the creator needs to reach the portal and Stripe checkout while pending); 'suspended' is fully locked.

const (
	OrgStatusPendingActivation OrgStatus = "pending_activation"
	OrgStatusActive            OrgStatus = "active"
	OrgStatusSuspended         OrgStatus = "suspended"
)

type OrgSubscriptionStatus

type OrgSubscriptionStatus string

OrgSubscriptionStatus tracks the Stripe subscription lifecycle separately from OrgStatus. An org can be status='active' (members retain access) while subscription_status='past_due' (in the 7-day Smart Retries grace window).

const (
	SubscriptionInactive OrgSubscriptionStatus = "inactive"
	SubscriptionActive   OrgSubscriptionStatus = "active"
	SubscriptionTrialing OrgSubscriptionStatus = "trialing"
	SubscriptionPastDue  OrgSubscriptionStatus = "past_due"
	SubscriptionCanceled OrgSubscriptionStatus = "canceled"
	SubscriptionUnpaid   OrgSubscriptionStatus = "unpaid"
)

type OrgSummary

type OrgSummary struct {
	Organization
	MemberCount    int `json:"memberCount"`
	WorkspaceCount int `json:"workspaceCount"`
}

OrgSummary extends Organization with aggregate counts for the platform admin dashboard. The counts are populated by a single SQL query (no N+1).

type Organization

type Organization struct {
	ID                 string                `json:"id"`
	Name               string                `json:"name"`
	Slug               string                `json:"slug"`
	CreatedBy          string                `json:"createdBy"`
	CreatedAt          time.Time             `json:"createdAt"`
	UpdatedAt          time.Time             `json:"updatedAt"`
	Status             OrgStatus             `json:"status"`
	PlanID             OrgPlan               `json:"planId"`
	SubscriptionStatus OrgSubscriptionStatus `json:"subscriptionStatus"`
}

Organization is the API DTO for an organization.

type OwnerType

type OwnerType string
const (
	OwnerTypeUser OwnerType = "user"
	OwnerTypeOrg  OwnerType = "org"
)

type PaginationMetadata

type PaginationMetadata struct {
	// Total number of items
	Total int `json:"total"`

	// Start index
	Start int `json:"start"`

	// End index
	End int `json:"end"`

	// Limit per page
	Limit int `json:"limit"`

	// Offset
	Offset int `json:"offset"`
}

PaginationMetadata represents pagination metadata

type PermissionRule

type PermissionRule struct {
	Action   string `json:"action"`
	Resource string `json:"resource"`
	Effect   string `json:"effect"`
}

PermissionRule is one tool-permission rule in a role config.

type PlatformSetting

type PlatformSetting struct {
	Key       string          `json:"key"`
	Value     json.RawMessage `json:"value"`
	UpdatedBy string          `json:"-"`
	UpdatedAt time.Time       `json:"updatedAt"`
}

PlatformSetting is one row of platform_settings. Used for platform-wide mutable configuration like the base system prompt. Key is a stable identifier; Value is the raw JSONB payload.

type PlatformSettingKey

type PlatformSettingKey string

PlatformSettingKey identifies a single platform-wide setting.

const (
	SettingSysPromptPlatform PlatformSettingKey = "sys_prompt_platform"
)

type PortRule

type PortRule struct {
	// Port number
	Port int `json:"port"`

	// Protocol (TCP or UDP)
	Protocol string `json:"protocol,omitempty"`
}

PortRule defines a port rule

type ProfileReference

type ProfileReference struct {
	// Name of RuntimeEnvironment to use
	Name string `json:"name"`

	// Namespace of RuntimeEnvironment
	Namespace string `json:"namespace,omitempty"`
}

ProfileReference defines a reference to a RuntimeEnvironment

type QuotaStatus

type QuotaStatus struct {
	EventType  string    `json:"eventType"`
	PeriodType string    `json:"periodType"`
	Limit      int64     `json:"limit"`
	Used       int64     `json:"used"`
	Remaining  int64     `json:"remaining"`
	ResetsAt   time.Time `json:"resetsAt"`
}

type RefreshWorkspaceResult

type RefreshWorkspaceResult struct {
	RestartGeneration int64 `json:"restartGeneration"`
}

RefreshWorkspaceResult is returned by POST /workspaces/:id/refresh-compute. It reports the restartGeneration that will trigger a pod rebuild, which re-resolves the runtime image to its latest version and applies the refreshed resource requests.

type RegisterRequest

type RegisterRequest struct {
	Username string `json:"username" binding:"required,min=3,max=64"`
	Email    string `json:"email" binding:"required,email"`
	Password string `json:"password" binding:"required,min=8,max=128"`
}

RegisterRequest is the request body for user registration.

type ResourceRequirements

type ResourceRequirements struct {
	// CPU resource limit
	CPU string `json:"cpu,omitempty"`

	// Memory resource limit
	Memory string `json:"memory,omitempty"`

	// GPU resource limit
	GPU string `json:"gpu,omitempty"`
}

ResourceRequirements defines resource limits for a sandbox

type ResourceStatus

type ResourceStatus struct {
	// Current CPU usage
	CPUUsage string `json:"cpuUsage,omitempty"`

	// Current memory usage
	MemoryUsage string `json:"memoryUsage,omitempty"`
}

ResourceStatus defines resource usage

type RoleConfig

type RoleConfig struct {
	Version     int              `json:"version"`
	System      *string          `json:"system,omitempty"`
	Description *string          `json:"description,omitempty"`
	Color       *string          `json:"color,omitempty"`
	Model       *string          `json:"model,omitempty"`
	Mode        *string          `json:"mode,omitempty"`
	Hidden      *bool            `json:"hidden,omitempty"`
	Permissions []PermissionRule `json:"permissions,omitempty"`
	Tools       json.RawMessage  `json:"tools,omitempty"`
	MCP         json.RawMessage  `json:"mcp,omitempty"`
	Raw         map[string]any   `json:"-"`
}

RoleConfig is the strongly-typed view of a role's JSONB config. Fields are pointers so nil = inherit from parent (during merge).

func MergeRoleConfigs

func MergeRoleConfigs(parent, child *RoleConfig) *RoleConfig

MergeRoleConfigs merges a parent config with a child config. Child values override parent values for scalar fields; permissions are concatenated (child appended after parent); Raw keys from both are merged (child wins).

func UnmarshalRoleConfig

func UnmarshalRoleConfig(data []byte) (*RoleConfig, error)

UnmarshalRoleConfig decodes a JSONB config blob into a RoleConfig, preserving unknown keys in the Raw map for forward compatibility. (Stress test 3.4: Go's default unmarshaler would silently drop unknown keys.)

type SSODomain

type SSODomain struct {
	Domain  string `json:"domain"`
	OrgSlug string `json:"orgSlug"`
	OrgName string `json:"orgName"`
}

SSODomain is a single entry in the domain discovery response.

type SecurityContext

type SecurityContext struct {
	// User ID to run container processes
	RunAsUser int64 `json:"runAsUser,omitempty"`

	// Group ID to run container processes
	RunAsGroup int64 `json:"runAsGroup,omitempty"`

	// Seccomp profile
	SeccompProfile string `json:"seccompProfile,omitempty"`

	// AppArmor profile
	AppArmorProfile string `json:"appArmorProfile,omitempty"`

	// Allow privilege escalation
	AllowPrivilegeEscalation bool `json:"allowPrivilegeEscalation,omitempty"`
}

SecurityContext defines security context

type Session

type Session struct {
	// Session ID
	ID string

	// User ID
	UserID string

	// Workspace ID
	WorkspaceID string

	// WebSocket connection
	Conn WSConnection

	// Creation time
	CreatedAt time.Time
}

Session represents a WebSocket session

type SessionListItem

type SessionListItem struct {
	ID            string     `json:"id"`
	Title         string     `json:"title,omitempty"`
	ParentID      string     `json:"parentId,omitempty"`
	LastMessageAt *time.Time `json:"lastMessageAt,omitempty"`
	MessageCount  int        `json:"messageCount"`
	Status        string     `json:"status"` // "active" | "idle"
	LastSeenAt    *time.Time `json:"lastSeenAt,omitempty"`
	HasUnread     bool       `json:"hasUnread"`
	ContextUsed   *int64     `json:"contextUsed,omitempty"`
}

SessionListItem is sidebar metadata for a session (NOT message bodies).

ParentID, when non-empty, is the session_id of the user-visible parent session — typically populated for opencode subagent (subtask) sessions spawned via the `task` tool. The sidebar nests children under their parent for navigation. NULL/empty means the session is top-level.

ContextUsed, when non-nil, is the prompt token count from the last session.next.step.ended SSE event persisted by the API proxy. nil means no LLM step has completed yet for this session (distinguishable from 0).

type SessionStatusItem

type SessionStatusItem struct {
	ID          string `json:"id"`
	Title       string `json:"title,omitempty"`
	Status      string `json:"status"`
	ContextUsed int64  `json:"contextUsed"`
}

SessionStatusItem describes a session reported by the workspace agent.

type StorageConfig

type StorageConfig struct {
	// Enable persistent storage
	Persistent bool `json:"persistent,omitempty"`

	// Size of persistent volume
	VolumeSize string `json:"volumeSize,omitempty"`
}

StorageConfig defines storage configuration

type UpdateOrgRequest

type UpdateOrgRequest struct {
	Name string `json:"name" binding:"omitempty,min=2,max=100"`
	Slug string `json:"slug" binding:"omitempty,min=2,max=50,slug"`
}

UpdateOrgRequest is the request body for updating an organization.

type UpsertSSOConfigRequest

type UpsertSSOConfigRequest struct {
	DiscoveryURL     string             `json:"discoveryUrl"     binding:"required,url"`
	ClientID         string             `json:"clientId"         binding:"required,min=1"`
	ClientSecret     string             `json:"clientSecret"     binding:"omitempty"`
	ClaimedDomains   []string           `json:"claimedDomains"`
	AutoProvision    *bool              `json:"autoProvision"`
	GroupRoleMapping map[string]OrgRole `json:"groupRoleMapping"`
}

UpsertSSOConfigRequest is the API request body for creating/updating SSO config.

type UsageEvent

type UsageEvent struct {
	IdempotencyKey string         `json:"idempotencyKey,omitempty"`
	Owner          BillingOwner   `json:"owner"`
	ActorID        string         `json:"actorId"`
	WorkspaceID    string         `json:"workspaceId,omitempty"`
	EventType      string         `json:"eventType"`
	EventSubtype   string         `json:"eventSubtype,omitempty"`
	Quantity       int64          `json:"quantity"`
	ResourceTier   string         `json:"resourceTier,omitempty"`
	Region         string         `json:"region,omitempty"`
	Metadata       map[string]any `json:"metadata,omitempty"`
	RequestContext map[string]any `json:"requestContext,omitempty"`
	Source         string         `json:"source"`
	EventTime      time.Time      `json:"eventTime"`
}

type UsageReport

type UsageReport struct {
	OwnerID     string                      `json:"ownerId"`
	OwnerType   OwnerType                   `json:"ownerType"`
	PeriodFrom  time.Time                   `json:"periodFrom"`
	PeriodTo    time.Time                   `json:"periodTo"`
	Totals      map[string]int64            `json:"totals"`
	ByWorkspace map[string]map[string]int64 `json:"byWorkspace,omitempty"`
	ByDay       map[string]map[string]int64 `json:"byDay,omitempty"`
}

type User

type User struct {
	ID            string     `json:"id" db:"id"`
	Username      string     `json:"username" db:"username"`
	Email         string     `json:"email" db:"email"`
	PasswordHash  string     `json:"-" db:"password_hash"`
	CreatedAt     time.Time  `json:"createdAt" db:"created_at"`
	UpdatedAt     time.Time  `json:"updatedAt" db:"updated_at"`
	Active        bool       `json:"active" db:"active"`
	Role          string     `json:"role" db:"role"`
	Status        UserStatus `json:"status" db:"status"`
	EmailVerified bool       `json:"emailVerified" db:"email_verified"`
}

User represents a user

type UserListEntry

type UserListEntry struct {
	ID        string     `json:"id"`
	Email     string     `json:"email"`
	Role      string     `json:"role"`
	Status    UserStatus `json:"status"`
	CreatedAt time.Time  `json:"createdAt"`
	OrgCount  int        `json:"orgCount"`
	OrgID     string     `json:"orgId,omitempty"`
	OrgName   string     `json:"orgName,omitempty"`
}

UserListEntry is the list DTO for platform admin user listing.

type UserStatus

type UserStatus string

UserStatus is the authoritative operational status of a user account.

const (
	UserStatusActive    UserStatus = "active"
	UserStatusSuspended UserStatus = "suspended"
)

type UserUpdates

type UserUpdates struct {
	Username      *string     `json:"username,omitempty"`
	Email         *string     `json:"email,omitempty"`
	Active        *bool       `json:"active,omitempty"`
	Role          *string     `json:"role,omitempty"`
	Status        *UserStatus `json:"status,omitempty"`
	PasswordHash  *string     `json:"-"`
	EmailVerified *bool       `json:"-"`
}

UserUpdates carries the fields that may be changed on a User record. All fields are pointers — nil means "do not update this field".

type WSConnection

type WSConnection interface {
	// ReadMessage reads a message from the connection
	ReadMessage() (messageType int, p []byte, err error)

	// WriteMessage writes a message to the connection
	WriteMessage(messageType int, data []byte) error

	// Close closes the connection
	Close() error
}

WSConnection represents a WebSocket connection

type Workspace

type Workspace struct {
	ID                      string            `json:"id"`
	Name                    string            `json:"name"`
	UserID                  string            `json:"userId"`
	Runtime                 string            `json:"runtime"`
	StorageSize             string            `json:"storageSize"`
	Phase                   string            `json:"phase"`
	PVCName                 string            `json:"pvcName,omitempty"`
	Labels                  map[string]string `json:"labels,omitempty"`
	DefaultModel            string            `json:"defaultModel,omitempty"`
	CreatedAt               time.Time         `json:"createdAt"`
	UpdatedAt               time.Time         `json:"updatedAt"`
	AgentNeedsRefresh       bool              `json:"agentNeedsRefresh"`
	CredentialsPendingSince *time.Time        `json:"credentialsPendingSince,omitempty"`
}

Workspace is the API transfer object for a workspace resource.

type WorkspaceConditionResult

type WorkspaceConditionResult struct {
	Type    string `json:"type"`
	Status  string `json:"status"`
	Reason  string `json:"reason,omitempty"`
	Message string `json:"message,omitempty"`
}

WorkspaceConditionResult carries a single workspace condition.

type WorkspaceConfig

type WorkspaceConfig struct {
	DefaultModel string `json:"defaultModel,omitempty"`
}

WorkspaceConfig is non-sensitive workspace metadata (default model) delivered to the pod via the bootstrap HTTP endpoint at boot.

type WorkspaceListItem

type WorkspaceListItem struct {
	ID                      string     `json:"id"`
	Name                    string     `json:"name"`
	UserID                  string     `json:"userId"`
	Runtime                 string     `json:"runtime"`
	StorageSize             string     `json:"storageSize"`
	Phase                   string     `json:"phase,omitempty"`
	ImageTag                string     `json:"imageTag,omitempty"`
	AgentVersion            string     `json:"agentVersion,omitempty"`
	DefaultModel            string     `json:"defaultModel,omitempty"`
	MaxActiveSessions       int        `json:"maxActiveSessions,omitempty"`
	CreatedAt               time.Time  `json:"createdAt"`
	UpdatedAt               time.Time  `json:"updatedAt"`
	AgentNeedsRefresh       bool       `json:"agentNeedsRefresh"`
	CredentialsPendingSince *time.Time `json:"credentialsPendingSince,omitempty"`
	// OrgID is the owning org for org-scoped workspaces (Epic 11; nil for
	// personal workspaces). The frontend relies on this field to decide
	// whether to fetch and enforce the org's allow_user_prompt policy in
	// the Workspace Settings drawer's "Custom Instructions" Lock UI.
	// Mirrors WorkspaceMetadata.OrgID.
	OrgID *string `json:"orgId,omitempty"`
}

WorkspaceListItem is a lightweight workspace representation for list responses.

type WorkspaceListResult

type WorkspaceListResult struct {
	Items      []WorkspaceListItem `json:"items"`
	Pagination *PaginationMetadata `json:"pagination,omitempty"`
}

WorkspaceListResult bundles workspace list items with pagination.

type WorkspaceMetadata

type WorkspaceMetadata struct {
	ID           string    `json:"id" db:"id"`
	UserID       string    `json:"userId" db:"user_id"`
	Name         string    `json:"name" db:"name"`
	Runtime      string    `json:"runtime" db:"runtime"`
	StorageSize  string    `json:"storageSize" db:"storage_size"`
	ImageTag     string    `json:"imageTag" db:"image_tag"`
	AgentVersion string    `json:"agentVersion" db:"agent_version"`
	CreatedAt    time.Time `json:"createdAt" db:"created_at"`
	UpdatedAt    time.Time `json:"updatedAt" db:"updated_at"`
	// Model selection (migration 000013)
	DefaultModel string `json:"defaultModel,omitempty" db:"default_model"`
	// Epic 27a: agent credential state (LEFT JOIN workspace_agent_state)
	AgentNeedsRefresh       bool       `json:"agentNeedsRefresh" db:"agent_needs_refresh"`
	CredentialsPendingSince *time.Time `json:"credentialsPendingSince,omitempty" db:"credentials_pending_since"`
	// Epic 11: org attribution (nullable — personal workspaces have no org)
	OrgID *string `json:"orgId,omitempty" db:"org_id"`
}

WorkspaceMetadata is the database record for a workspace.

Phase and pvc_state used to live here as a denormalised cache of the Workspace CRD's status fields. The cache was removed in migration 9 because it was eventually-consistent at best (best-effort writes from `syncPhase`) and routinely diverged from the CRD shortly after creation, which caused the sidebar to render new workspaces with no phase. The CRD is now the only source of truth; phase is fetched directly from the kube-apiserver in `ListWorkspaces` and `enforceMaxActiveWorkspaces`.

func WorkspaceMetaFromCtx

func WorkspaceMetaFromCtx(ctx context.Context) (*WorkspaceMetadata, bool)

WorkspaceMetaFromCtx returns the *WorkspaceMetadata stored in ctx by WorkspaceAccessMiddleware, or (nil, false) when the middleware did not run (e.g. the caller is a background job, a route outside idGroup, or a unit test). Callers that need to authorize MUST handle the (nil, false) case explicitly — a missing meta is NOT an implicit allow.

type WorkspaceNotFoundError

type WorkspaceNotFoundError struct {
	ID string
}

WorkspaceNotFoundError is returned when a workspace cannot be found.

func (*WorkspaceNotFoundError) Error

func (e *WorkspaceNotFoundError) Error() string

type WorkspacePrompt

type WorkspacePrompt struct {
	WorkspaceID string    `json:"-"`
	Prompt      string    `json:"prompt"`
	AgentRoleID *string   `json:"agentRoleId,omitempty"`
	UpdatedBy   string    `json:"-"`
	UpdatedAt   time.Time `json:"updatedAt"`
}

WorkspacePrompt holds the user-level agent customization for a workspace. This is only consulted when the org's allow_user_prompt policy is true.

type WorkspaceStatusResult

type WorkspaceStatusResult struct {
	Phase            string                     `json:"phase"`
	PVCName          string                     `json:"pvcName,omitempty"`
	ActiveSessions   int                        `json:"activeSessions"`
	LastActivityAt   *time.Time                 `json:"lastActivityAt,omitempty"`
	Message          string                     `json:"message,omitempty"`
	Conditions       []WorkspaceConditionResult `json:"conditions,omitempty"`
	CredentialState  CredentialStateResult      `json:"credentialState"`
	AgentHealth      AgentHealthResult          `json:"agentHealth"`
	Sessions         []SessionStatusItem        `json:"sessions,omitempty"`
	ImageTag         string                     `json:"imageTag,omitempty"`
	DiskUsedBytes    int64                      `json:"diskUsedBytes,omitempty"`
	DiskTotalBytes   int64                      `json:"diskTotalBytes,omitempty"`
	MemoryUsedBytes  int64                      `json:"memoryUsedBytes,omitempty"`
	MemoryTotalBytes int64                      `json:"memoryTotalBytes,omitempty"`
	ContextUsed      int64                      `json:"contextUsed"`
	ContextTotal     int64                      `json:"contextTotal"`
}

WorkspaceStatusResult carries the status fields read from the Workspace CRD.

type WorkspaceUpdates

type WorkspaceUpdates struct {
	Name         *string `json:"name,omitempty"`
	DefaultModel *string `json:"defaultModel,omitempty"`
}

WorkspaceUpdates carries the fields that may be changed on a WorkspaceMetadata record.

Jump to

Keyboard shortcuts

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