trustedai

package module
v0.0.0-...-30b5f87 Latest Latest
Warning

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

Go to latest
Published: Aug 8, 2025 License: AGPL-3.0 Imports: 11 Imported by: 0

README ยถ

TrustedAI

TrustedAI Logo

Enterprise-Grade LLM Gateway for Secure AI Adoption

Go React Status

Bringing enterprise security and governance to Large Language Model deployments

๐Ÿš€ Why TrustedAI?

Organizations adopting AI face a critical challenge: How do you harness the power of LLMs while maintaining enterprise security, compliance, and cost control?

TrustedAI solves this by providing a secure, observable, and governable gateway between your organization and LLM providers. No more shadow IT, ungoverned API keys, or compliance nightmares.

The Problem We Solve
  • ๐Ÿ”’ Security Gaps: Direct API access bypasses enterprise security controls
  • ๐Ÿ’ธ Cost Overruns: No visibility into usage patterns or cost attribution
  • ๐Ÿ“Š Compliance Blind Spots: Lack of audit trails and usage monitoring
  • ๐Ÿข Governance Challenges: Scattered API keys and ungoverned access
  • ๐Ÿ”ง Developer Friction: Complex integration patterns for enterprise features

โœจ Key Features

๐Ÿ›ก๏ธ Enterprise Security First
  • SSO-Only Authentication: OIDC/SAML integration with Okta, EntraID, Keycloak
  • Zero Local Passwords: Eliminate credential vulnerabilities
  • Session Management: Secure token-based access with easy revocation
  • Multi-Tenant Architecture: Organization-level isolation and controls
๐Ÿ“Š Complete Observability
  • Real-Time Analytics: Usage patterns, cost tracking, and performance metrics
  • OpenTelemetry Integration: Seamless monitoring stack integration
  • Detailed Audit Trails: Full request/response logging for compliance
  • Cost Attribution: Per-user, per-model billing and quota management
๐Ÿ—๏ธ Production-Ready Architecture
  • Dual-Plane Design:
    • Control Plane: Management APIs, user interface, and administration
    • Data Plane: High-performance LLM request routing and processing
  • Multi-Provider Support:
    • Frontend APIs: OpenAI, Anthropic (Gemini planned)
    • Backend Routing: OpenRouter with planned support for Bedrock, Vertex AI
  • Database-Driven: PostgreSQL-backed configuration and state management
โšก Developer Experience
  • Modern Web UI: React/TypeScript dashboard with real-time updates
  • ConnectRPC APIs: Type-safe, high-performance API layer with HTTP/2
  • Comprehensive Testing: Unit, integration, and acceptance test suites
  • Docker Compose: Simple local development setup

๐Ÿ”ฎ Roadmap

We're actively developing these enterprise-critical features:

  • ๐Ÿ›ก๏ธ AI Guardrails: Content filtering, safety controls, and policy enforcement
  • ๐Ÿ“ Prompt Management: Centralized prompt templates and version control
  • ๐ŸŽฏ Advanced Routing: Load balancing, failover, and A/B testing
  • ๐Ÿ“Š Enhanced Analytics: Custom dashboards and reporting
  • ๐Ÿ”— More Integrations: Bedrock, Vertex AI, Azure OpenAI Service

๐Ÿš€ Quick Start

Prerequisites
1. Clone and Setup
git clone https://github.com/MadsRC/trustedai.git
cd trustedai

# Install tools and dependencies
mise install
mise run dev/bootstrap.sh
2. Start Infrastructure
# Start PostgreSQL, Keycloak, and OTEL Collector
docker compose up -d

# Wait for services to be ready (especially database)
docker compose ps
3. Run TrustedAI
# Start the backend (control plane + data plane)
DATABASE_URL="postgres://postgres:postgres@localhost:5432/postgres" \
LLMGW_BASE_URL="http://localhost:5173" \
go run cmd/trustedai/main.go

# In another terminal, start the frontend
cd frontend
npm run dev
4. Access the Dashboard

Open http://localhost:5173 and sign in using:

๐Ÿ“š Documentation

