diff --git a/cmd/server/main.go b/cmd/server/main.go deleted file mode 100644 index 0d9bbfe..0000000 --- a/cmd/server/main.go +++ /dev/null @@ -1,337 +0,0 @@ -package main - -import ( - "context" - "log" - "net/http" - "os" - "os/signal" - "syscall" - "time" - - "github.com/gin-gonic/gin" - "go.uber.org/zap" - - "github.com/kms/api-key-service/internal/audit" - "github.com/kms/api-key-service/internal/config" - "github.com/kms/api-key-service/internal/database" - "github.com/kms/api-key-service/internal/domain" - "github.com/kms/api-key-service/internal/handlers" - "github.com/kms/api-key-service/internal/metrics" - "github.com/kms/api-key-service/internal/middleware" - "github.com/kms/api-key-service/internal/repository/postgres" - "github.com/kms/api-key-service/internal/services" -) - -func main() { - // Initialize configuration - cfg := config.NewConfig() - if err := cfg.Validate(); err != nil { - log.Fatal("Configuration validation failed:", err) - } - - // Initialize logger - logger := initLogger(cfg) - defer logger.Sync() - - logger.Info("Starting API Key Management Service", - zap.String("version", cfg.GetString("APP_VERSION")), - zap.String("environment", cfg.GetString("APP_ENV")), - ) - - // Initialize database - logger.Info("Connecting to database", - zap.String("dsn", cfg.GetDatabaseDSNForLogging())) - - db, err := database.NewPostgresProvider( - cfg.GetDatabaseDSN(), - cfg.GetInt("DB_MAX_OPEN_CONNS"), - cfg.GetInt("DB_MAX_IDLE_CONNS"), - cfg.GetString("DB_CONN_MAX_LIFETIME"), - ) - if err != nil { - logger.Fatal("Failed to initialize database", - zap.String("dsn", cfg.GetDatabaseDSNForLogging()), - zap.Error(err)) - } - - logger.Info("Database connection established successfully") - - // Database migrations are handled by PostgreSQL docker-entrypoint-initdb.d - logger.Info("Database migrations are handled by PostgreSQL on container startup") - - // Initialize repositories - appRepo := postgres.NewApplicationRepository(db) - tokenRepo := postgres.NewStaticTokenRepository(db) - permRepo := postgres.NewPermissionRepository(db) - grantRepo := postgres.NewGrantedPermissionRepository(db) - auditRepo := postgres.NewAuditRepository(db) - - // Initialize audit logger - auditLogger := audit.NewAuditLogger(cfg, logger, auditRepo) - - // Initialize services - appService := services.NewApplicationService(appRepo, auditRepo, logger) - tokenService := services.NewTokenService(tokenRepo, appRepo, permRepo, grantRepo, cfg.GetString("INTERNAL_HMAC_KEY"), cfg, logger) - authService := services.NewAuthenticationService(cfg, logger, permRepo) - - // Initialize handlers - healthHandler := handlers.NewHealthHandler(db, logger) - appHandler := handlers.NewApplicationHandler(appService, authService, logger) - tokenHandler := handlers.NewTokenHandler(tokenService, authService, logger) - authHandler := handlers.NewAuthHandler(authService, tokenService, cfg, logger) - auditHandler := handlers.NewAuditHandler(auditLogger, authService, logger) - - // Set up router - router := setupRouter(cfg, logger, healthHandler, appHandler, tokenHandler, authHandler, auditHandler) - - // Create HTTP server - srv := &http.Server{ - Addr: cfg.GetServerAddress(), - Handler: router, - ReadTimeout: cfg.GetDuration("SERVER_READ_TIMEOUT"), - WriteTimeout: cfg.GetDuration("SERVER_WRITE_TIMEOUT"), - IdleTimeout: cfg.GetDuration("SERVER_IDLE_TIMEOUT"), - } - - // Initialize bootstrap data - logger.Info("Initializing bootstrap data") - if err := initializeBootstrapData(context.Background(), appService, tokenService, cfg, logger); err != nil { - logger.Fatal("Failed to initialize bootstrap data", zap.Error(err)) - } - - // Start server in goroutine - go func() { - logger.Info("Starting HTTP server", zap.String("address", srv.Addr)) - if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { - logger.Fatal("Failed to start server", zap.Error(err)) - } - }() - - // Start metrics server if enabled - var metricsSrv *http.Server - if cfg.GetBool("METRICS_ENABLED") { - metricsSrv = startMetricsServer(cfg, logger) - } - - // Wait for interrupt signal to gracefully shutdown the server - quit := make(chan os.Signal, 1) - signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) - <-quit - - logger.Info("Shutting down server...") - - // Give outstanding requests time to complete - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - - // Shutdown main server - if err := srv.Shutdown(ctx); err != nil { - logger.Error("Server forced to shutdown", zap.Error(err)) - } - - // Shutdown metrics server - if metricsSrv != nil { - if err := metricsSrv.Shutdown(ctx); err != nil { - logger.Error("Metrics server forced to shutdown", zap.Error(err)) - } - } - - logger.Info("Server exited") -} - -func initLogger(cfg config.ConfigProvider) *zap.Logger { - var logger *zap.Logger - var err error - - if cfg.IsProduction() { - logger, err = zap.NewProduction() - } else { - logger, err = zap.NewDevelopment() - } - - if err != nil { - log.Fatal("Failed to initialize logger:", err) - } - - return logger -} - -func setupRouter(cfg config.ConfigProvider, logger *zap.Logger, healthHandler *handlers.HealthHandler, appHandler *handlers.ApplicationHandler, tokenHandler *handlers.TokenHandler, authHandler *handlers.AuthHandler, auditHandler *handlers.AuditHandler) *gin.Engine { - // Set Gin mode based on environment - if cfg.IsProduction() { - gin.SetMode(gin.ReleaseMode) - } - - router := gin.New() - - // Add middleware - router.Use(middleware.Logger(logger)) - router.Use(middleware.Recovery(logger)) - router.Use(metrics.Middleware(logger)) - router.Use(middleware.CORS()) - router.Use(middleware.Security()) - router.Use(middleware.ValidateContentType()) - - if cfg.GetBool("RATE_LIMIT_ENABLED") { - router.Use(middleware.RateLimit(cfg.GetInt("RATE_LIMIT_RPS"), cfg.GetInt("RATE_LIMIT_BURST"))) - } - - // Health check endpoint (no authentication required) - router.GET("/health", healthHandler.Health) - router.GET("/ready", healthHandler.Ready) - - // API routes - api := router.Group("/api") - { - // Authentication endpoints (no prior auth required) - api.GET("/login", authHandler.Login) // HTML page for browser access - api.POST("/login", authHandler.Login) // JSON API for programmatic access - api.POST("/verify", authHandler.Verify) - api.POST("/renew", authHandler.Renew) - - // Protected routes (require authentication) - protected := api.Group("/") - protected.Use(middleware.Authentication(cfg, logger)) - { - // Application management - protected.GET("/applications", appHandler.List) - protected.POST("/applications", appHandler.Create) - protected.GET("/applications/:id", appHandler.GetByID) - protected.PUT("/applications/:id", appHandler.Update) - protected.DELETE("/applications/:id", appHandler.Delete) - - // Token management - protected.GET("/applications/:id/tokens", tokenHandler.ListByApp) - protected.POST("/applications/:id/tokens", tokenHandler.Create) - protected.DELETE("/tokens/:id", tokenHandler.Delete) - - // Audit management - protected.GET("/audit/events", auditHandler.ListEvents) - protected.GET("/audit/events/:id", auditHandler.GetEvent) - protected.GET("/audit/stats", auditHandler.GetStats) - - // Documentation endpoint - protected.GET("/docs", func(c *gin.Context) { - c.JSON(http.StatusOK, gin.H{ - "service": "API Key Management Service", - "version": cfg.GetString("APP_VERSION"), - "documentation": "See README.md and docs/ directory", - "endpoints": map[string]interface{}{ - "authentication": []string{ - "POST /api/login", - "POST /api/verify", - "POST /api/renew", - }, - "applications": []string{ - "GET /api/applications", - "POST /api/applications", - "GET /api/applications/:id", - "PUT /api/applications/:id", - "DELETE /api/applications/:id", - }, - "tokens": []string{ - "GET /api/applications/:id/tokens", - "POST /api/applications/:id/tokens", - "DELETE /api/tokens/:id", - }, - "audit": []string{ - "GET /api/audit/events", - "GET /api/audit/events/:id", - "GET /api/audit/stats", - }, - }, - }) - }) - } - } - - return router -} - -func startMetricsServer(cfg config.ConfigProvider, logger *zap.Logger) *http.Server { - mux := http.NewServeMux() - - // Prometheus metrics endpoint - mux.HandleFunc("/metrics", metrics.PrometheusHandler()) - - // Health endpoint for metrics server - mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - w.Write([]byte("OK")) - }) - - srv := &http.Server{ - Addr: cfg.GetMetricsAddress(), - Handler: mux, - } - - go func() { - logger.Info("Starting metrics server", zap.String("address", srv.Addr)) - if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { - logger.Error("Failed to start metrics server", zap.Error(err)) - } - }() - - return srv -} - -func initializeBootstrapData(ctx context.Context, appService services.ApplicationService, tokenService services.TokenService, cfg config.ConfigProvider, logger *zap.Logger) error { - // Check if internal application already exists - internalAppID := cfg.GetString("INTERNAL_APP_ID") - _, err := appService.GetByID(ctx, internalAppID) - if err == nil { - logger.Info("Internal application already exists, skipping bootstrap") - return nil - } - - logger.Info("Creating internal application for bootstrap", zap.String("app_id", internalAppID)) - - // Create internal application for system operations - internalAppReq := &domain.CreateApplicationRequest{ - AppID: internalAppID, - AppLink: "https://kms.internal/system", - Type: []domain.ApplicationType{domain.ApplicationTypeStatic, domain.ApplicationTypeUser}, - CallbackURL: "https://kms.internal/callback", - TokenPrefix: "KMS", - TokenRenewalDuration: domain.Duration{Duration: 365 * 24 * time.Hour}, // 1 year - MaxTokenDuration: domain.Duration{Duration: 365 * 24 * time.Hour}, // 1 year - Owner: domain.Owner{ - Type: domain.OwnerTypeTeam, - Name: "KMS System", - Owner: "system@kms.internal", - }, - } - - app, err := appService.Create(ctx, internalAppReq, "system") - if err != nil { - logger.Error("Failed to create internal application", zap.Error(err)) - return err - } - - logger.Info("Internal application created successfully", - zap.String("app_id", app.AppID), - zap.String("hmac_key", app.HMACKey)) - - // Create a static token for internal system operations if needed - internalTokenReq := &domain.CreateStaticTokenRequest{ - AppID: internalAppID, - Owner: domain.Owner{ - Type: domain.OwnerTypeTeam, - Name: "KMS System Token", - Owner: "system@kms.internal", - }, - Permissions: []string{"internal.*", "app.*", "token.*", "audit.*"}, - } - - token, err := tokenService.CreateStaticToken(ctx, internalTokenReq, "system") - if err != nil { - logger.Warn("Failed to create internal system token, continuing...", zap.Error(err)) - } else { - logger.Info("Internal system token created successfully", - zap.String("token_id", token.ID.String())) - } - - logger.Info("Bootstrap data initialization completed successfully") - return nil -} diff --git a/.gitignore b/kms/.gitignore similarity index 100% rename from .gitignore rename to kms/.gitignore diff --git a/CLAUDE.md b/kms/CLAUDE.md similarity index 100% rename from CLAUDE.md rename to kms/CLAUDE.md diff --git a/Dockerfile b/kms/Dockerfile similarity index 100% rename from Dockerfile rename to kms/Dockerfile diff --git a/README.md b/kms/README.md similarity index 100% rename from README.md rename to kms/README.md diff --git a/docker-compose.yml b/kms/docker-compose.yml similarity index 100% rename from docker-compose.yml rename to kms/docker-compose.yml diff --git a/docs/API.md b/kms/docs/API.md similarity index 100% rename from docs/API.md rename to kms/docs/API.md diff --git a/docs/ARCHITECTURE.md b/kms/docs/ARCHITECTURE.md similarity index 100% rename from docs/ARCHITECTURE.md rename to kms/docs/ARCHITECTURE.md diff --git a/docs/DEPLOYMENT_GUIDE.md b/kms/docs/DEPLOYMENT_GUIDE.md similarity index 100% rename from docs/DEPLOYMENT_GUIDE.md rename to kms/docs/DEPLOYMENT_GUIDE.md diff --git a/docs/PRODUCTION_ROADMAP.md b/kms/docs/PRODUCTION_ROADMAP.md similarity index 100% rename from docs/PRODUCTION_ROADMAP.md rename to kms/docs/PRODUCTION_ROADMAP.md diff --git a/docs/SECURITY_ARCHITECTURE.md b/kms/docs/SECURITY_ARCHITECTURE.md similarity index 100% rename from docs/SECURITY_ARCHITECTURE.md rename to kms/docs/SECURITY_ARCHITECTURE.md diff --git a/docs/SYSTEM_IMPLEMENTATION_GUIDE.md b/kms/docs/SYSTEM_IMPLEMENTATION_GUIDE.md similarity index 100% rename from docs/SYSTEM_IMPLEMENTATION_GUIDE.md rename to kms/docs/SYSTEM_IMPLEMENTATION_GUIDE.md diff --git a/go.mod b/kms/go.mod similarity index 100% rename from go.mod rename to kms/go.mod diff --git a/go.sum b/kms/go.sum similarity index 100% rename from go.sum rename to kms/go.sum diff --git a/internal/audit/audit.go b/kms/internal/audit/audit.go similarity index 100% rename from internal/audit/audit.go rename to kms/internal/audit/audit.go diff --git a/internal/auth/header_validator.go b/kms/internal/auth/header_validator.go similarity index 100% rename from internal/auth/header_validator.go rename to kms/internal/auth/header_validator.go diff --git a/internal/auth/jwt.go b/kms/internal/auth/jwt.go similarity index 100% rename from internal/auth/jwt.go rename to kms/internal/auth/jwt.go diff --git a/internal/auth/oauth2.go b/kms/internal/auth/oauth2.go similarity index 100% rename from internal/auth/oauth2.go rename to kms/internal/auth/oauth2.go diff --git a/internal/auth/permissions.go b/kms/internal/auth/permissions.go similarity index 100% rename from internal/auth/permissions.go rename to kms/internal/auth/permissions.go diff --git a/internal/auth/saml.go b/kms/internal/auth/saml.go similarity index 100% rename from internal/auth/saml.go rename to kms/internal/auth/saml.go diff --git a/internal/authorization/rbac.go b/kms/internal/authorization/rbac.go similarity index 100% rename from internal/authorization/rbac.go rename to kms/internal/authorization/rbac.go diff --git a/internal/cache/cache.go b/kms/internal/cache/cache.go similarity index 100% rename from internal/cache/cache.go rename to kms/internal/cache/cache.go diff --git a/internal/cache/redis.go b/kms/internal/cache/redis.go similarity index 100% rename from internal/cache/redis.go rename to kms/internal/cache/redis.go diff --git a/internal/config/config.go b/kms/internal/config/config.go similarity index 100% rename from internal/config/config.go rename to kms/internal/config/config.go diff --git a/internal/crypto/token.go b/kms/internal/crypto/token.go similarity index 100% rename from internal/crypto/token.go rename to kms/internal/crypto/token.go diff --git a/internal/database/postgres.go b/kms/internal/database/postgres.go similarity index 100% rename from internal/database/postgres.go rename to kms/internal/database/postgres.go diff --git a/internal/domain/duration.go b/kms/internal/domain/duration.go similarity index 100% rename from internal/domain/duration.go rename to kms/internal/domain/duration.go diff --git a/internal/domain/models.go b/kms/internal/domain/models.go similarity index 100% rename from internal/domain/models.go rename to kms/internal/domain/models.go diff --git a/internal/domain/session.go b/kms/internal/domain/session.go similarity index 100% rename from internal/domain/session.go rename to kms/internal/domain/session.go diff --git a/internal/domain/tenant.go b/kms/internal/domain/tenant.go similarity index 100% rename from internal/domain/tenant.go rename to kms/internal/domain/tenant.go diff --git a/internal/errors/errors.go b/kms/internal/errors/errors.go similarity index 100% rename from internal/errors/errors.go rename to kms/internal/errors/errors.go diff --git a/internal/errors/secure_responses.go b/kms/internal/errors/secure_responses.go similarity index 100% rename from internal/errors/secure_responses.go rename to kms/internal/errors/secure_responses.go diff --git a/internal/handlers/application.go b/kms/internal/handlers/application.go similarity index 100% rename from internal/handlers/application.go rename to kms/internal/handlers/application.go diff --git a/internal/handlers/audit.go b/kms/internal/handlers/audit.go similarity index 100% rename from internal/handlers/audit.go rename to kms/internal/handlers/audit.go diff --git a/internal/handlers/auth.go b/kms/internal/handlers/auth.go similarity index 100% rename from internal/handlers/auth.go rename to kms/internal/handlers/auth.go diff --git a/internal/handlers/health.go b/kms/internal/handlers/health.go similarity index 100% rename from internal/handlers/health.go rename to kms/internal/handlers/health.go diff --git a/internal/handlers/oauth2.go b/kms/internal/handlers/oauth2.go similarity index 100% rename from internal/handlers/oauth2.go rename to kms/internal/handlers/oauth2.go diff --git a/internal/handlers/saml.go b/kms/internal/handlers/saml.go similarity index 100% rename from internal/handlers/saml.go rename to kms/internal/handlers/saml.go diff --git a/internal/handlers/token.go b/kms/internal/handlers/token.go similarity index 100% rename from internal/handlers/token.go rename to kms/internal/handlers/token.go diff --git a/internal/metrics/metrics.go b/kms/internal/metrics/metrics.go similarity index 100% rename from internal/metrics/metrics.go rename to kms/internal/metrics/metrics.go diff --git a/internal/middleware/csrf.go b/kms/internal/middleware/csrf.go similarity index 100% rename from internal/middleware/csrf.go rename to kms/internal/middleware/csrf.go diff --git a/internal/middleware/logger.go b/kms/internal/middleware/logger.go similarity index 100% rename from internal/middleware/logger.go rename to kms/internal/middleware/logger.go diff --git a/internal/middleware/middleware.go b/kms/internal/middleware/middleware.go similarity index 100% rename from internal/middleware/middleware.go rename to kms/internal/middleware/middleware.go diff --git a/internal/middleware/security.go b/kms/internal/middleware/security.go similarity index 100% rename from internal/middleware/security.go rename to kms/internal/middleware/security.go diff --git a/internal/middleware/validation.go b/kms/internal/middleware/validation.go similarity index 100% rename from internal/middleware/validation.go rename to kms/internal/middleware/validation.go diff --git a/internal/repository/interfaces.go b/kms/internal/repository/interfaces.go similarity index 100% rename from internal/repository/interfaces.go rename to kms/internal/repository/interfaces.go diff --git a/internal/repository/postgres/application_repository.go b/kms/internal/repository/postgres/application_repository.go similarity index 100% rename from internal/repository/postgres/application_repository.go rename to kms/internal/repository/postgres/application_repository.go diff --git a/internal/repository/postgres/audit_repository.go b/kms/internal/repository/postgres/audit_repository.go similarity index 100% rename from internal/repository/postgres/audit_repository.go rename to kms/internal/repository/postgres/audit_repository.go diff --git a/internal/repository/postgres/permission_repository.go b/kms/internal/repository/postgres/permission_repository.go similarity index 100% rename from internal/repository/postgres/permission_repository.go rename to kms/internal/repository/postgres/permission_repository.go diff --git a/internal/repository/postgres/session_repository.go b/kms/internal/repository/postgres/session_repository.go similarity index 100% rename from internal/repository/postgres/session_repository.go rename to kms/internal/repository/postgres/session_repository.go diff --git a/internal/repository/postgres/token_repository.go b/kms/internal/repository/postgres/token_repository.go similarity index 100% rename from internal/repository/postgres/token_repository.go rename to kms/internal/repository/postgres/token_repository.go diff --git a/internal/services/application_service.go b/kms/internal/services/application_service.go similarity index 100% rename from internal/services/application_service.go rename to kms/internal/services/application_service.go diff --git a/internal/services/auth_service.go b/kms/internal/services/auth_service.go similarity index 100% rename from internal/services/auth_service.go rename to kms/internal/services/auth_service.go diff --git a/internal/services/interfaces.go b/kms/internal/services/interfaces.go similarity index 100% rename from internal/services/interfaces.go rename to kms/internal/services/interfaces.go diff --git a/internal/services/session_service.go b/kms/internal/services/session_service.go similarity index 100% rename from internal/services/session_service.go rename to kms/internal/services/session_service.go diff --git a/internal/services/token_service.go b/kms/internal/services/token_service.go similarity index 100% rename from internal/services/token_service.go rename to kms/internal/services/token_service.go diff --git a/internal/validation/validator.go b/kms/internal/validation/validator.go similarity index 100% rename from internal/validation/validator.go rename to kms/internal/validation/validator.go diff --git a/kms-frontend/.env b/kms/kms-frontend/.env similarity index 100% rename from kms-frontend/.env rename to kms/kms-frontend/.env diff --git a/kms-frontend/.gitignore b/kms/kms-frontend/.gitignore similarity index 100% rename from kms-frontend/.gitignore rename to kms/kms-frontend/.gitignore diff --git a/kms-frontend/Dockerfile b/kms/kms-frontend/Dockerfile similarity index 100% rename from kms-frontend/Dockerfile rename to kms/kms-frontend/Dockerfile diff --git a/kms-frontend/README.md b/kms/kms-frontend/README.md similarity index 100% rename from kms-frontend/README.md rename to kms/kms-frontend/README.md diff --git a/kms-frontend/nginx.conf b/kms/kms-frontend/nginx.conf similarity index 100% rename from kms-frontend/nginx.conf rename to kms/kms-frontend/nginx.conf diff --git a/kms-frontend/package-lock.json b/kms/kms-frontend/package-lock.json similarity index 100% rename from kms-frontend/package-lock.json rename to kms/kms-frontend/package-lock.json diff --git a/kms-frontend/package.json b/kms/kms-frontend/package.json similarity index 100% rename from kms-frontend/package.json rename to kms/kms-frontend/package.json diff --git a/kms-frontend/public/favicon.ico b/kms/kms-frontend/public/favicon.ico similarity index 100% rename from kms-frontend/public/favicon.ico rename to kms/kms-frontend/public/favicon.ico diff --git a/kms-frontend/public/index.html b/kms/kms-frontend/public/index.html similarity index 100% rename from kms-frontend/public/index.html rename to kms/kms-frontend/public/index.html diff --git a/kms-frontend/public/logo192.png b/kms/kms-frontend/public/logo192.png similarity index 100% rename from kms-frontend/public/logo192.png rename to kms/kms-frontend/public/logo192.png diff --git a/kms-frontend/public/logo512.png b/kms/kms-frontend/public/logo512.png similarity index 100% rename from kms-frontend/public/logo512.png rename to kms/kms-frontend/public/logo512.png diff --git a/kms-frontend/public/manifest.json b/kms/kms-frontend/public/manifest.json similarity index 100% rename from kms-frontend/public/manifest.json rename to kms/kms-frontend/public/manifest.json diff --git a/kms-frontend/public/robots.txt b/kms/kms-frontend/public/robots.txt similarity index 100% rename from kms-frontend/public/robots.txt rename to kms/kms-frontend/public/robots.txt diff --git a/kms-frontend/src/App.css b/kms/kms-frontend/src/App.css similarity index 100% rename from kms-frontend/src/App.css rename to kms/kms-frontend/src/App.css diff --git a/kms-frontend/src/App.test.tsx b/kms/kms-frontend/src/App.test.tsx similarity index 100% rename from kms-frontend/src/App.test.tsx rename to kms/kms-frontend/src/App.test.tsx diff --git a/kms-frontend/src/App.tsx b/kms/kms-frontend/src/App.tsx similarity index 100% rename from kms-frontend/src/App.tsx rename to kms/kms-frontend/src/App.tsx diff --git a/kms-frontend/src/components/Applications.tsx b/kms/kms-frontend/src/components/Applications.tsx similarity index 100% rename from kms-frontend/src/components/Applications.tsx rename to kms/kms-frontend/src/components/Applications.tsx diff --git a/kms-frontend/src/components/Audit.tsx b/kms/kms-frontend/src/components/Audit.tsx similarity index 100% rename from kms-frontend/src/components/Audit.tsx rename to kms/kms-frontend/src/components/Audit.tsx diff --git a/kms-frontend/src/components/Dashboard.tsx b/kms/kms-frontend/src/components/Dashboard.tsx similarity index 100% rename from kms-frontend/src/components/Dashboard.tsx rename to kms/kms-frontend/src/components/Dashboard.tsx diff --git a/kms-frontend/src/components/Login.tsx b/kms/kms-frontend/src/components/Login.tsx similarity index 100% rename from kms-frontend/src/components/Login.tsx rename to kms/kms-frontend/src/components/Login.tsx diff --git a/kms-frontend/src/components/TokenTester.tsx b/kms/kms-frontend/src/components/TokenTester.tsx similarity index 100% rename from kms-frontend/src/components/TokenTester.tsx rename to kms/kms-frontend/src/components/TokenTester.tsx diff --git a/kms-frontend/src/components/TokenTesterCallback.tsx b/kms/kms-frontend/src/components/TokenTesterCallback.tsx similarity index 100% rename from kms-frontend/src/components/TokenTesterCallback.tsx rename to kms/kms-frontend/src/components/TokenTesterCallback.tsx diff --git a/kms-frontend/src/components/Tokens.tsx b/kms/kms-frontend/src/components/Tokens.tsx similarity index 100% rename from kms-frontend/src/components/Tokens.tsx rename to kms/kms-frontend/src/components/Tokens.tsx diff --git a/kms-frontend/src/components/Users.tsx b/kms/kms-frontend/src/components/Users.tsx similarity index 100% rename from kms-frontend/src/components/Users.tsx rename to kms/kms-frontend/src/components/Users.tsx diff --git a/kms-frontend/src/contexts/AuthContext.tsx b/kms/kms-frontend/src/contexts/AuthContext.tsx similarity index 100% rename from kms-frontend/src/contexts/AuthContext.tsx rename to kms/kms-frontend/src/contexts/AuthContext.tsx diff --git a/kms-frontend/src/index.css b/kms/kms-frontend/src/index.css similarity index 100% rename from kms-frontend/src/index.css rename to kms/kms-frontend/src/index.css diff --git a/kms-frontend/src/index.tsx b/kms/kms-frontend/src/index.tsx similarity index 100% rename from kms-frontend/src/index.tsx rename to kms/kms-frontend/src/index.tsx diff --git a/kms-frontend/src/logo.svg b/kms/kms-frontend/src/logo.svg similarity index 100% rename from kms-frontend/src/logo.svg rename to kms/kms-frontend/src/logo.svg diff --git a/kms-frontend/src/react-app-env.d.ts b/kms/kms-frontend/src/react-app-env.d.ts similarity index 100% rename from kms-frontend/src/react-app-env.d.ts rename to kms/kms-frontend/src/react-app-env.d.ts diff --git a/kms-frontend/src/reportWebVitals.ts b/kms/kms-frontend/src/reportWebVitals.ts similarity index 100% rename from kms-frontend/src/reportWebVitals.ts rename to kms/kms-frontend/src/reportWebVitals.ts diff --git a/kms-frontend/src/services/apiService.ts b/kms/kms-frontend/src/services/apiService.ts similarity index 100% rename from kms-frontend/src/services/apiService.ts rename to kms/kms-frontend/src/services/apiService.ts diff --git a/kms-frontend/src/setupTests.ts b/kms/kms-frontend/src/setupTests.ts similarity index 100% rename from kms-frontend/src/setupTests.ts rename to kms/kms-frontend/src/setupTests.ts diff --git a/kms-frontend/tsconfig.json b/kms/kms-frontend/tsconfig.json similarity index 100% rename from kms-frontend/tsconfig.json rename to kms/kms-frontend/tsconfig.json diff --git a/migrations/001_initial_schema.down.sql b/kms/migrations/001_initial_schema.down.sql similarity index 100% rename from migrations/001_initial_schema.down.sql rename to kms/migrations/001_initial_schema.down.sql diff --git a/migrations/001_initial_schema.up.sql b/kms/migrations/001_initial_schema.up.sql similarity index 100% rename from migrations/001_initial_schema.up.sql rename to kms/migrations/001_initial_schema.up.sql diff --git a/migrations/002_user_sessions.down.sql b/kms/migrations/002_user_sessions.down.sql similarity index 100% rename from migrations/002_user_sessions.down.sql rename to kms/migrations/002_user_sessions.down.sql diff --git a/migrations/002_user_sessions.up.sql b/kms/migrations/002_user_sessions.up.sql similarity index 100% rename from migrations/002_user_sessions.up.sql rename to kms/migrations/002_user_sessions.up.sql diff --git a/migrations/003_add_token_prefix.down.sql b/kms/migrations/003_add_token_prefix.down.sql similarity index 100% rename from migrations/003_add_token_prefix.down.sql rename to kms/migrations/003_add_token_prefix.down.sql diff --git a/migrations/003_add_token_prefix.up.sql b/kms/migrations/003_add_token_prefix.up.sql similarity index 100% rename from migrations/003_add_token_prefix.up.sql rename to kms/migrations/003_add_token_prefix.up.sql diff --git a/migrations/004_add_audit_events.down.sql b/kms/migrations/004_add_audit_events.down.sql similarity index 100% rename from migrations/004_add_audit_events.down.sql rename to kms/migrations/004_add_audit_events.down.sql diff --git a/migrations/004_add_audit_events.up.sql b/kms/migrations/004_add_audit_events.up.sql similarity index 100% rename from migrations/004_add_audit_events.up.sql rename to kms/migrations/004_add_audit_events.up.sql diff --git a/nginx/default.conf b/kms/nginx/default.conf similarity index 100% rename from nginx/default.conf rename to kms/nginx/default.conf diff --git a/nginx/nginx.conf b/kms/nginx/nginx.conf similarity index 100% rename from nginx/nginx.conf rename to kms/nginx/nginx.conf diff --git a/templates/login.html b/kms/templates/login.html similarity index 100% rename from templates/login.html rename to kms/templates/login.html diff --git a/test/README.md b/kms/test/README.md similarity index 100% rename from test/README.md rename to kms/test/README.md diff --git a/test/auth_test.go b/kms/test/auth_test.go similarity index 100% rename from test/auth_test.go rename to kms/test/auth_test.go diff --git a/test/cache_test.go b/kms/test/cache_test.go similarity index 100% rename from test/cache_test.go rename to kms/test/cache_test.go diff --git a/test/e2e_test.sh b/kms/test/e2e_test.sh similarity index 100% rename from test/e2e_test.sh rename to kms/test/e2e_test.sh diff --git a/test/integration_test.go b/kms/test/integration_test.go similarity index 100% rename from test/integration_test.go rename to kms/test/integration_test.go diff --git a/test/jwt_test.go b/kms/test/jwt_test.go similarity index 100% rename from test/jwt_test.go rename to kms/test/jwt_test.go diff --git a/test/mock_repositories.go b/kms/test/mock_repositories.go similarity index 100% rename from test/mock_repositories.go rename to kms/test/mock_repositories.go diff --git a/test/oauth2_test.go b/kms/test/oauth2_test.go similarity index 100% rename from test/oauth2_test.go rename to kms/test/oauth2_test.go diff --git a/test/permissions_test.go b/kms/test/permissions_test.go similarity index 100% rename from test/permissions_test.go rename to kms/test/permissions_test.go diff --git a/test/saml_test.go b/kms/test/saml_test.go similarity index 100% rename from test/saml_test.go rename to kms/test/saml_test.go diff --git a/test/test_helpers.go b/kms/test/test_helpers.go similarity index 100% rename from test/test_helpers.go rename to kms/test/test_helpers.go diff --git a/test/token_repository_test.go b/kms/test/token_repository_test.go similarity index 100% rename from test/token_repository_test.go rename to kms/test/token_repository_test.go