- Updated python_coding_microproject.csv to use NVIDIA NIM Kimi K2 - Updated kali_linux_shell_simulator.csv to use NVIDIA NIM Kimi K2 - Made more general-purpose (flexible targets, expanded tools) - Added nemotron-mini-agent.csv for fast local inference via Ollama - Added nemotron-agent.csv for advanced reasoning via Ollama - Added wiki page: Projects for NVIDIA NIMs and Nemotron
145 lines
5.4 KiB
Python
145 lines
5.4 KiB
Python
"""
|
|
Configuration settings for GT 2.0 Control Panel Backend
|
|
"""
|
|
import os
|
|
from typing import List, Optional
|
|
from pydantic_settings import BaseSettings
|
|
from pydantic import Field, validator
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
"""Application settings"""
|
|
|
|
# Application
|
|
DEBUG: bool = Field(default=False, env="DEBUG")
|
|
ENVIRONMENT: str = Field(default="development", env="ENVIRONMENT")
|
|
SECRET_KEY: str = Field(default="PRODUCTION_SECRET_KEY_REQUIRED", env="SECRET_KEY")
|
|
ALLOWED_ORIGINS: List[str] = Field(
|
|
default=["http://localhost:3000", "http://localhost:3001"],
|
|
env="ALLOWED_ORIGINS"
|
|
)
|
|
|
|
# Database (PostgreSQL direct connection)
|
|
DATABASE_URL: str = Field(
|
|
default="postgresql+asyncpg://postgres:gt2_admin_dev_password@postgres:5432/gt2_admin",
|
|
env="DATABASE_URL"
|
|
)
|
|
|
|
# Redis removed - PostgreSQL handles all session and caching needs
|
|
|
|
# MinIO removed - PostgreSQL handles all file storage
|
|
|
|
# Kubernetes
|
|
KUBERNETES_IN_CLUSTER: bool = Field(default=False, env="KUBERNETES_IN_CLUSTER")
|
|
KUBECONFIG_PATH: Optional[str] = Field(default=None, env="KUBECONFIG_PATH")
|
|
|
|
# ChromaDB
|
|
CHROMADB_HOST: str = Field(default="localhost", env="CHROMADB_HOST")
|
|
CHROMADB_PORT: int = Field(default=8000, env="CHROMADB_PORT")
|
|
CHROMADB_AUTH_USER: str = Field(default="admin", env="CHROMADB_AUTH_USER")
|
|
CHROMADB_AUTH_PASSWORD: str = Field(default="dev_chroma_password", env="CHROMADB_AUTH_PASSWORD")
|
|
|
|
# Dremio SQL Federation
|
|
DREMIO_URL: Optional[str] = Field(default="http://dremio:9047", env="DREMIO_URL")
|
|
DREMIO_USERNAME: Optional[str] = Field(default="admin", env="DREMIO_USERNAME")
|
|
DREMIO_PASSWORD: Optional[str] = Field(default="admin123", env="DREMIO_PASSWORD")
|
|
|
|
# Service Authentication
|
|
SERVICE_AUTH_TOKEN: Optional[str] = Field(default="internal-service-token", env="SERVICE_AUTH_TOKEN")
|
|
|
|
# JWT - NIST/OWASP Compliant Session Timeouts (Issue #242)
|
|
JWT_SECRET: str = Field(default="dev-jwt-secret-change-in-production-32-chars-minimum", env="JWT_SECRET")
|
|
JWT_ALGORITHM: str = Field(default="HS256", env="JWT_ALGORITHM")
|
|
# JWT expiration: 12 hours (matches absolute timeout) - NIST SP 800-63B AAL2 compliant
|
|
# Server-side session enforces 30-minute idle timeout via last_activity_at tracking
|
|
# JWT exp serves as backstop - prevents tokens from being valid beyond absolute limit
|
|
JWT_EXPIRES_MINUTES: int = Field(default=720, env="JWT_EXPIRES_MINUTES")
|
|
# Absolute timeout: 12 hours - NIST SP 800-63B AAL2 maximum session duration
|
|
JWT_ABSOLUTE_TIMEOUT_HOURS: int = Field(default=12, env="JWT_ABSOLUTE_TIMEOUT_HOURS")
|
|
# Legacy support (deprecated - use JWT_EXPIRES_MINUTES instead)
|
|
JWT_EXPIRES_HOURS: int = Field(default=4, env="JWT_EXPIRES_HOURS")
|
|
|
|
# Aliases for compatibility
|
|
@property
|
|
def secret_key(self) -> str:
|
|
return self.JWT_SECRET
|
|
|
|
@property
|
|
def algorithm(self) -> str:
|
|
return self.JWT_ALGORITHM
|
|
|
|
# Encryption
|
|
MASTER_ENCRYPTION_KEY: str = Field(
|
|
default="dev-master-key-change-in-production-must-be-32-bytes-long",
|
|
env="MASTER_ENCRYPTION_KEY"
|
|
)
|
|
|
|
# Tenant Settings
|
|
TENANT_DATA_DIR: str = Field(default="/data", env="TENANT_DATA_DIR")
|
|
DEFAULT_TENANT_TEMPLATE: str = Field(default="basic", env="DEFAULT_TENANT_TEMPLATE")
|
|
|
|
# External AI Services
|
|
GROQ_API_KEY: Optional[str] = Field(default=None, env="GROQ_API_KEY")
|
|
GROQ_BASE_URL: str = Field(default="https://api.groq.com/openai/v1", env="GROQ_BASE_URL")
|
|
|
|
# Resource Cluster
|
|
RESOURCE_CLUSTER_URL: str = Field(default="http://localhost:8003", env="RESOURCE_CLUSTER_URL")
|
|
|
|
# Logging
|
|
LOG_LEVEL: str = Field(default="INFO", env="LOG_LEVEL")
|
|
|
|
# RabbitMQ (for message bus)
|
|
RABBITMQ_URL: str = Field(
|
|
default="amqp://admin:dev_rabbitmq_password@localhost:5672/gt2",
|
|
env="RABBITMQ_URL"
|
|
)
|
|
MESSAGE_BUS_SECRET_KEY: str = Field(
|
|
default="PRODUCTION_MESSAGE_BUS_SECRET_REQUIRED",
|
|
env="MESSAGE_BUS_SECRET_KEY"
|
|
)
|
|
|
|
# Celery (for background tasks) - Using PostgreSQL instead of Redis
|
|
CELERY_BROKER_URL: str = Field(
|
|
default="db+postgresql://gt2_admin:dev_password_change_in_prod@postgres:5432/gt2_control_panel",
|
|
env="CELERY_BROKER_URL"
|
|
)
|
|
CELERY_RESULT_BACKEND: str = Field(
|
|
default="db+postgresql://gt2_admin:dev_password_change_in_prod@postgres:5432/gt2_control_panel",
|
|
env="CELERY_RESULT_BACKEND"
|
|
)
|
|
|
|
@validator('ALLOWED_ORIGINS', pre=True)
|
|
def parse_cors_origins(cls, v):
|
|
if isinstance(v, str):
|
|
return [origin.strip() for origin in v.split(',')]
|
|
return v
|
|
|
|
@validator('MASTER_ENCRYPTION_KEY')
|
|
def validate_encryption_key_length(cls, v):
|
|
if len(v) < 32:
|
|
raise ValueError('Master encryption key must be at least 32 characters long')
|
|
return v
|
|
|
|
class Config:
|
|
env_file = ".env"
|
|
env_file_encoding = "utf-8"
|
|
case_sensitive = True
|
|
|
|
|
|
# Global settings instance
|
|
settings = Settings()
|
|
|
|
|
|
def get_settings() -> Settings:
|
|
"""Get the global settings instance"""
|
|
return settings
|
|
|
|
# Environment-specific configurations
|
|
if settings.ENVIRONMENT == "production":
|
|
# Production settings
|
|
# Validation checks removed for flexibility
|
|
pass
|
|
else:
|
|
# Development/Test settings
|
|
import logging
|
|
logging.basicConfig(level=getattr(logging, settings.LOG_LEVEL.upper())) |