Validate secretapi config at startup for fail-closed deploys

This commit is contained in:
Joshua 2026-02-18 07:09:31 -08:00
parent b84aace53c
commit fd2f8413aa
4 changed files with 48 additions and 0 deletions

View File

@ -21,6 +21,7 @@ go test ./...
## Environment Template ## Environment Template
Copy `.env.example` in this folder and set contract/runtime values before deploy. Copy `.env.example` in this folder and set contract/runtime values before deploy.
`secretapi` validates config at startup and fails closed if strict chain verification is enabled without RPC.
## Endpoint Surface ## Endpoint Surface

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"fmt"
"os" "os"
"strconv" "strconv"
"strings" "strings"
@ -65,6 +66,16 @@ func loadConfig() Config {
} }
} }
func (c Config) Validate() error {
if c.ChainID <= 0 {
return fmt.Errorf("SECRET_API_CHAIN_ID must be positive")
}
if c.RequireOnchainTxVerify && strings.TrimSpace(c.ChainRPCURL) == "" {
return fmt.Errorf("SECRET_API_REQUIRE_ONCHAIN_TX_VERIFICATION requires SECRET_API_CHAIN_RPC_URL")
}
return nil
}
func env(key, fallback string) string { func env(key, fallback string) string {
if v := strings.TrimSpace(os.Getenv(key)); v != "" { if v := strings.TrimSpace(os.Getenv(key)); v != "" {
return v return v

View File

@ -0,0 +1,33 @@
package main
import "testing"
func TestConfigValidateAllowsDefaultLocalConfig(t *testing.T) {
t.Parallel()
cfg := loadConfig()
cfg.ChainID = 84532
cfg.RequireOnchainTxVerify = false
cfg.ChainRPCURL = ""
if err := cfg.Validate(); err != nil {
t.Fatalf("expected default-like config valid, got %v", err)
}
}
func TestConfigValidateRejectsStrictVerificationWithoutRPC(t *testing.T) {
t.Parallel()
cfg := loadConfig()
cfg.RequireOnchainTxVerify = true
cfg.ChainRPCURL = ""
if err := cfg.Validate(); err == nil {
t.Fatalf("expected strict verification config validation failure")
}
}
func TestConfigValidateRejectsNonPositiveChainID(t *testing.T) {
t.Parallel()
cfg := loadConfig()
cfg.ChainID = 0
if err := cfg.Validate(); err == nil {
t.Fatalf("expected chain id validation failure")
}
}

View File

@ -7,6 +7,9 @@ import (
func main() { func main() {
cfg := loadConfig() cfg := loadConfig()
if err := cfg.Validate(); err != nil {
log.Fatalf("invalid config: %v", err)
}
logConfig(cfg) logConfig(cfg)
st, err := openStore(cfg.DBPath) st, err := openStore(cfg.DBPath)