Add THRESHOLD_* env var support with BOUNDARY_* fallback

Introduce api.Getenv/api.LookupEnv which prefer THRESHOLD_X and fall back to legacy BOUNDARY_X; use them for user-facing env var reads.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
shadowdaoandClaude Sonnet 5.5 committed 2026-10-12 09:45:44 -07:00
1 parent eeb38a1a84
commit 306960d24b
16 files changed
+135 -57

No files matched your search

+12 -13
View File
@@ -15,7 +15,6 @@ import (
"net"
"net/http"
"net/url"
"os"
"path"
"strconv"
"strings"
@@ -296,15 +295,15 @@ func (c *Config) ReadEnvironment() error {
var envServerName string
// Parse the environment variables
if v := os.Getenv(EnvBoundaryAddr); v != "" {
if v := Getenv(EnvBoundaryAddr); v != "" {
c.Addr = v
}
if v := os.Getenv(EnvBoundaryToken); v != "" {
if v := Getenv(EnvBoundaryToken); v != "" {
c.Token = v
}
if v := os.Getenv(EnvBoundaryMaxRetries); v != "" {
if v := Getenv(EnvBoundaryMaxRetries); v != "" {
maxRetries, err := strconv.ParseUint(v, 10, 32)
if err != nil {
return err
@@ -318,7 +317,7 @@ func (c *Config) ReadEnvironment() error {
c.MaxRetries = int(maxRetries)
}
if v := os.Getenv(EnvBoundarySRVLookup); v != "" {
if v := Getenv(EnvBoundarySRVLookup); v != "" {
var err error
lookup, err := strconv.ParseBool(v)
if err != nil {
@@ -327,7 +326,7 @@ func (c *Config) ReadEnvironment() error {
c.SRVLookup = lookup
}
if t := os.Getenv(EnvBoundaryClientTimeout); t != "" {
if t := Getenv(EnvBoundaryClientTimeout); t != "" {
clientTimeout, err := parseutil.ParseDurationSecond(t)
if err != nil {
return fmt.Errorf("could not parse %q", EnvBoundaryClientTimeout)
@@ -335,7 +334,7 @@ func (c *Config) ReadEnvironment() error {
c.Timeout = clientTimeout
}
if v := os.Getenv(EnvBoundaryRateLimit); v != "" {
if v := Getenv(EnvBoundaryRateLimit); v != "" {
rateLimit, burstLimit, err := parseRateLimit(v)
if err != nil {
return err
@@ -346,23 +345,23 @@ func (c *Config) ReadEnvironment() error {
// TLS Config
{
var foundTLSConfig bool
if v := os.Getenv(EnvBoundaryCACert); v != "" {
if v := Getenv(EnvBoundaryCACert); v != "" {
foundTLSConfig = true
envCACert = v
}
if v := os.Getenv(EnvBoundaryCAPath); v != "" {
if v := Getenv(EnvBoundaryCAPath); v != "" {
foundTLSConfig = true
envCAPath = v
}
if v := os.Getenv(EnvBoundaryClientCert); v != "" {
if v := Getenv(EnvBoundaryClientCert); v != "" {
foundTLSConfig = true
envClientCert = v
}
if v := os.Getenv(EnvBoundaryClientKey); v != "" {
if v := Getenv(EnvBoundaryClientKey); v != "" {
foundTLSConfig = true
envClientKey = v
}
if v := os.Getenv(EnvBoundaryTLSInsecure); v != "" {
if v := Getenv(EnvBoundaryTLSInsecure); v != "" {
foundTLSConfig = true
var err error
envInsecure, err = strconv.ParseBool(v)
@@ -370,7 +369,7 @@ func (c *Config) ReadEnvironment() error {
return fmt.Errorf("could not parse BOUNDARY_TLS_INSECURE")
}
}
if v := os.Getenv(EnvBoundaryTLSServerName); v != "" {
if v := Getenv(EnvBoundaryTLSServerName); v != "" {
foundTLSConfig = true
envServerName = v
}
+56
View File
@@ -0,0 +1,56 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package api
import (
"os"
"strings"
)
const (
// legacyEnvPrefix is the environment variable prefix used by upstream
// HashiCorp Boundary. It is still honored as a fallback.
legacyEnvPrefix = "BOUNDARY_"
// envPrefix is the preferred environment variable prefix for Threshold.
envPrefix = "THRESHOLD_"
)
// PreferredEnvName returns the Threshold (THRESHOLD_*) form of an environment
// variable name. Names that do not use the legacy BOUNDARY_ prefix are
// returned unchanged.
func PreferredEnvName(name string) string {
if strings.HasPrefix(name, legacyEnvPrefix) {
return envPrefix + strings.TrimPrefix(name, legacyEnvPrefix)
}
return name
}
// LegacyEnvName returns the legacy (BOUNDARY_*) form of an environment
// variable name. Names that do not use the THRESHOLD_ prefix are returned
// unchanged.
func LegacyEnvName(name string) string {
if strings.HasPrefix(name, envPrefix) {
return legacyEnvPrefix + strings.TrimPrefix(name, envPrefix)
}
return name
}
// LookupEnv looks up an environment variable, preferring the THRESHOLD_*
// name and falling back to the legacy BOUNDARY_* name. The name may be given
// with either prefix; names with neither prefix are looked up as-is.
func LookupEnv(name string) (string, bool) {
if v, ok := os.LookupEnv(PreferredEnvName(LegacyEnvName(name))); ok {
return v, true
}
return os.LookupEnv(LegacyEnvName(name))
}
// Getenv is like os.Getenv but follows the LookupEnv precedence. A set but
// empty THRESHOLD_* variable falls through to the legacy BOUNDARY_* variable.
func Getenv(name string) string {
if v := os.Getenv(PreferredEnvName(LegacyEnvName(name))); v != "" {
return v
}
return os.Getenv(LegacyEnvName(name))
}
+24
View File
@@ -0,0 +1,24 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package api
import "testing"
func TestEnvFallback(t *testing.T) {
t.Setenv("THRESHOLD_ZZ_TEST", "")
t.Setenv("BOUNDARY_ZZ_TEST", "old")
if got := Getenv("BOUNDARY_ZZ_TEST"); got != "old" {
t.Fatalf("want old, got %q", got)
}
t.Setenv("THRESHOLD_ZZ_TEST", "new")
if got := Getenv("BOUNDARY_ZZ_TEST"); got != "new" {
t.Fatalf("want new, got %q", got)
}
if got, ok := LookupEnv("THRESHOLD_ZZ_TEST"); !ok || got != "new" {
t.Fatalf("want new, got %q %v", got, ok)
}
if PreferredEnvName("BOUNDARY_ADDR") != "THRESHOLD_ADDR" || LegacyEnvName("THRESHOLD_ADDR") != "BOUNDARY_ADDR" {
t.Fatal("name mapping")
}
}
+2 -3
View File
@@ -5,7 +5,6 @@ package api
import (
"fmt"
"os"
"strings"
retryablehttp "github.com/hashicorp/go-retryablehttp"
@@ -60,8 +59,8 @@ func (d *OutputStringError) parseRequest() {
for k, v := range d.Request.Header {
for _, h := range v {
if strings.ToLower(k) == "authorization" {
tokenName := os.Getenv("BOUNDARY_TOKEN_NAME")
keyringType := os.Getenv("BOUNDARY_KEYRING_TYPE")
tokenName := Getenv("BOUNDARY_TOKEN_NAME")
keyringType := Getenv("BOUNDARY_KEYRING_TYPE")
switch {
case tokenName == "none" || keyringType == "none":
h = `Bearer <token>`