From 4d050c91e36f744a9c9191003f7d88fac86af09d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20=C3=96z=C3=A7elik?= Date: Fri, 11 Oct 2024 20:07:38 -0700 Subject: [PATCH] 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 --- app/safe/cmd/entity.go | 47 ++++++++ app/safe/cmd/main.go | 52 +++++++++ .../server/route/base/extract/extract.go | 4 +- app/safe/internal/server/route/fetch/fetch.go | 2 +- app/safe/internal/state/io/disk.go | 4 + app/safe/internal/state/io/postgres.go | 90 +++++++++++++++ app/safe/internal/state/io/read.go | 5 + .../state/secret/collection/populate.go | 3 + .../internal/state/secret/collection/read.go | 11 ++ .../state/secret/queue/deletion/disk.go | 5 +- .../state/secret/queue/insertion/disk.go | 13 ++- core/constants/env/env.go | 2 + core/crypto/encrypt.go | 105 ++++++++++++++++++ core/entity/v1/data/store.go | 1 + core/env/store.go | 9 +- dockerfiles/vsecm-ist-fips/safe.Dockerfile | 2 +- dockerfiles/vsecm-ist/safe.Dockerfile | 2 +- go.mod | 1 + go.sum | 2 + helm-charts/0.27.4/charts/safe/values.yaml | 5 +- makefiles/VSecMBuild.mk | 22 ++-- 21 files changed, 365 insertions(+), 22 deletions(-) create mode 100644 app/safe/cmd/entity.go create mode 100644 app/safe/internal/state/io/postgres.go diff --git a/app/safe/cmd/entity.go b/app/safe/cmd/entity.go new file mode 100644 index 00000000..710f710c --- /dev/null +++ b/app/safe/cmd/entity.go @@ -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"` +} diff --git a/app/safe/cmd/main.go b/app/safe/cmd/main.go index 14af7f1a..62307217 100644 --- a/app/safe/cmd/main.go +++ b/app/safe/cmd/main.go @@ -12,18 +12,48 @@ package main import ( "context" + "encoding/json" + "time" "github.com/spiffe/go-spiffe/v2/workloadapi" "github.com/vmware-tanzu/secrets-manager/app/safe/internal/bootstrap" server "github.com/vmware-tanzu/secrets-manager/app/safe/internal/server/engine" + "github.com/vmware-tanzu/secrets-manager/app/safe/internal/state/io" + "github.com/vmware-tanzu/secrets-manager/app/safe/internal/state/secret/collection" "github.com/vmware-tanzu/secrets-manager/core/constants/env" "github.com/vmware-tanzu/secrets-manager/core/constants/key" "github.com/vmware-tanzu/secrets-manager/core/crypto" + entity "github.com/vmware-tanzu/secrets-manager/core/entity/v1/data" + cEnv "github.com/vmware-tanzu/secrets-manager/core/env" log "github.com/vmware-tanzu/secrets-manager/core/log/std" "github.com/vmware-tanzu/secrets-manager/core/probe" ) +func pollForConfig(ctx context.Context, id string) (*SafeConfig, error) { + for { + log.InfoLn(&id, "Polling for VSecM Safe internal configuration") + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + vSecMSafeInternalConfig, err := collection.ReadSecret(id, "vsecm-safe") + if err != nil { + log.InfoLn(&id, "Failed to load VSecM Safe internal configuration", err.Error()) + } else if vSecMSafeInternalConfig != nil && len(vSecMSafeInternalConfig.Values) > 0 { + var safeConfig SafeConfig + err := json.Unmarshal([]byte(vSecMSafeInternalConfig.Values[0]), &safeConfig) + if err != nil { + log.InfoLn(&id, "Failed to parse VSecM Safe internal configuration", err.Error()) + } else { + return &safeConfig, nil + } + } + time.Sleep(5 * time.Second) + } + } +} + func main() { id := crypto.Id() @@ -38,6 +68,28 @@ func main() { ) defer cancel() + if cEnv.BackingStoreForSafe() == entity.Postgres { + go func() { + log.InfoLn(&id, "Backing store is postgres.") + log.InfoLn(&id, "VSecM Safe will remain read-only until the internal configuration is loaded.") + + safeConfig, err := pollForConfig(ctx, id) + if err != nil { + log.FatalLn(&id, "Failed to retrieve VSecM Safe internal configuration", err.Error()) + } + + log.InfoLn(&id, "VSecM Safe internal configuration loaded. Initializing database.") + + err = io.InitDB(safeConfig.Config.DataSourceName) + if err != nil { + log.FatalLn(&id, "Failed to initialize database:", err) + return + } + + log.InfoLn(&id, "Database connection initialized.") + }() + } + log.InfoLn(&id, "Acquiring identity...") // Channel to notify when the bootstrap timeout has been reached. diff --git a/app/safe/internal/server/route/base/extract/extract.go b/app/safe/internal/server/route/base/extract/extract.go index e9b4c4e3..bd1498a1 100644 --- a/app/safe/internal/server/route/base/extract/extract.go +++ b/app/safe/internal/server/route/base/extract/extract.go @@ -19,7 +19,7 @@ import ( log "github.com/vmware-tanzu/secrets-manager/core/log/std" ) -// WorkloadIDAndParts extracts the workload identifier and its constituent parts +// WorkloadIdAndParts extracts the workload identifier and its constituent parts // from a SPIFFE ID string, based on a predefined prefix that is removed from // the SPIFFE ID. // @@ -32,7 +32,7 @@ import ( // which is essentially the first part of the SPIFFE ID after removing the // prefix. The second return value is a slice of strings representing all // parts of the SPIFFE ID after the prefix removal. -func WorkloadIDAndParts(spiffeid string) (string, []string) { +func WorkloadIdAndParts(spiffeid string) (string, []string) { re := env.NameRegExpForWorkload() if re == "" { return "", nil diff --git a/app/safe/internal/server/route/fetch/fetch.go b/app/safe/internal/server/route/fetch/fetch.go index 339468d0..701b0667 100644 --- a/app/safe/internal/server/route/fetch/fetch.go +++ b/app/safe/internal/server/route/fetch/fetch.go @@ -88,7 +88,7 @@ func Fetch( log.DebugLn(&cid, "Fetch: preparing request") - workloadId, parts := extract.WorkloadIDAndParts(spiffeid) + workloadId, parts := extract.WorkloadIdAndParts(spiffeid) if len(parts) == 0 { handle.BadPeerSvidResponse(cid, w, spiffeid, j) return diff --git a/app/safe/internal/state/io/disk.go b/app/safe/internal/state/io/disk.go index 541e8fc4..4bcc12a3 100644 --- a/app/safe/internal/state/io/disk.go +++ b/app/safe/internal/state/io/disk.go @@ -34,6 +34,10 @@ import ( // channel allows the function to operate asynchronously, notifying the // caller of any issues in the process of persisting the secret. func PersistToDisk(secret entity.SecretStored, errChan chan<- error) { + if env.BackingStoreForSafe() != entity.File { + panic("Attempted to save to disk when backing store is not file") + } + backupCount := env.SecretBackupCountForSafe() // Save the secret diff --git a/app/safe/internal/state/io/postgres.go b/app/safe/internal/state/io/postgres.go new file mode 100644 index 00000000..260eb66c --- /dev/null +++ b/app/safe/internal/state/io/postgres.go @@ -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") +} diff --git a/app/safe/internal/state/io/read.go b/app/safe/internal/state/io/read.go index e6a7771f..5fbdc651 100644 --- a/app/safe/internal/state/io/read.go +++ b/app/safe/internal/state/io/read.go @@ -13,6 +13,7 @@ package io import ( "encoding/json" "errors" + "github.com/vmware-tanzu/secrets-manager/core/env" "github.com/vmware-tanzu/secrets-manager/core/crypto" entity "github.com/vmware-tanzu/secrets-manager/core/entity/v1/data" @@ -36,6 +37,10 @@ import ( // returned. The error provides context about the nature of the failure, // such as issues with decryption or data deserialization. func ReadFromDisk(key string) (*entity.SecretStored, error) { + if env.BackingStoreForSafe() != entity.File { + panic("Attempted to read from disk when backing store is not file") + } + contents, err := crypto.DecryptDataFromDisk(key) if err != nil { return nil, errors.Join( diff --git a/app/safe/internal/state/secret/collection/populate.go b/app/safe/internal/state/secret/collection/populate.go index 9593c1e5..102ed7bb 100644 --- a/app/safe/internal/state/secret/collection/populate.go +++ b/app/safe/internal/state/secret/collection/populate.go @@ -72,6 +72,9 @@ func PopulateSecrets(cid string) error { if err != nil { log.ErrorLn(&cid, "populateSecrets:error", err.Error()) } + case data.Postgres: + // TODO: implement me. + log.WarnLn(&cid, "populateSecrets: postgres initial secrets population is not implemented yet.") case data.Kubernetes: panic("implement kubernetes store") case data.AwsSecretStore: diff --git a/app/safe/internal/state/secret/collection/read.go b/app/safe/internal/state/secret/collection/read.go index 823a03f0..b901d8ed 100644 --- a/app/safe/internal/state/secret/collection/read.go +++ b/app/safe/internal/state/secret/collection/read.go @@ -15,6 +15,7 @@ import ( "github.com/vmware-tanzu/secrets-manager/app/safe/internal/state/stats" "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" data "github.com/vmware-tanzu/secrets-manager/lib/entity" ) @@ -199,6 +200,16 @@ func ReadSecret(cid string, key string) (*entity.SecretStored, error) { return &s, nil } + store := env.BackingStoreForSafe() + + switch store { + case entity.File: + log.TraceLn(&cid, "will read from file store.") + case entity.Postgres: + log.WarnLn(&cid, "TODO: fetch from postgres store") + return nil, nil + } + stored, err := io.ReadFromDisk(key) if err != nil { diff --git a/app/safe/internal/state/secret/queue/deletion/disk.go b/app/safe/internal/state/secret/queue/deletion/disk.go index 1872385e..d375b58f 100644 --- a/app/safe/internal/state/secret/queue/deletion/disk.go +++ b/app/safe/internal/state/secret/queue/deletion/disk.go @@ -69,7 +69,7 @@ func ProcessSecretBackingStoreQueue() { log.TraceLn(&cid, "ProcessSecretQueue: using in-memory store.") return case entity.File: - log.TraceLn(&cid, "ProcessSecretQueue: Will persist to disk.") + log.TraceLn(&cid, "ProcessSecretQueue: Will delete secret from disk.") case entity.Kubernetes: panic("implement kubernetes store") case entity.AwsSecretStore: @@ -78,6 +78,9 @@ func ProcessSecretBackingStoreQueue() { panic("implement azure secret store") case entity.GcpSecretStore: panic("implement gcp secret store") + case entity.Postgres: + log.WarnLn(&cid, "Delete operation has not been implemented for postgres backing store yet.") + return } if secret.Name == "" { diff --git a/app/safe/internal/state/secret/queue/insertion/disk.go b/app/safe/internal/state/secret/queue/insertion/disk.go index 42a608e8..2e95617b 100644 --- a/app/safe/internal/state/secret/queue/insertion/disk.go +++ b/app/safe/internal/state/secret/queue/insertion/disk.go @@ -73,8 +73,12 @@ func ProcessSecretBackingStoreQueue() { panic("implement azure secret store") case entity.GcpSecretStore: panic("implement gcp secret store") + case entity.Postgres: + log.TraceLn(&cid, "ProcessSecretQueue: Will persist to Postgres.") } + // TODO: will definitely need cleanup. + // Get a secret to be persisted to the disk. secret := <-SecretUpsertQueue @@ -93,7 +97,14 @@ func ProcessSecretBackingStoreQueue() { // // Do not call this function elsewhere. // It is meant to be called inside this `processSecretQueue` goroutine. - io.PersistToDisk(secret, errChan) + if store == entity.Postgres { + + // TODO: for debugging; delete values before merging. + log.TraceLn(&cid, "Persisting to Postgres.", secret.Name) + io.PersistToPostgres(secret, errChan) + } else { + io.PersistToDisk(secret, errChan) + } log.TraceLn(&cid, "processSecretQueue: should have persisted the secret.") diff --git a/core/constants/env/env.go b/core/constants/env/env.go index 2b5e8100..556fd24d 100644 --- a/core/constants/env/env.go +++ b/core/constants/env/env.go @@ -37,6 +37,7 @@ const VSecMRootKeyInputModeManual VarName = "VSECM_ROOT_KEY_INPUT_MODE_MANUAL" const VSecMRootKeyName VarName = "VSECM_ROOT_KEY_NAME" const VSecMRootKeyPath VarName = "VSECM_ROOT_KEY_PATH" const VSecMSafeBackingStore VarName = "VSECM_SAFE_BACKING_STORE" +const VSecMSafePostgresDataSourceName VarName = "VSECM_SAFE_POSTGRES_DATASOURCE_NAME" const VSecMSafeBootstrapTimeout VarName = "VSECM_SAFE_BOOTSTRAP_TIMEOUT" const VSecMSafeDataPath VarName = "VSECM_SAFE_DATA_PATH" const VSecMSafeEndpointUrl VarName = "VSECM_SAFE_ENDPOINT_URL" @@ -125,6 +126,7 @@ const VSecMSpiffeIdPrefixSafeDefault VarValue = "^spiffe://vsecm.com/workload/vs const VSecMSpiffeIdPrefixSentinelDefault VarValue = "^spiffe://vsecm.com/workload/vsecm-sentinel/ns/vsecm-system/sa/vsecm-sentinel/n/[^/]+$" const VSecMSpiffeIdPrefixWorkloadDefault VarValue = "^spiffe://vsecm.com/workload/[^/]+/ns/[^/]+/sa/[^/]+/n/[^/]+$" const VSecMNameRegExpForWorkloadDefault VarValue = "^spiffe://vsecm.com/workload/([^/]+)/ns/[^/]+/sa/[^/]+/n/[^/]+$" +const VSecMSafePostgresDataSourceNameDefault VarValue = "user=postgres dbname=postgres sslmode=disable" const VSecMRelayServerUrlDefault VarValue = "https://vsecm-relay.vsecm-system.svc.cluster.local:443/" diff --git a/core/crypto/encrypt.go b/core/crypto/encrypt.go index f68d6468..9ae67792 100644 --- a/core/crypto/encrypt.go +++ b/core/crypto/encrypt.go @@ -199,3 +199,108 @@ func EncryptToWriterAes(out io.Writer, data string) error { return nil } + +var lastEncryptBytesAesCall time.Time + +// EncryptBytesAes encrypts the given data using AES encryption and returns the encrypted bytes. +func EncryptBytesAes(data []byte) ([]byte, error) { + rkt := RootKeyCollectionFromMemory() + + // Throttle calls to this method to ensure IV randomness + if time.Since(lastEncryptBytesAesCall) < time.Millisecond*time.Duration( + env.IvInitializationIntervalForSafe(), + ) { + return nil, errors.New("calls too frequent") + } + + lastEncryptBytesAesCall = time.Now() + + aesKey := rkt.AesSeed + + if aesKey == "" { + return nil, errors.New("EncryptBytesAes: no AES key") + } + + aesKeyDecoded, err := hex.DecodeString(aesKey) + defer func() { + // Clear the key from memory for security reasons. + for i := range aesKeyDecoded { + aesKeyDecoded[i] = 0 + } + }() + + if err != nil { + return nil, errors.Join( + err, + errors.New("EncryptBytesAes: failed to decode AES key"), + ) + } + + block, err := aes.NewCipher(aesKeyDecoded) + if err != nil { + return nil, errors.Join( + err, + errors.New("EncryptBytesAes: failed to create AES cipher block"), + ) + } + + totalSize := uint64(aes.BlockSize) + uint64(len(data)) + if totalSize > uint64(math.MaxInt64) { + return nil, errors.New("EncryptBytesAes: data too large") + } + + ciphertext := make([]byte, totalSize) + + iv := ciphertext[:aes.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + return nil, err + } + + stream := cipher.NewCFBEncrypter(block, iv) + stream.XORKeyStream(ciphertext[aes.BlockSize:], data) + + return ciphertext, nil +} + +// EncryptBytesAge encrypts the given data using the age encryption protocol and returns the encrypted bytes. +func EncryptBytesAge(data []byte) ([]byte, error) { + rkt := RootKeyCollectionFromMemory() + publicKey := rkt.PublicKey + + if publicKey == "" { + return nil, errors.New("EncryptBytesAge: no public key") + } + + recipient, err := age.ParseX25519Recipient(publicKey) + if err != nil { + return nil, errors.Join( + err, + errors.New("EncryptBytesAge: failed to parse public key"), + ) + } + + var buf bytes.Buffer + wrappedWriter, err := age.Encrypt(&buf, recipient) + if err != nil { + return nil, errors.Join( + err, + errors.New("EncryptBytesAge: failed to create encrypted buffer"), + ) + } + + if _, err := wrappedWriter.Write(data); err != nil { + return nil, errors.Join( + err, + errors.New("EncryptBytesAge: failed to write to encrypted buffer"), + ) + } + + if err := wrappedWriter.Close(); err != nil { + return nil, errors.Join( + err, + errors.New("EncryptBytesAge: failed to close encrypted writer"), + ) + } + + return buf.Bytes(), nil +} diff --git a/core/entity/v1/data/store.go b/core/entity/v1/data/store.go index 5de4c727..470ecb88 100644 --- a/core/entity/v1/data/store.go +++ b/core/entity/v1/data/store.go @@ -20,4 +20,5 @@ var ( AzureSecretStore BackingStore = "azure-secret" GcpSecretStore BackingStore = "gcp-secret" Kubernetes BackingStore = "k8s" + Postgres BackingStore = "postgres" ) diff --git a/core/env/store.go b/core/env/store.go index efebdfe8..26992322 100644 --- a/core/env/store.go +++ b/core/env/store.go @@ -63,8 +63,13 @@ func BackingStoreForSafe() data.BackingStore { return data.File } - if s != string(data.File) { - panic("Only File is supported as a backing store") + switch s { + case string(data.File): + return data.File + case string(data.Postgres): + return data.Postgres + default: + panic("Only File and Postgres are supported as a backing store") } return data.File diff --git a/dockerfiles/vsecm-ist-fips/safe.Dockerfile b/dockerfiles/vsecm-ist-fips/safe.Dockerfile index b8b108bc..e958158e 100644 --- a/dockerfiles/vsecm-ist-fips/safe.Dockerfile +++ b/dockerfiles/vsecm-ist-fips/safe.Dockerfile @@ -20,7 +20,7 @@ COPY go.mod /build/go.mod WORKDIR /build # GOEXPERIMENT=boringcrypto is required for FIPS compliance. -RUN CGO_ENABLED=0 GOEXPERIMENT=boringcrypto GOOS=linux go build -mod vendor -a -o vsecm-safe ./app/safe/cmd/main.go +RUN CGO_ENABLED=0 GOEXPERIMENT=boringcrypto GOOS=linux go build -mod vendor -a -o vsecm-safe ./app/safe/cmd/main.go ./app/safe/cmd/entity.go # generate clean, final image for end users FROM gcr.io/distroless/static-debian11 diff --git a/dockerfiles/vsecm-ist/safe.Dockerfile b/dockerfiles/vsecm-ist/safe.Dockerfile index 8430411f..95cac9ef 100644 --- a/dockerfiles/vsecm-ist/safe.Dockerfile +++ b/dockerfiles/vsecm-ist/safe.Dockerfile @@ -18,7 +18,7 @@ COPY lib /build/lib COPY vendor /build/vendor COPY go.mod /build/go.mod WORKDIR /build -RUN CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -o vsecm-safe ./app/safe/cmd/main.go +RUN CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -o vsecm-safe ./app/safe/cmd/main.go ./app/safe/cmd/entity.go # generate clean, final image for end users FROM gcr.io/distroless/static-debian11 diff --git a/go.mod b/go.mod index 35b86602..1e576acf 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( filippo.io/age v1.1.1 github.com/agiledragon/gomonkey/v2 v2.11.0 github.com/akamensky/argparse v1.4.0 + github.com/lib/pq v1.10.9 github.com/spiffe/go-spiffe/v2 v2.3.0 github.com/stretchr/testify v1.9.0 github.com/vmware-tanzu/secrets-manager/sdk v0.27.0 diff --git a/go.sum b/go.sum index 6e8c16c6..93536276 100644 --- a/go.sum +++ b/go.sum @@ -55,6 +55,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/helm-charts/0.27.4/charts/safe/values.yaml b/helm-charts/0.27.4/charts/safe/values.yaml index 6f8ecbc1..d891876b 100644 --- a/helm-charts/0.27.4/charts/safe/values.yaml +++ b/helm-charts/0.27.4/charts/safe/values.yaml @@ -77,9 +77,10 @@ environments: value: ":8082" # -- The backing store for VSecM Safe. # Possible values are: "memory", "file", "aws-secret", "azure-secret", - # "gcp-secret", "k8s". Currently, only "memory" and "file" are supported. + # "gcp-secret", "k8s". Currently, only "memory", "postgres", and "file" + # are supported. - name: VSECM_SAFE_BACKING_STORE - value: "file" + value: "file" # # -- The interval (in milliseconds) that the VSecM Safe will wait during # bootstrapping before it bails out. - name: VSECM_SAFE_BOOTSTRAP_TIMEOUT diff --git a/makefiles/VSecMBuild.mk b/makefiles/VSecMBuild.mk index c18fcb1c..9b07832a 100644 --- a/makefiles/VSecMBuild.mk +++ b/makefiles/VSecMBuild.mk @@ -25,9 +25,9 @@ bundle-all-local: \ safe-bundle-ist \ sidecar-bundle-ist \ sentinel-bundle-ist \ - init-container-bundle-ist \ - relay-client-bundle-ist \ - relay-server-bundle-ist + init-container-bundle-ist + # relay-client-bundle-ist \ + # relay-server-bundle-ist bundle-all: \ inspector-bundle \ @@ -67,11 +67,11 @@ push-all: \ sentinel-push-ist \ sentinel-push-ist-fips \ init-container-push-ist \ - init-container-push-ist-fips \ - relay-client-push-ist \ - relay-client-push-ist-fips \ - rely-server-push-ist \ - relay-server-push-ist-fips + init-container-push-ist-fips +# relay-client-push-ist \ +# relay-client-push-ist-fips \ +# rely-server-push-ist \ +# relay-server-push-ist-fips # Builds everything and pushes to public DockerHub registries. build: @@ -139,9 +139,9 @@ push-all-local: \ safe-push-ist-local \ sidecar-push-ist-local \ sentinel-push-ist-local \ - init-container-push-ist-local \ - relay-client-push-ist-local \ - relay-server-push-ist-local + init-container-push-ist-local +# relay-client-push-ist-local \ +# relay-server-push-ist-local # Builds everything and pushes to the local registry.