๐Ÿ—๏ธ Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   React App     โ”‚    โ”‚  Control Plane  โ”‚
โ”‚  (Port 5173)    โ”‚โ—„โ”€โ”€โ–บโ”‚   (Port 9999)   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                โ”‚
                                โ–ผ
                       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                       โ”‚   Data Plane    โ”‚
                       โ”‚   (Port 8081)   โ”‚
                       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                โ”‚
                                โ–ผ
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚    LLM Providers        โ”‚
                    โ”‚ OpenAI โ”‚ Anthropic โ”‚... โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Control Plane: User management, configuration, analytics, and web UI Data Plane: High-performance LLM request routing and response handling

๐Ÿค Contributing

We welcome contributions! TrustedAI is in active development and we're looking for:

  • ๐Ÿ› Bug Reports: Help us identify and fix issues
  • ๐Ÿ’ก Feature Requests: Share your enterprise AI governance needs
  • ๐Ÿ”ง Code Contributions: Check our issues for good first contributions
  • ๐Ÿ“– Documentation: Help improve our guides and examples
Development Workflow
  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Follow our conventions: Read CLAUDE.md for coding standards
  4. Test your changes: mise run test:unit
  5. Format code: mise run format
  6. Lint code: mise run lint
  7. Commit with conventional commits: feat: add amazing feature
  8. Open a Pull Request

๐Ÿ“‹ Requirements

  • Go: 1.24.4+
  • Node.js: 24.2.0+
  • PostgreSQL: 17+
  • Docker: For local development

๐Ÿ“„ License

TrustedAI is licensed under the GNU Affero General Public License v3.0.

We chose AGPL-3.0 because we believe enterprise AI infrastructure should be transparent, auditable, and community-driven. This ensures that improvements to TrustedAI benefit everyone in the ecosystem.

๐Ÿšง Project Status

TrustedAI is currently in Alpha. We're actively developing core features and welcome feedback from enterprise teams tackling AI governance challenges.

  • โœ… Core Architecture: Control/Data plane separation
  • โœ… Authentication: SSO integration with OIDC
  • โœ… Multi-Provider: OpenAI, Anthropic, OpenRouter support
  • โœ… Observability: Usage tracking and metrics
  • ๐Ÿšง Guardrails: In development
  • ๐Ÿšง Prompt Management: Planned
  • ๐Ÿšง Advanced Routing: Planned

๐Ÿ’ฌ Community & Support


Ready to bring enterprise security to your AI deployment?

โญ Star this repo if TrustedAI solves a problem you're facing!

Get Started โ€ข View Issues โ€ข Join Discussions

Documentation ยถ

Index ยถ

Constants ยถ

This section is empty.

Variables ยถ

View Source
var (
	// ErrNotFound should be returned when a requested resource cannot be found
	ErrNotFound = errors.New("not found")

	// ErrDuplicateEntry should be returned when a resource would violate unique constraints
	ErrDuplicateEntry = errors.New("duplicate entry")

	// ErrUnauthorized should be returned when a user lacks permission for an operation
	ErrUnauthorized = errors.New("unauthorized")
)
View Source
var OrganizationContextKey = ContextKey{}

Functions ยถ

func GetFrontendFS ยถ

func GetFrontendFS() fs.FS

GetFrontendFS returns the embedded frontend filesystem

Types ยถ

type APIToken ยถ

type APIToken struct {
	ID          string     `json:"id"`
	UserID      string     `json:"userId"`
	Description string     `json:"description"`
	PrefixHash  string     `json:"-"` // SHA256 of token prefix for lookups
	TokenHash   string     `json:"-"` // Argon2id hash of full token
	CreatedAt   time.Time  `json:"createdAt"`
	ExpiresAt   time.Time  `json:"expiresAt"`
	LastUsedAt  *time.Time `json:"lastUsedAt,omitempty"`
}

APIToken represents an API access credential

type BillingRepository ยถ

