feat(05-03): implement lagoon.Encrypted, key:generate, Laravel decrypt helper

- AES-256-GCM with stdlib HKDF column keys and previous_keys fallback
- Fail-loud LoadAppKey, redacting marshal paths, key:generate via crypto/rand
- Standalone DecryptLaravelPayload unwired from Scan/Value
This commit is contained in:
Jakub Zych
2026-09-18 19:35:24 +02:00
parent 06bad37c24
commit 8d9109a771
8 changed files with 503 additions and 9 deletions

View File

@@ -80,11 +80,21 @@ func gormFromSQL(sqlDB *sql.DB) (*gorm.DB, error) {
}
// OpenFromApp reads database.dsn from app config and opens the shared pool.
// It also loads app.key via LoadAppKey and PublishEncryptionKeys so Encrypted
// columns do not re-read config on every row.
func OpenFromApp(ctx context.Context, app *backpack.App) (*sql.DB, *gorm.DB, error) {
if app == nil || app.Config == nil {
return nil, nil, fmt.Errorf("lagoon: app config is missing")
}
return Open(ctx, DSN(app.Config))
sqlDB, gdb, err := Open(ctx, DSN(app.Config))
if err != nil {
return nil, nil, err
}
if err := loadEncryptionKeysFromApp(app); err != nil {
_ = sqlDB.Close()
return nil, nil, err
}
return sqlDB, gdb, nil
}
// DSN returns database.dsn from layered config (env SUMMER_DATABASE__DSN).