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
- Variables
- func MarshalRoleConfig(cfg *RoleConfig) ([]byte, error)
- func MaxPromptPerLevel() int
- type APIKey
- type ActivateWorkspaceResponse
- type ActiveSessionsResponse
- type AddOrgMemberRequest
- type AgentHealthResult
- type AgentRole
- type AuditEntry
- type AuditFilters
- type AuthConfig
- type AuthResponse
- type BillingOwner
- type CachedSession
- type ChangeOrgMemberRoleRequest
- type ContainerStateValue
- type ContainerStatus
- type CreateAPIKeyRequest
- type CreateInvitationsRequest
- type CreateOrgRequest
- type CreateOrgResponse
- type CreateWorkspaceRequest
- type CredentialStateResult
- type EffectiveAgentRole
- type EffectivePrompt
- type EgressRule
- type EmailToken
- type EnsureSessionResponse
- type Event
- type ExecutionResult
- type FileInfo
- type FilesystemConfig
- type InvitationDetail
- type LastAdminOrg
- type ListOptions
- type LoginRequest
- type Message
- type NetworkAccess
- type NetworkInfo
- type OrgInvitation
- type OrgMember
- type OrgPlan
- type OrgPolicy
- type OrgPolicyKey
- type OrgPolicyValues
- func (p *OrgPolicyValues) IsModelAllowed(modelID string) bool
- func (p *OrgPolicyValues) IsProviderAllowed(providerID string) bool
- func (p *OrgPolicyValues) IsUserPromptAllowed() bool
- func (p *OrgPolicyValues) MaxActive() int
- func (p *OrgPolicyValues) MaxWorkspaces() int
- func (p *OrgPolicyValues) OrgPrompt() string
- type OrgResponse
- type OrgRole
- type OrgSSOConfig
- type OrgSSOConfigResponse
- type OrgStatus
- type OrgSubscriptionStatus
- type OrgSummary
- type Organization
- type OwnerType
- type PaginationMetadata
- type PermissionRule
- type PlatformSetting
- type PlatformSettingKey
- type PortRule
- type ProfileReference
- type QuotaStatus
- type RefreshWorkspaceResult
- type RegisterRequest
- type ResourceRequirements
- type ResourceStatus
- type RoleConfig
- type SSODomain
- type SecurityContext
- type Session
- type SessionListItem
- type SessionStatusItem
- type StorageConfig
- type UpdateOrgRequest
- type UpsertSSOConfigRequest
- type UsageEvent
- type UsageReport
- type User
- type UserListEntry
- type UserStatus
- type UserUpdates
- type WSConnection
- type Workspace
- type WorkspaceConditionResult
- type WorkspaceConfig
- type WorkspaceListItem
- type WorkspaceListResult
- type WorkspaceMetadata
- type WorkspaceNotFoundError
- type WorkspacePrompt
- type WorkspaceStatusResult
- type WorkspaceUpdates
Constants ¶
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.
const ContextKeyUserRole contextKey = "userRole"
ContextKeyUserRole is the context key used to store the authenticated user's role.
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).
const RoleConfigVersion = 1
RoleConfigVersion is the current config schema version.
Variables ¶
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 ¶
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 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 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 ¶
LastAdminOrg identifies an org where a user is the sole active admin.
type ListOptions ¶
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 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.
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 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.
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 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 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.