type BillingRepository interface {
	// CreateBillingSummary stores a new billing summary
	CreateBillingSummary(ctx context.Context, summary *BillingSummary) error

	// GetBillingSummary retrieves a billing summary by ID
	GetBillingSummary(ctx context.Context, id string) (*BillingSummary, error)

	// ListBillingSummariesByUser retrieves billing summaries for a specific user
	ListBillingSummariesByUser(ctx context.Context, userID string, limit, offset int) ([]*BillingSummary, error)

	// ListBillingSummariesByPeriod retrieves billing summaries for a specific period
	ListBillingSummariesByPeriod(ctx context.Context, start, end time.Time) ([]*BillingSummary, error)

	// GetBillingSummaryForUserPeriod retrieves existing billing summary for a user and period
	GetBillingSummaryForUserPeriod(ctx context.Context, userID string, start, end time.Time) (*BillingSummary, error)

	// UpdateBillingSummary updates an existing billing summary
	UpdateBillingSummary(ctx context.Context, summary *BillingSummary) error
}

BillingRepository defines persistence operations for billing summaries

type BillingSummary ยถ

type BillingSummary struct {
	ID                string    `json:"id"`
	UserID            string    `json:"userId"`
	PeriodStart       time.Time `json:"periodStart"`
	PeriodEnd         time.Time `json:"periodEnd"`
	TotalRequests     int       `json:"totalRequests"`
	TotalInputTokens  int64     `json:"totalInputTokens"`
	TotalOutputTokens int64     `json:"totalOutputTokens"`
	TotalCostCents    float64   `json:"totalCostCents"`
	CreatedAt         time.Time `json:"createdAt"`
}

BillingSummary represents pre-aggregated billing data for a user and period

type ContextKey ยถ

type ContextKey struct{}

Context keys for passing data through request contexts

type CostResult ยถ

type CostResult struct {
	InputCostCents  float64 `json:"inputCostCents"`
	OutputCostCents float64 `json:"outputCostCents"`
	TotalCostCents  float64 `json:"totalCostCents"`
}

CostResult represents the result of a cost calculation

type CredentialRepository ยถ

type CredentialRepository interface {
	GetOpenRouterCredential(ctx context.Context, credentialID uuid.UUID) (*OpenRouterCredential, error)
	ListOpenRouterCredentials(ctx context.Context) ([]OpenRouterCredential, error)
	CreateOpenRouterCredential(ctx context.Context, cred *OpenRouterCredential) error
	UpdateOpenRouterCredential(ctx context.Context, cred *OpenRouterCredential) error
	DeleteOpenRouterCredential(ctx context.Context, credentialID uuid.UUID) error
}

CredentialRepository defines persistence operations for Credentials

type DeviceAuthResponse ยถ

type DeviceAuthResponse struct {
	DeviceCode      string
	UserCode        string
	VerificationURI string
	ExpiresIn       time.Duration
	Interval        time.Duration
}

type ModelRepository ยถ

type ModelRepository interface {
	GetAllModels(ctx context.Context) ([]ModelWithCredentials, error)
	GetModelByID(ctx context.Context, modelID string) (*ModelWithCredentials, error)
	CreateModel(ctx context.Context, model *gai.Model, credentialID uuid.UUID, credentialType trustedaiv1.CredentialType) error
	UpdateModel(ctx context.Context, model *gai.Model, credentialID uuid.UUID, credentialType trustedaiv1.CredentialType) error
	DeleteModel(ctx context.Context, modelID string) error
}

ModelRepository defines persistence operations for Models

type ModelWithCredentials ยถ

type ModelWithCredentials struct {
	Model          gai.Model
	CredentialID   uuid.UUID
	CredentialType trustedaiv1.CredentialType
}

ModelWithCredentials represents a model with its associated credentials

type OpenRouterCredential ยถ

type OpenRouterCredential struct {
	ID          uuid.UUID `json:"id"`
	Name        string    `json:"name"`
	Description string    `json:"description"`
	APIKey      string    `json:"api_key"`
	SiteName    string    `json:"site_name"`
	HTTPReferer string    `json:"http_referer"`
	Enabled     bool      `json:"enabled"`
}

OpenRouterCredential represents an OpenRouter API credential

type Organization ยถ

