Go Library
The pkg/kiln package provides a Go library for integrating kiln’s encrypted environment variable functionality directly into your applications.
Installation
Section titled “Installation”go get github.com/thunderbottom/kiln/pkg/kilnBasic Usage
Section titled “Basic Usage”Loading Configuration
Section titled “Loading Configuration”package main
import ( "fmt" "log"
"github.com/thunderbottom/kiln/pkg/kiln")
func main() { // Load kiln.toml configuration cfg, err := kiln.LoadConfig("kiln.toml") if err != nil { log.Fatal(err) }
fmt.Printf("Loaded %d recipients\n", len(cfg.Recipients))}Identity Management
Section titled “Identity Management”// Load identity from specific key fileidentity, err := kiln.NewIdentityFromKey("/path/to/key.key")if err != nil { log.Fatal(err)}defer identity.Cleanup() // Always cleanup for security
// Auto-discover key from standard locationsidentity, err := kiln.DiscoverAndLoadIdentity()if err != nil { log.Fatal(err)}defer identity.Cleanup()Reading Environment Variables
Section titled “Reading Environment Variables”Single Variable
Section titled “Single Variable”// Get one environment variablevalue, cleanup, err := kiln.GetEnvironmentVar(identity, cfg, "production", "DATABASE_URL")if err != nil { log.Fatal(err)}defer cleanup() // Secure memory cleanup
fmt.Println("Database URL:", string(value))All Variables
Section titled “All Variables”// Get all environment variables from a filevars, cleanup, err := kiln.GetAllEnvironmentVars(identity, cfg, "production")if err != nil { log.Fatal(err)}defer cleanup()
for key, value := range vars { fmt.Printf("%s=%s\n", key, string(value))}Setting Variables
Section titled “Setting Variables”// Set a single variableerr := kiln.SetEnvironmentVar(identity, cfg, "development", "API_KEY", []byte("secret-key"))if err != nil { log.Fatal(err)}
// Set multiple variablesvars := map[string][]byte{ "DATABASE_URL": []byte("postgres://localhost/myapp"), "API_KEY": []byte("secret-api-key"), "DEBUG": []byte("true"),}
err = kiln.SetMultipleEnvironmentVars(identity, cfg, "development", vars)if err != nil { log.Fatal(err)}Advanced Usage
Section titled “Advanced Usage”Key Discovery
Section titled “Key Discovery”// Discover private key from standard locationskeyPath, err := kiln.DiscoverPrivateKey()if err != nil { log.Fatal("No compatible private key found:", err)}
fmt.Println("Using key:", keyPath)Access Control Validation
Section titled “Access Control Validation”// Check if identity can access a specific filecanAccess := kiln.ValidateAccess(identity, cfg, "production")if !canAccess { log.Fatal("Access denied to production environment")}Configuration Validation
Section titled “Configuration Validation”// Validate configuration fileif err := kiln.ValidateConfig(cfg); err != nil { log.Fatal("Invalid configuration:", err)}
// Check specific file configurationfileConfig, exists := cfg.Files["production"]if !exists { log.Fatal("Production environment not configured")}Integration Patterns
Section titled “Integration Patterns”Application Configuration
Section titled “Application Configuration”type AppConfig struct { DatabaseURL string APIKey string Debug bool}
func LoadConfig(env string) (*AppConfig, error) { cfg, err := kiln.LoadConfig("kiln.toml") if err != nil { return nil, err }
identity, err := kiln.DiscoverAndLoadIdentity() if err != nil { return nil, err } defer identity.Cleanup()
vars, cleanup, err := kiln.GetAllEnvironmentVars(identity, cfg, env) if err != nil { return nil, err } defer cleanup()
return &AppConfig{ DatabaseURL: string(vars["DATABASE_URL"]), APIKey: string(vars["API_KEY"]), Debug: string(vars["DEBUG"]) == "true", }, nil}HTTP Server with Encrypted Config
Section titled “HTTP Server with Encrypted Config”package main
import ( "log" "net/http" "os"
"github.com/thunderbottom/kiln/pkg/kiln")
func main() { cfg, err := kiln.LoadConfig("kiln.toml") if err != nil { log.Fatal(err) }
identity, err := kiln.DiscoverAndLoadIdentity() if err != nil { log.Fatal(err) } defer identity.Cleanup()
// Get server configuration vars, cleanup, err := kiln.GetAllEnvironmentVars(identity, cfg, "production") if err != nil { log.Fatal(err) } defer cleanup()
port := string(vars["PORT"]) if port == "" { port = "8080" }
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("OK")) })
log.Printf("Server starting on port %s", port) log.Fatal(http.ListenAndServe(":"+port, nil))}CI/CD Integration
Section titled “CI/CD Integration”func deployWithSecrets(environment string) error { cfg, err := kiln.LoadConfig("deploy/kiln.toml") if err != nil { return err }
// Use deploy key in CI identity, err := kiln.NewIdentityFromKey("/secrets/deploy.key") if err != nil { return err } defer identity.Cleanup()
vars, cleanup, err := kiln.GetAllEnvironmentVars(identity, cfg, environment) if err != nil { return err } defer cleanup()
// Set environment variables for deployment for key, value := range vars { os.Setenv(key, string(value)) }
// Run deployment command return runDeployment()}Security Considerations
Section titled “Security Considerations”Memory Management
Section titled “Memory Management”// Correct: Always cleanupvalue, cleanup, err := kiln.GetEnvironmentVar(identity, cfg, "prod", "SECRET")if err != nil { return err}defer cleanup() // Secure memory wipe
// Wrong: No cleanupvalue, _, err := kiln.GetEnvironmentVar(identity, cfg, "prod", "SECRET")// Memory remains unwiped!Identity Lifecycle
Section titled “Identity Lifecycle”// Correct: Cleanup identityidentity, err := kiln.NewIdentityFromKey("key.key")if err != nil { return err}defer identity.Cleanup()
// Wrong: No cleanupidentity, _ := kiln.NewIdentityFromKey("key.key")// Private key remains in memory!API Reference
Section titled “API Reference”Core Functions
Section titled “Core Functions”| Function | Description |
|---|---|
LoadConfig(path string) (*Config, error) | Load kiln.toml configuration |
NewIdentityFromKey(keyPath string) (*Identity, error) | Load identity from key file |
DiscoverPrivateKey() (string, error) | Find compatible private key |
GetEnvironmentVar(identity *Identity, cfg *Config, file, key string) ([]byte, func(), error) | Get single variable |
GetAllEnvironmentVars(identity *Identity, cfg *Config, file string) (map[string][]byte, func(), error) | Get all variables |
SetEnvironmentVar(identity *Identity, cfg *Config, file, key string, value []byte) error | Set single variable |
SetMultipleEnvironmentVars(identity *Identity, cfg *Config, file string, vars map[string][]byte) error | Set multiple variables |
type Config struct { Recipients map[string]string Groups map[string][]string Files map[string]FileConfig}
type FileConfig struct { Filename string Access []string}
type Identity struct { // Private fields - use provided methods}For complete API documentation, see the Go package documentation.