fix: address PR #1 security review — drop platform seeds, seal db passwords

- Remove managed connection seeding: platform-postgres/dragonfly carried
  the backend's own DATABASE_URL/DRAGONFLY_URL into tenant projects where
  any member could run arbitrary DBX queries against core tables
  (Codex P1). NewPlatformService loses the seeds param; firstPartyDBSeeds
  deleted.
- Seal db_connections passwords with the existing AES-256-GCM encryptor
  (enc:v1:<b64> marker); decrypted only in dbxArgsFor. Legacy plaintext
  values still read, but migration 00008 strips them (Codex P1).
- Migration 00008: delete is_managed rows, drop plaintext password keys.
- dbxConnectionName uses the full project UUID — the 8-hex prefix could
  collide and alias another project's credentials (Codex P2).
- ci.yml triggers on master, not the nonexistent main/develop branches.
- demo-mode stubs renamed to user-managed connections; CHANGELOG notes
  under Unreleased.

Authored By: TDvorak <[email protected]>

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-17 20:39:31 +02:00
1 parent 55edbf8b56
commit fffac52295
7 files changed
+85 -95

No files matched your search

+1 -35
View File
@@ -6,11 +6,8 @@ import (
"fmt"
"log/slog"
"net/http"
"net/url"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"time"
@@ -94,7 +91,7 @@ func Bootstrap(ctx context.Context) (*App, error) {
if err != nil {
return nil, fmt.Errorf("encryption key: %w", err)
}
platform := services.NewPlatformService(repo, store, services.NewMailer(cfg), os.Getenv("VITE_APP_URL"), dbxClient, firstPartyDBSeeds(cfg), encryptor, logger)
platform := services.NewPlatformService(repo, store, services.NewMailer(cfg), os.Getenv("VITE_APP_URL"), dbxClient, encryptor, logger)
if cfg.Env == "production" {
gin.SetMode(gin.ReleaseMode)
@@ -212,37 +209,6 @@ func (a *App) Run() error {
return nil
}
// firstPartyDBSeeds turns the platform's own Postgres and Dragonfly URLs into
// managed connection seeds registered on every project.
func firstPartyDBSeeds(cfg config.Config) []services.ManagedDBSeed {
var seeds []services.ManagedDBSeed
if u, err := url.Parse(cfg.DatabaseURL); err == nil && u.Hostname() != "" {
cfg2 := services.DBConnectionConfig{
Host: u.Hostname(),
Database: strings.TrimPrefix(u.Path, "/"),
Username: u.User.Username(),
}
if p, ok := u.User.Password(); ok {
cfg2.Password = p
}
if port, err := strconv.Atoi(u.Port()); err == nil {
cfg2.Port = &port
}
seeds = append(seeds, services.ManagedDBSeed{Name: "platform-postgres", DBType: "postgres", Config: cfg2})
}
if u, err := url.Parse(cfg.DragonflyURL); err == nil && u.Hostname() != "" {
cfg2 := services.DBConnectionConfig{Host: u.Hostname()}
if p, ok := u.User.Password(); ok {
cfg2.Password = p
}
if port, err := strconv.Atoi(u.Port()); err == nil {
cfg2.Port = &port
}
seeds = append(seeds, services.ManagedDBSeed{Name: "platform-dragonfly", DBType: "redis", Config: cfg2})
}
return seeds
}
func (a *App) Close() error {
if a.sweepCancel != nil {
a.sweepCancel()