-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ability to Use Postgres as a Backing Store for VSecM Safe (#1165)
Maintains feature parity with the former version. Unit and integration tests pass. I'm merging this. Will do follow-up PRs to address `TODO:` comments in the code, and also clean-up the code. --- * wip * add polling to main to test config setting for safe itself * temporarily disable relay client * testing persistence to postgres * SQL statement change * lastworking * add entity.go * mostly-working version * fixed store response * add guard clauses * more debugging * exception for initial persistence to db * changes
- Loading branch information
Showing
21 changed files
with
365 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
| Protect your secrets, protect your sensitive data. | ||
: Explore VMware Secrets Manager docs at https://vsecm.com/ | ||
</ | ||
<>/ keep your secrets... secret | ||
>/ | ||
<>/' Copyright 2023-present VMware Secrets Manager contributors. | ||
>/' SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
package main | ||
|
||
// TODO: obviously there is a need for cleanup; once things start to work | ||
// as expected, move the codes to where they should belong. | ||
|
||
// TODO: move me to a proper place. | ||
|
||
// TODO: by design, VSecM Safe will not use more than one backing store | ||
// (create an ADR for that). | ||
// This means, there is a chicken-and-the-egg problem for persisting the | ||
// internal VSecM Safe configuration. | ||
// | ||
// For postgres backing store, VSecM Safe should keep its initial config | ||
// in memory until the database is there; and then it should save it to | ||
// the database, too. | ||
|
||
// TODO: we should check for the existence of the table in postgres and | ||
// log an error if it's not there. | ||
|
||
// TODO: when postgres mode vsecm safe shall be read-only (except for config update) | ||
// until it is initialized. once initialized, it should save its config to postgres too | ||
// and then it should be readwrite. | ||
|
||
// TODO: we need documentation for this postgres store feature. (and also a demo recording) | ||
|
||
// TODO: it's best block requests when the db is not ready yet (in postgres mode) | ||
// because otherwise, the initCommand will retry in exponential backoff and | ||
// eventually give up. | ||
// or the keystone secret will not be persisted although keystone will | ||
// be informed that safe is ready. | ||
|
||
type SafeConfig struct { | ||
Config struct { | ||
BackingStore string `json:"backingStore"` | ||
DataSourceName string `json:"dataSourceName"` | ||
} `json:"config"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package io | ||
|
||
import ( | ||
"database/sql" | ||
"encoding/base64" | ||
"encoding/json" | ||
"errors" | ||
|
||
_ "github.com/lib/pq" | ||
|
||
"github.com/vmware-tanzu/secrets-manager/core/crypto" | ||
entity "github.com/vmware-tanzu/secrets-manager/core/entity/v1/data" | ||
"github.com/vmware-tanzu/secrets-manager/core/env" | ||
log "github.com/vmware-tanzu/secrets-manager/core/log/std" | ||
"github.com/vmware-tanzu/secrets-manager/lib/backoff" | ||
) | ||
|
||
var db *sql.DB | ||
|
||
// InitDB initializes the database connection | ||
func InitDB(dataSourceName string) error { | ||
var err error | ||
db, err = sql.Open("postgres", dataSourceName) | ||
if err != nil { | ||
return err | ||
} | ||
return db.Ping() | ||
} | ||
|
||
// PersistToPostgres saves a given secret to the Postgres database | ||
func PersistToPostgres(secret entity.SecretStored, errChan chan<- error) { | ||
cid := secret.Meta.CorrelationId | ||
|
||
log.TraceLn(&cid, "PersistToPostgres: Persisting secret to database") | ||
|
||
// Serialize the secret to JSON | ||
jsonData, err := json.Marshal(secret) | ||
if err != nil { | ||
errChan <- errors.Join(err, errors.New("PersistToPostgres: Failed to marshal secret")) | ||
log.ErrorLn(&cid, "PersistToPostgres: Error marshaling secret:", err.Error()) | ||
return | ||
} | ||
|
||
// Encrypt the JSON data | ||
var encryptedData string | ||
fipsMode := env.FipsCompliantModeForSafe() | ||
|
||
if fipsMode { | ||
encryptedBytes, err := crypto.EncryptBytesAes(jsonData) | ||
if err != nil { | ||
errChan <- errors.Join(err, errors.New("PersistToPostgres: Failed to encrypt secret with AES")) | ||
log.ErrorLn(&cid, "PersistToPostgres: Error encrypting secret with AES:", err.Error()) | ||
return | ||
} | ||
encryptedData = base64.StdEncoding.EncodeToString(encryptedBytes) | ||
} else { | ||
encryptedBytes, err := crypto.EncryptBytesAge(jsonData) | ||
if err != nil { | ||
errChan <- errors.Join(err, errors.New("PersistToPostgres: Failed to encrypt secret with Age")) | ||
log.ErrorLn(&cid, "PersistToPostgres: Error encrypting secret with Age:", err.Error()) | ||
return | ||
} | ||
encryptedData = base64.StdEncoding.EncodeToString(encryptedBytes) | ||
} | ||
|
||
err = backoff.RetryExponential("PersistToPostgres", func() error { | ||
if db == nil { | ||
if secret.Name == "vsecm-safe" { | ||
// TODO: implement me. | ||
log.InfoLn(&cid, "PersistToPostgres: vsecm-safe secret will be persisted after db connection is initialized") | ||
return nil | ||
} | ||
return errors.New("PersistToPostgres: Database connection is nil") | ||
} | ||
|
||
// TODO: get table name from env var. | ||
_, err := db.Exec( | ||
`INSERT INTO "vsecm-secrets" (name, data) VALUES ($1, $2) ON CONFLICT (name) DO UPDATE SET data = $2`, | ||
secret.Name, encryptedData) | ||
return err | ||
}) | ||
|
||
if err != nil { | ||
errChan <- errors.Join(err, errors.New("PersistToPostgres: Failed to persist secret to database")) | ||
log.ErrorLn(&cid, "PersistToPostgres: Error persisting secret to database:", err.Error()) | ||
return | ||
} | ||
|
||
log.TraceLn(&cid, "PersistToPostgres: Secret persisted to database successfully") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.