type Organization struct {
	ID          string    `json:"id"`
	Name        string    `json:"name"`
	DisplayName string    `json:"displayName"`
	IsSystem    bool      `json:"isSystem"` // Marks the platform's own organization
	CreatedAt   time.Time `json:"createdAt"`
	SSOType     string    `json:"ssoType"`   // "oidc", "saml", "github", etc
	SSOConfig   SSOConfig `json:"ssoConfig"` // Flexible provider configuration with redaction
}

Organization represents a tenant in the system

func (*Organization) IsSSOEnabled ยถ

func (o *Organization) IsSSOEnabled() bool

IsSSOEnabled checks if organization has SSO configured

func (*Organization) IsSystemTenant ยถ

func (o *Organization) IsSystemTenant() bool

IsSystemTenant identifies the platform management tenant

type OrganizationRepository ยถ

type OrganizationRepository interface {
	Create(ctx context.Context, org *Organization) error
	Get(ctx context.Context, id string) (*Organization, error)
	GetByName(ctx context.Context, name string) (*Organization, error)
	List(ctx context.Context) ([]*Organization, error)
	ListForUser(ctx context.Context, user *User) ([]*Organization, error)
	Update(ctx context.Context, org *Organization) error
	Delete(ctx context.Context, id string) error
}

OrganizationRepository defines persistence operations for Organizations

type ProviderConfig ยถ

type ProviderConfig struct {
	ID           string `json:"id"`
	Name         string `json:"name"`
	ProviderType string `json:"provider_type"`
	Enabled      bool   `json:"enabled"`
}

ProviderConfig represents a provider configuration

type ProviderRepository ยถ

type ProviderRepository interface {
	GetAllProviders(ctx context.Context) ([]ProviderConfig, error)
	GetProviderByID(ctx context.Context, providerID string) (*ProviderConfig, error)
	CreateProvider(ctx context.Context, provider *ProviderConfig) error
	UpdateProvider(ctx context.Context, provider *ProviderConfig) error
	DeleteProvider(ctx context.Context, providerID string) error
}

ProviderRepository defines persistence operations for Providers

type SSOConfig ยถ

type SSOConfig map[string]any

SSOConfig is a custom type for SSO configuration

func (*SSOConfig) Scan ยถ

func (s *SSOConfig) Scan(value any) error

Scan implements sql.Scanner interface for database scanning

func (SSOConfig) Value ยถ

func (s SSOConfig) Value() (driver.Value, error)

Value implements driver.Valuer interface for database storage

type SsoProvider ยถ

type SsoProvider interface {
	GetAuthURL(ctx context.Context, state string) (string, error)
	HandleCallback(ctx context.Context, code string) (*User, error)
	ValidateToken(ctx context.Context, token string) (bool, map[string]any, error)

	// Device Flow additions
	StartDeviceAuth(ctx context.Context) (*DeviceAuthResponse, error)
	CheckDeviceAuth(ctx context.Context, deviceCode string) (*User, error)
}

type TokenRepository ยถ

type TokenRepository interface {
	// CreateToken generates and stores a new API token
	CreateToken(
		ctx context.Context,
		userID string,
		description string,
		expiresAt time.Time,
	) (*APIToken, string, error) // Returns token record and raw token

	// GetTokenByPrefixHash retrieves token by hashed prefix
	GetTokenByPrefixHash(ctx context.Context, prefixHash string) (*APIToken, error)

	// RevokeToken permanently invalidates a token
	RevokeToken(ctx context.Context, tokenID string) error

	// ListUserTokens returns all active tokens for a user
	ListUserTokens(ctx context.Context, userID string) ([]*APIToken, error)

	// ListUserTokensForUser returns tokens visible to the requesting user
	ListUserTokensForUser(ctx context.Context, requestingUser *User, targetUserID string) ([]*APIToken, error)

	// ListAllTokensForUser returns all tokens visible to the requesting user
	ListAllTokensForUser(ctx context.Context, requestingUser *User) ([]*APIToken, error)

	// RevokeTokenForUser revokes a token if the requesting user has permission
	RevokeTokenForUser(ctx context.Context, requestingUser *User, tokenID string) error

	// UpdateTokenUsage records when a token was last used
	UpdateTokenUsage(ctx context.Context, tokenID string) error
}

