Go SDK
Production-grade, thread-safe Go client for CustomKeys secrets management. Designed for backend services, CLI tools, and infrastructure automation.
Installation
go get github.com/cksxe/sdk-go
Quick Start
package main import ( "fmt" "log" "os" customkeys "github.com/cksxe/sdk-go" ) func main() { client, err := customkeys.New( customkeys.WithToken(os.Getenv("CUSTOMKEYS_TOKEN")), customkeys.WithEnv(os.Getenv("CUSTOMKEYS_ENV_ID")), ) if err != nil { log.Fatal(err) } defer client.Close() // Fetch a single secret dbURL, ok := client.Get("DATABASE_URL") if !ok { log.Fatal("DATABASE_URL not found") } fmt.Println("Connected:", dbURL[:20]+"...") // Fetch all secrets all := client.GetAll() fmt.Printf("Loaded %d secrets\n", len(all)) }
Configuration
All options are set via functional options passed to customkeys.New():
| Option | Default | Description |
|---|---|---|
WithToken(string) | required | API token with secrets:read scope |
WithEnv(string) | required | Environment UUID |
WithBaseURL(string) | https://customkeys-api.superxepic.dev | API base URL |
WithTTL(time.Duration) | 60s | Cache freshness window |
WithPollInterval(time.Duration) | 30s | Background refresh interval |
WithTimeout(time.Duration) | 10s | HTTP request timeout |
WithMaxRetries(int) | 3 | Retries on transient failures |
WithHTTPClient(*http.Client) | auto | Custom HTTP client |
WithLogger(Logger) | disabled | Debug logging |
Methods
| Method | Return | Description |
|---|---|---|
Get(key) | (string, bool) | Returns the value or ("", false) if not found |
MustGet(key) | string | Returns the value or panics — use for required config at startup |
GetOrDefault(key, default) | string | Returns the value or the provided default |
GetAll() | map[string]string | Returns a shallow copy of all cached secrets |
Refresh(ctx) | error | Forces an immediate cache refresh (blocking) |
Ready() | bool | true after initial bulk pull completes |
Close() | — | Stops polling, zeros memory, releases resources |
Usage with Gin / Echo / Chi
package main import ( "log" "net/http" "os" "github.com/go-chi/chi/v5" customkeys "github.com/cksxe/sdk-go" ) var secrets *customkeys.Client func main() { var err error secrets, err = customkeys.New( customkeys.WithToken(os.Getenv("CUSTOMKEYS_TOKEN")), customkeys.WithEnv(os.Getenv("CUSTOMKEYS_ENV_ID")), ) if err != nil { log.Fatal(err) } defer secrets.Close() r := chi.NewRouter() r.Get("/health", func(w http.ResponseWriter, r *http.Request) { dbHost := secrets.GetOrDefault("DB_HOST", "localhost") w.Write([]byte("OK — DB: " + dbHost)) }) log.Fatal(http.ListenAndServe(":8080", r)) }
Callbacks and Observability
client, _ := customkeys.New( customkeys.WithToken(os.Getenv("CUSTOMKEYS_TOKEN")), customkeys.WithEnv(os.Getenv("CUSTOMKEYS_ENV_ID")), customkeys.WithOnRefresh(func(count int) { log.Printf("Refreshed %d secrets", count) }), customkeys.WithOnError(func(err error) { log.Printf("Refresh failed: %v", err) // Send to your alerting system }), customkeys.WithLogger(log.Default()), )
Security Features
- TLS 1.2+ enforced on all connections
- Token sanitization — rejects control characters and newlines
- Response body limiting — 10 MB max to prevent memory exhaustion
- Memory zeroing —
Close()overwrites cached secret values before freeing - Singleflight dedup — concurrent refreshes are coalesced into one API call
- Exponential backoff — retries with 500ms/1s/2s delays, auth errors never retried
- No disk I/O — secrets are never written to the filesystem
[!IMPORTANT] The API token is sensitive. Always load it from an environment variable — never hardcode it in source.
Last updated: 4/20/2026Report Issue