TokenRepository defines persistence operations for API tokens

type UsageEvent ยถ

type UsageEvent struct {
	ID              string    `json:"id"`
	RequestID       string    `json:"requestId"`
	UserID          string    `json:"userId"`
	ModelID         string    `json:"modelId"`
	InputTokens     *int      `json:"inputTokens,omitempty"`
	OutputTokens    *int      `json:"outputTokens,omitempty"`
	CachedTokens    *int      `json:"cachedTokens,omitempty"`
	ReasoningTokens *int      `json:"reasoningTokens,omitempty"`
	Status          string    `json:"status"`
	FailureStage    *string   `json:"failureStage,omitempty"`
	ErrorType       *string   `json:"errorType,omitempty"`
	ErrorMessage    *string   `json:"errorMessage,omitempty"`
	UsageDataSource string    `json:"usageDataSource"`
	DataComplete    bool      `json:"dataComplete"`
	Timestamp       time.Time `json:"timestamp"`
	DurationMs      *int      `json:"durationMs,omitempty"`
	InputCostCents  *float64  `json:"inputCostCents,omitempty"`
	OutputCostCents *float64  `json:"outputCostCents,omitempty"`
	TotalCostCents  *float64  `json:"totalCostCents,omitempty"`
}

UsageEvent represents a single usage tracking event

type UsageRepository ยถ

type UsageRepository interface {
	// CreateUsageEvent stores a new usage event
	CreateUsageEvent(ctx context.Context, event *UsageEvent) error

	// GetUsageEvent retrieves a usage event by ID
	GetUsageEvent(ctx context.Context, id string) (*UsageEvent, error)

	// ListUsageEventsByUser retrieves usage events for a specific user with pagination
	ListUsageEventsByUser(ctx context.Context, userID string, limit, offset int) ([]*UsageEvent, error)

	// ListUsageEventsForCostCalculation retrieves uncalculated usage events that are ready for cost calculation
	ListUsageEventsForCostCalculation(ctx context.Context, limit int) ([]*UsageEvent, error)

	// UpdateUsageEventCost updates the cost fields for a usage event
	UpdateUsageEventCost(ctx context.Context, eventID string, cost CostResult) error

	// ListUsageEventsByPeriod retrieves usage events for a specific period
	ListUsageEventsByPeriod(ctx context.Context, userID string, start, end time.Time) ([]*UsageEvent, error)
}

UsageRepository defines persistence operations for usage events

type User ยถ

type User struct {
	ID             string    `json:"id"`
	Email          string    `json:"email"`
	Name           string    `json:"name"`
	OrganizationID string    `json:"organizationId"`
	ExternalID     string    `json:"externalId"` // ID from identity provider
	Provider       string    `json:"provider"`   // "github", "okta", etc
	SystemAdmin    bool      `json:"systemAdmin"`
	CreatedAt      time.Time `json:"createdAt"`
	LastLogin      time.Time `json:"lastLogin"`
}

User represents a system user with SSO integration capabilities

func (*User) GetOrganizationID ยถ

func (u *User) GetOrganizationID() string

GetOrganizationID implements tenant association for authorization

func (*User) IsSystemAdmin ยถ

func (u *User) IsSystemAdmin() bool

IsSystemAdmin checks if user has platform-level privileges

type UserRepository ยถ

type UserRepository interface {
	Create(ctx context.Context, user *User) error
	Get(ctx context.Context, id string) (*User, error)
	GetByEmail(ctx context.Context, email string) (*User, error)
	GetByExternalID(ctx context.Context, provider, externalID string) (*User, error)
	ListByOrganization(ctx context.Context, orgID string) ([]*User, error)
	ListByOrganizationForUser(ctx context.Context, requestingUser *User, orgID string) ([]*User, error)
	ListAllForUser(ctx context.Context, requestingUser *User) ([]*User, error)
	Update(ctx context.Context, user *User) error
	Delete(ctx context.Context, id string) error
}

UserRepository defines persistence operations for Users

Jump to

Keyboard shortcuts

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