### Build and Run Go Application with encx Generation Source: https://github.com/hengadev/encx/blob/main/examples/complete-webapp/README.md This Go development workflow snippet covers installing dependencies, generating encx code, running database migrations, and starting the application. It's a standard process for projects utilizing encx for code generation. ```bash # Install dependencies go mod tidy # Generate encx code encx-gen generate -v . # Run database migrations go run migrations/migrate.go # Start the application go run main.go ``` -------------------------------- ### Start PostgreSQL Database with Docker Compose Source: https://github.com/hengadev/encx/blob/main/examples/complete-webapp/README.md This snippet shows how to start a PostgreSQL database instance using Docker Compose. It ensures the database is running before proceeding with application setup. A `sleep` command is included to allow the database to become ready. ```bash # Start PostgreSQL with Docker docker-compose up -d postgres # Wait for database to be ready sleep 5 ``` -------------------------------- ### Build and Install encx-gen CLI Tool Source: https://github.com/hengadev/encx/blob/main/docs/CODE_GENERATION_GUIDE.md Instructions for building and installing the encx-gen command-line interface tool. This can be done using make commands or by running the tool directly with 'go run'. ```bash make build-cli make install-cli ``` ```bash go run cmd/encx-gen/main.go version ``` -------------------------------- ### Complete AWS Example Migration (Go) Source: https://github.com/hengadev/encx/blob/main/docs/MIGRATION_GUIDE_V0.6.0.md This complete example shows the full migration of an AWS-based application using encx from version v0.5.x to v0.6.0+. It contrasts the older initialization method with the new approach, which involves separate initializations for KMS and Secrets Manager and a consolidated crypto initialization. ```go // Before (v0.5.x): package main import ( "context" "log" "os" "github.com/hengadev/encx" "github.com/hengadev/encx/providers/awskms" ) func main() { ctx := context.Background() // Initialize KMS kms, err := awskms.New(ctx, awskms.Config{ Region: "us-east-1", }) if err != nil { log.Fatal(err) } // Load pepper from filesystem pepper, err := os.ReadFile(".encx/pepper.secret") if err != nil { log.Fatal(err) } // Initialize crypto crypto, err := encx.NewCrypto(ctx, encx.WithKMSService(kms), encx.WithKEKAlias("my-app-kek"), encx.WithPepper(pepper), ) if err != nil { log.Fatal(err) } // Use crypto... } ``` ```go // After (v0.6.0+): package main import ( "context" "log" "github.com/hengadev/encx" "github.com/hengadev/encx/providers/aws" ) func main() { ctx := context.Background() // Initialize KMS for cryptographic operations kms, err := aws.NewKMSService(ctx, aws.Config{ Region: "us-east-1", }) if err != nil { log.Fatal(err) } // Initialize Secrets Manager for pepper storage secrets, err := aws.NewSecretsManagerStore(ctx, aws.Config{ Region: "us-east-1", }) if err != nil { log.Fatal(err) } // Create configuration cfg := encx.Config{ KEKAlias: "my-app-kek", PepperAlias: "my-app-service", // Service identifier } // Initialize crypto (pepper loaded automatically from Secrets Manager) crypto, err := encx.NewCrypto(ctx, kms, secrets, cfg) if err != nil { log.Fatal(err) } // Use crypto... } ``` -------------------------------- ### Update Encryption Test Setup (Go) Source: https://github.com/hengadev/encx/blob/main/docs/MIGRATION_GUIDE_V0.6.0.md This snippet provides two options for updating test setups in Go for encryption tests. Option 1 uses a simplified test helper encx.NewTestCrypto. Option 2 shows an explicit setup using mock services and configuration, suitable for more complex testing scenarios. ```go // Before: func TestEncryption(t *testing.T) { crypto, _ := encx.NewCrypto(ctx, encx.WithKMSService(mockKMS), encx.WithPepper(testPepper), ) // ... } ``` ```go // After: func TestEncryption(t *testing.T) { // Option 1: Use test helper (simplest) crypto := encx.NewTestCrypto(t) // Option 2: Explicit setup kms := encx.NewSimpleTestKMS() secrets := encx.NewInMemorySecretStore() cfg := encx.Config{ KEKAlias: "test-kek", PepperAlias: "test-service", } crypto, _ := encx.NewCrypto(ctx, kms, secrets, cfg) // ... } ``` -------------------------------- ### Use Test KMS for Encx Debugging Source: https://github.com/hengadev/encx/blob/main/docs/TROUBLESHOOTING.md Go code example showing how to initialize encx with a test KMS implementation to isolate issues related to actual KMS service interactions. ```go // Switch to test KMS to isolate issue crypto, _ := encx.NewTestCrypto(t) err := crypto.ProcessStruct(ctx, user) ``` -------------------------------- ### Run Go Examples Source: https://github.com/hengadev/encx/blob/main/docs/EXAMPLES.md Provides command-line instructions for running the provided Go examples. Users can execute individual examples or all examples within the examples directory using `go run` commands. ```bash go run basic_example.go go run combined_tags_example.go go run ecommerce_example.go ``` ```bash go run examples/*.go ``` -------------------------------- ### Build and Run Go Example Source: https://github.com/hengadev/encx/blob/main/examples/s3-streaming-upload/README.md Instructions to compile and run the S3 streaming upload example written in Go. Navigate to the example directory, build the executable, and then run it. ```bash cd examples/s3-streaming-upload go build -o s3-upload ./s3-upload ``` -------------------------------- ### Configure Argon2 Parameters for Encx Hashing Source: https://github.com/hengadev/encx/blob/main/docs/TROUBLESHOOTING.md Go code example demonstrating how to configure Argon2 parameters (Memory, Iterations, Parallelism) when initializing encx.NewCrypto to balance security and hashing speed. ```go // Heavy parameters slow down secure hashing params := &encx.Argon2Params{ Memory: 65536, // 64MB - reduce for faster hashing Iterations: 3, // Reduce iterations if too slow Parallelism: 4, // Adjust based on CPU cores } crypto, err := encx.NewCrypto(ctx, encx.WithArgon2Params(params)) ``` -------------------------------- ### encx Basic Configuration (encx.yaml) Source: https://github.com/hengadev/encx/blob/main/docs/CODE_GENERATION_GUIDE.md Example of a basic encx configuration file (`encx.yaml`). It specifies the version and generation options like `output_suffix` and `package_name` for generated files. ```yaml version: "1" generation: output_suffix: "_encx" package_name: "encx" packages: {} ``` -------------------------------- ### Pepper Generation (Bash, Python, Go) Source: https://github.com/hengadev/encx/blob/main/docs/SECURITY.md Provides methods for generating a secure 32-byte pepper using command-line tools and scripting languages. Includes examples for OpenSSL, Python, and Go, suitable for initial setup or regeneration. ```Bash # Generate secure 32-byte pepper openssl rand -base64 32 | head -c 32 ``` ```Python # Or using Python python3 -c "import secrets; print(secrets.token_urlsafe(32)[:32])" ``` ```Go # Or using Go go run -c 'package main; import("crypto/rand"; "encoding/base64"; "fmt"); func main() { b := make([]byte, 32); rand.Read(b); fmt.Println(base64.StdEncoding.EncodeToString(b)[:32]) }' ``` -------------------------------- ### Install encx and Vault API Source: https://github.com/hengadev/encx/blob/main/providers/secrets/hashicorp/README.md Installs the encx library and the official HashiCorp Vault API client using go get. These are the core dependencies for using the Vault KV v2 provider. ```bash go get github.com/hengadev/encx go get github.com/hashicorp/vault/api ``` -------------------------------- ### Minimal Reproduction Case for Bug Reporting in Go Source: https://github.com/hengadev/encx/blob/main/docs/TROUBLESHOOTING.md Provides a template for creating a minimal, reproducible example in Go for bug reporting. It includes setting up test crypto, defining a user struct, executing the problematic function, and comments indicating where to show the unexpected behavior. ```go func TestReproduceBug(t *testing.T) { crypto, _ := encx.NewTestCrypto(t) user := &User{Name: "Test"} err := crypto.ProcessStruct(context.Background(), user) // Show the unexpected behavior } ``` -------------------------------- ### Secure Logging Example in Go Source: https://github.com/hengadev/encx/blob/main/docs/SECURITY.md This Go code illustrates secure logging practices for sensitive data operations. The 'GOOD' example logs operation type, field, status, and size, adhering to the principle of not logging plaintext sensitive data, DEKs, or peppers. ```go // ❌ BAD log.Printf("Encrypted email: %s -> %x", email, encrypted) // ✅ GOOD log.Printf("operation=encrypt field=email status=success size=%d", len(encrypted)) ``` -------------------------------- ### Check encx-gen Installation and Version (Bash) Source: https://github.com/hengadev/encx/blob/main/docs/CODE_GENERATION_GUIDE.md Provides bash commands to verify if the `encx-gen` tool is installed and accessible in the system's PATH. It also shows how to check the installed version of the tool. ```bash which encx-gen encx-gen version ``` -------------------------------- ### Enable Debug Logging in Go Source: https://github.com/hengadev/encx/blob/main/docs/TROUBLESHOOTING.md Provides a Go example for adding debug logging during `encx` processing. It shows how to log user data before processing, log errors during `crypto.ProcessStruct`, and log success messages including the length of the generated DEK. ```go import "log" // Add before processing log.Printf("Processing user: %+v", user) err := crypto.ProcessStruct(ctx, user) if err != nil { log.Printf("ProcessStruct error: %v", err) } else { log.Printf("ProcessStruct success, DEK len: %d", len(user.DEK)) } ``` -------------------------------- ### Update Crypto Initialization with Environment Variables (Go) Source: https://github.com/hengadev/encx/blob/main/docs/MIGRATION_GUIDE_V0.6.0.md This snippet illustrates updating crypto initialization in Go for environment-based configuration. It shows the use of encx.NewCryptoFromEnv, which automatically reads KEK_ALIAS and PEPPER_ALIAS from environment variables, simplifying setup for applications. ```go // After (Environment-Based - Recommended for Applications): // Set environment variables: // export ENCX_KEK_ALIAS="my-app-kek" // export ENCX_PEPPER_ALIAS="my-app-service" crypto, err := encx.NewCryptoFromEnv(ctx, kms, secrets) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Troubleshooting: Incorrect Crypto Initialization (Go) Source: https://github.com/hengadev/encx/blob/main/docs/MIGRATION_GUIDE_V0.6.0.md These code examples illustrate common errors when initializing the ENCX crypto service. The '❌ Wrong' snippets show incorrect calls missing required services (KMS, Secrets, or both), while the '✅ Correct' snippets demonstrate the proper way to pass these services during initialization. ```go // ❌ Wrong crypto, err := encx.NewCrypto(ctx, cfg) // ✅ Correct crypto, err := encx.NewCrypto(ctx, kms, secrets, cfg) ``` ```go // ❌ Wrong crypto, err := encx.NewCrypto(ctx, kms, cfg) // ✅ Correct crypto, err := encx.NewCrypto(ctx, kms, secrets, cfg) ``` -------------------------------- ### Use Generated encx Code for Encryption and Decryption Source: https://github.com/hengadev/encx/blob/main/docs/CODE_GENERATION_GUIDE.md Example Go code demonstrating how to use the functions generated by encx. It shows creating a crypto instance, processing (encrypting/hashing) user data with `ProcessUserEncx`, and later decrypting it with `DecryptUserEncx`. ```go ctx := context.Background() crypto := encx.NewCrypto(config) // Original user data user := &User{ Email: "user@example.com", Phone: "+1234567890", SSN: "123-45-6789", } // Process (encrypt/hash) the user data // Note: Function name follows pattern ProcessEncx // For a User struct, the generator creates ProcessUserEncx userEncx, err := ProcessUserEncx(ctx, crypto, user) if err != nil { log.Fatal(err) } // Store userEncx in database... // Later, decrypt the data decryptedUser, err := DecryptUserEncx(ctx, crypto, userEncx) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Basic Hashing Example in Go Source: https://github.com/hengadev/encx/blob/main/examples/context7/README.md Demonstrates simple hashing for lookup purposes using Encx in Go. This is useful for scenarios where you need to quickly check for the existence of an item without storing the original sensitive data. ```Go package main import ( "fmt" "github.com/hengadev/encx" ) func main() { dataToHash := []byte("unique-identifier-12345") // Generate a hash for the data hashedData, err := encx.Hash(dataToHash) if err != nil { fmt.Println("Error hashing data:", err) return } fmt.Printf("Original Data: %s\n", dataToHash) fmt.Printf("Hashed Data: %x\n", hashedData) // To verify, you would re-hash the input data and compare hashes inputToVerify := []byte("unique-identifier-12345") hashedInput, err := encx.Hash(inputToVerify) if err != nil { fmt.Println("Error hashing data for verification:", err) return } if encx.CompareHash(hashedData, hashedInput) { fmt.Println("Hash verification successful: Data matches.") } else { fmt.Println("Hash verification failed: Data does not match.") } // Example with different data differentData := []byte("another-identifier-67890") hashedDifferentData, err := encx.Hash(differentData) if err != nil { fmt.Println("Error hashing different data:", err) return } if encx.CompareHash(hashedData, hashedDifferentData) { fmt.Println("Hash verification successful with different data (this should not happen).") } else { fmt.Println("Hash verification failed with different data (as expected).") } } ``` -------------------------------- ### Development Workflow with encx (Bash) Source: https://github.com/hengadev/encx/blob/main/docs/CODE_GENERATION_GUIDE.md A step-by-step guide outlining a typical development workflow when using `encx`, from initial struct design and validation to code generation, testing, and committing changes, including generated files. ```bash # 1. Design your structs # 2. Validate tags make validate # 3. Generate code make generate # 4. Test integration make test # 5. Commit both source and generated code git add . && git commit -m "Add encrypted user model" ``` -------------------------------- ### Package Organization Example for encx (File Structure) Source: https://github.com/hengadev/encx/blob/main/docs/CODE_GENERATION_GUIDE.md Presents a recommended directory structure for projects using `encx`, emphasizing the separation of domain models (with `encx` tags) and generated code, as well as the use of configuration files at both package and global levels. ```plaintext project/ ├── models/ # Domain models with encx tags │ ├── user.go │ ├── user_encx.go # Generated │ └── encx.yaml # Package-specific config ├── api/ # API models │ ├── request.go │ └── request_encx.go # Generated └── encx.yaml # Global config ``` -------------------------------- ### Integration Testing Encx Services (Go) Source: https://github.com/hengadev/encx/blob/main/docs/EXAMPLES.md Shows an example of integration testing for the encx services in Go. This test uses a real encx.TestCrypto instance to verify actual encryption and hashing operations within the UserService. ```go func TestUserService_Integration(t *testing.T) { // Create test crypto with real operations crypto, _ := encx.NewTestCrypto(t) service := NewUserService(crypto) // Test actual encryption/hashing err := service.CreateUser("integration@example.com", "testPassword") assert.NoError(t, err) } ``` -------------------------------- ### Docker Configuration for S3 Upload Example Source: https://github.com/hengadev/encx/blob/main/examples/s3-streaming-upload/README.md Dockerfile to build a Docker image for the S3 streaming upload example. It uses a multi-stage build to compile the Go application and then create a lean runtime image. ```dockerfile FROM golang:1.21-alpine AS builder WORKDIR /app COPY . . RUN go build -o s3-upload . FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /app/s3-upload . CMD ["./s3-upload"] ``` -------------------------------- ### Go Test: Old Way (Complex Setup) vs. New Way (Simple Setup) Source: https://github.com/hengadev/encx/blob/main/TESTING.md Compares two approaches for testing API endpoints. The 'old way' involves a complex setup with external dependencies like HashiCorp Vault, making tests brittle and slow. The 'new way' utilizes encx.NewTestCrypto for a simple, fast, and reliable test setup without external dependencies. ```go // DON'T DO THIS ANYMORE func TestPhoneEndpoint_OLD_WAY(t *testing.T) { // Complex Vault container setup vaultContainer, err := testutils.SetupVault(context.Background(), t) require.NoError(t, err) defer testutils.TeardownVault(context.Background(), t, vaultContainer) // Create real vault KMS service kms, err := hashicorpvault.New(/* complex config */) require.NoError(t, err) // Create real crypto with external dependencies crypto, err := encx.New(context.Background(), kms, "alias", "secret/pepper") require.NoError(t, err) // Test is now dependent on external Vault service // Brittle, slow, and requires Docker } ``` ```go // DO THIS INSTEAD func TestPhoneEndpoint_NEW_WAY(t *testing.T) { ctx := context.Background() // Simple test setup with no external dependencies crypto, _ := encx.NewTestCrypto(t) // Rest of your test logic remains the same // Fast, reliable, no Docker required } ``` -------------------------------- ### Go Performance Benchmarks for User Processing and Decryption Source: https://github.com/hengadev/encx/blob/main/examples/complete-webapp/README.md These Go benchmarks measure the performance of user data processing and decryption using the encx library. They utilize the Go testing package and require setup for cryptographic operations and context. The benchmarks reset the timer before the loop to ensure accurate measurements. ```go // models/benchmark_test.go func BenchmarkUserProcessing(b *testing.B) { ctx := context.Background() crypto := setupBenchmarkCrypto(b) user := &User{ Email: "benchmark@example.com", FirstName: "Benchmark", LastName: "User", Phone: "+1234567890", SSN: "123-45-6789", Address: "123 Benchmark St", City: "Testville", State: "CA", ZipCode: "12345", } b.ResetTimer() for i := 0; i < b.N; i++ { userEncx, err := ProcessUserEncx(ctx, crypto, user) if err != nil { b.Fatal(err) } _ = userEncx } } func BenchmarkUserDecryption(b *testing.B) { ctx := context.Background() crypto := setupBenchmarkCrypto(b) user := &User{Email: "benchmark@example.com", FirstName: "Test"} userEncx, _ := ProcessUserEncx(ctx, crypto, user) b.ResetTimer() for i := 0; i < b.N; i++ { decryptedUser, err := DecryptUserEncx(ctx, crypto, userEncx) if err != nil { b.Fatal(err) } _ = decryptedUser } } ``` -------------------------------- ### Install ENCX Library in Go Source: https://github.com/hengadev/encx/blob/main/README.md This snippet shows the command to install the ENCX library using the Go build tool. It is a prerequisite for using the library in your Go projects. ```bash go get github.com/hengadev/encx ``` -------------------------------- ### Encrypt and Hash Email for Lookup and Privacy with Go Source: https://github.com/hengadev/encx/blob/main/docs/EXAMPLES.md Shows how to encrypt an email field for privacy while also generating a basic hash for fast lookups, using the ENCX library in Go. This example illustrates finding a user by email hash and then decrypting the email. ```go //go:generate encx-gen generate . // Source struct type User struct { Email string `encx:"encrypt,hash_basic"` } // Generated UserEncx struct contains: // - EmailEncrypted []byte // Stored in database // - EmailHash string // Used for user lookups // - DEKEncrypted []byte // - KeyVersion int // - Metadata metadata.EncryptionMetadata func ExampleEmailLookup() { crypto, _ := encx.NewTestCrypto(nil) ctx := context.Background() // Process user with generated function user := &User{Email: "user@example.com"} userEncx, _ := ProcessUserEncx(ctx, crypto, user) // Later: find user by email searchEmail := "user@example.com" emailBytes, _ := serialization.Serialize(searchEmail) // Assuming serialization.Serialize exists searchHash := crypto.HashBasic(ctx, emailBytes) if searchHash == userEncx.EmailHash { fmt.Println("User found!") // Decrypt email for display using generated function decrypted, _ := DecryptUserEncx(ctx, crypto, userEncx) fmt.Printf("User email: %s\n", decrypted.Email) } } ``` -------------------------------- ### Install encx and AWS SDK Source: https://github.com/hengadev/encx/blob/main/providers/keys/aws/README.md Installs the encx library along with the necessary AWS SDK v2 configuration and KMS service packages. These are foundational for interacting with AWS KMS from your Go application. ```bash go get github.com/hengadev/encx go get github.com/aws/aws-sdk-go-v2/config go get github.com/aws/aws-sdk-go-v2/service/kms ``` -------------------------------- ### Password Hashing in Go Source: https://github.com/hengadev/encx/blob/main/examples/context7/README.md Implements secure password hashing using best practices in Go. This example is crucial for protecting user credentials by ensuring that even if the database is compromised, passwords remain unreadable. ```Go package main import ( "fmt" "github.com/hengadev/encx" ) func main() { password := "mysecretpassword123" // Hash the password hashedPassword, err := encx.HashPassword(password) if err != nil { fmt.Println("Error hashing password:", err) return } fmt.Printf("Original Password: %s\n", password) fmt.Printf("Hashed Password: %s\n", hashedPassword) // Verify the password isValid := encx.VerifyPassword(password, hashedPassword) if isValid { fmt.Println("Password verification successful!") } else { fmt.Println("Password verification failed!") } // Example of a wrong password verification wrongPassword := "wrongpassword" isValid = encx.VerifyPassword(wrongPassword, hashedPassword) if isValid { fmt.Println("Wrong password verification successful (this should not happen)!") } else { fmt.Println("Wrong password verification failed (as expected)!") } } ``` -------------------------------- ### Go Serializer Example Source: https://github.com/hengadev/encx/blob/main/README.md Demonstrates the usage of per-struct serializers in Go. This example is self-contained and illustrates how to define and use custom serializers for different data structures. ```Go package main import ( "encoding/json" "fmt" ) // Person represents a person with a name and age. type Person struct { Name string `json:"name"` Age int `json:"age"` } // MarshalJSON customizes the JSON encoding for Person. func (p Person) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ "person_name": p.Name, "person_age": p.Age, }) } // UnmarshalJSON customizes the JSON decoding for Person. func (p *Person) UnmarshalJSON(data []byte) error { var intermediate map[string]interface{} if err := json.Unmarshal(data, &intermediate); err != nil { return err } p.Name = intermediate["person_name"].(string) p.Age = int(intermediate["person_age"].(float64)) return nil } func main() { person := Person{Name: "Alice", Age: 30} // Custom marshaling jsonBytes, err := json.Marshal(person) if err != nil { fmt.Println("Error marshaling:", err) return } fmt.Println("Marshaled JSON:", string(jsonBytes)) // Custom unmarshaling var decodedPerson Person err = json.Unmarshal(jsonBytes, &decodedPerson) if err != nil { fmt.Println("Error unmarshaling:", err) return } fmt.Printf("Unmarshaled Person: %+v\n", decodedPerson) } ``` -------------------------------- ### encx-gen generate CLI Command Examples (Bash) Source: https://github.com/hengadev/encx/blob/main/docs/API_REFERENCE.md Provides examples for using the `encx-gen generate` command to generate encx code. This includes generating for the current directory, multiple packages, using custom configurations, enabling verbose output, and performing dry runs. ```Bash # Generate for current directory encx-gen generate . # Generate for multiple packages encx-gen generate ./models ./api # Verbose generation with custom config encx-gen generate -config=custom.yaml -v ./models # Dry run to preview changes encx-gen generate -dry-run . ``` -------------------------------- ### Basic Encryption Example in Go Source: https://github.com/hengadev/encx/blob/main/examples/context7/README.md A fundamental example of basic field encryption using Encx in Go. This snippet serves as a starting point for understanding how to encrypt specific fields within a Go struct. ```Go package main import ( "fmt" "github.com/hengadev/encx" ) type BasicData struct { ID int SecretKey string `json:"secret_key,omitempty"` // This field will be encrypted Description string } func main() { key := []byte("a-simple-secret-key-for-testing") data := BasicData{ ID: 1, SecretKey: "supersecretvalue123", Description: "This is a description.", } // Encrypt the SecretKey field encryptedData, err := encx.EncryptStructField(key, data, "SecretKey") if err != nil { fmt.Println("Error encrypting field:", err) return } fmt.Printf("Original Data: %+v\n", data) fmt.Printf("Encrypted Data (SecretKey field): %+v\n", encryptedData) // Decrypt the SecretKey field decryptedData, err := encx.DecryptStructField(key, encryptedData, "SecretKey") if err != nil { fmt.Println("Error decrypting field:", err) return } fmt.Printf("Decrypted Data (SecretKey field): %+v\n", decryptedData) } ``` -------------------------------- ### NewKVStore Usage Example Source: https://github.com/hengadev/encx/blob/main/providers/secrets/hashicorp/README.md Shows a practical example of calling NewKVStore to create a Vault KV v2 store instance and the importance of deferring its Close method to manage token renewal. ```go kv, err := vaultkv.NewKVStore() if err != nil { log.Fatal(err) } defér kv.Close() ``` -------------------------------- ### Dockerfile for Encx Web Application Production Deployment Source: https://github.com/hengadev/encx/blob/main/examples/complete-webapp/README.md This Dockerfile outlines the steps to build a production-ready image for the encx web application. It uses a multi-stage build process, first compiling the application with Go and then copying the executable and configuration to a minimal Alpine Linux base image. It exposes port 8080 and sets the default command to run the application. ```dockerfile # Dockerfile FROM golang:1.21-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go run cmd/encx-gen/main.go generate -v . RUN go build -o webapp ./main.go FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /app/webapp . COPY --from=builder /app/config.yaml . EXPOSE 8080 CMD ["./webapp"] ``` -------------------------------- ### Initialize ENCX using Test Crypto Helper Source: https://github.com/hengadev/encx/blob/main/docs/MIGRATION_GUIDE_V0.6.0.md This Go code utilizes the `encx.NewTestCrypto(t)` helper function to initialize a crypto instance for testing. This provides a convenient way to set up test environments with mock dependencies. ```go crypto := encx.NewTestCrypto(t) ``` -------------------------------- ### Application Configuration: Go Structs for Settings Source: https://github.com/hengadev/encx/blob/main/examples/complete-webapp/README.md This Go code defines the configuration structure for the application, including settings for the server, database connection details, and Encx-specific parameters like key paths and versions. It utilizes YAML tags for configuration loading and environment variable overrides. ```go // config/config.go package config type Config struct { Server ServerConfig `yaml:"server"` Database DatabaseConfig `yaml:"database"` Encx EncxConfig `yaml:"encx"` } type ServerConfig struct { Port string `yaml:"port" env:"PORT" env-default:"8080"` Host string `yaml:"host" env:"HOST" env-default:"localhost"` } type DatabaseConfig struct { Host string `yaml:"host" env:"DB_HOST" env-default:"localhost"` Port string `yaml:"port" env:"DB_PORT" env-default:"5432"` Database string `yaml:"database" env:"DB_NAME" env-default:"webapp_example"` Username string `yaml:"username" env:"DB_USER" env-default:"postgres"` Password string `yaml:"password" env:"DB_PASSWORD" env-default:"password"` } type EncxConfig struct { KEKPath string `yaml:"kek_path" env:"KEK_PATH" env-default:"./keys/kek.key"` PepperPath string `yaml:"pepper_path" env:"PEPPER_PATH" env-default:"./keys/pepper.key"` KeyVersion int `yaml:"key_version" env:"KEY_VERSION" env-default:"1"` } ``` -------------------------------- ### Go Encx Crypto Client Initialization Source: https://github.com/hengadev/encx/blob/main/docs/SECURITY.md Demonstrates how to initialize the `encx` crypto client for both development and production environments. The development version uses a test crypto implementation, while the production version integrates with KMS, specifies a KEK alias, and includes a pepper for enhanced security. ```go // Development crypto, _ := encx.NewTestCrypto(nil) // Production crypto, _ := encx.NewCrypto(ctx, encx.WithKMSService(kms), encx.WithKEKAlias(alias), encx.WithPepper(pepper), ) ``` -------------------------------- ### Encx Supported and Problematic Data Types Source: https://github.com/hengadev/encx/blob/main/docs/TROUBLESHOOTING.md Lists of data types supported and problematic for encryption/hashing with the encx library, with examples of how to handle unsupported types. ```go // ✅ Supported types for encryption/hashing string, int, int8, int16, int32, int64 uint, uint8, uint16, uint32, uint64 float32, float64, bool []byte, []string, []int (and other slices) map[string]string, map[string]interface{} struct types // ❌ Problematic types chan int // Channels func() // Functions unsafe.Pointer // Unsafe pointers ``` ```go // ❌ Problematic type User struct { Data chan string `encx:"encrypt"` // Can't serialize channels } // ✅ Solution - use serializable representation type User struct { Data string `encx:"encrypt"` // Serialize channel data to string } ``` -------------------------------- ### Start Vault Dev Server and Enable KV v2 Source: https://github.com/hengadev/encx/blob/main/providers/secrets/hashicorp/README.md Commands to start a Vault development server with a root token and enable the KV secrets engine version 2. This setup is useful for local testing and development, allowing you to interact with Vault using basic commands. ```bash # Start Vault dev server vault server -dev -dev-root-token-id="root" # In another terminal export VAULT_ADDR='http://127.0.0.1:8200' export VAULT_TOKEN='root' # KV v2 is enabled by default at "secret/" in dev mode # You can enable it at "kv/" for consistency: vault secrets enable -version=2 kv ``` -------------------------------- ### Go Integration Tests for User Registration Flow Source: https://github.com/hengadev/encx/blob/main/examples/complete-webapp/README.md This Go test suite verifies the complete user registration and login flow, including profile retrieval. It sets up a test server, simulates API requests, and asserts expected responses and data integrity. Dependencies include standard Go testing libraries and the project's internal models. ```go // handlers/integration_test.go func TestUserRegistrationFlow(t *testing.T) { // Setup test server server := setupTestServer(t) defer server.Close() // Register user regData := models.UserRegistration{ Email: "test@example.com", Password: "securepassword", FirstName: "John", LastName: "Doe", Phone: "+1234567890", SSN: "123-45-6789", } // Test registration resp := testRequest(t, server, "POST", "/api/users/register", regData) assert.Equal(t, http.StatusOK, resp.StatusCode) // Test login loginData := map[string]string{ "email": "test@example.com", "password": "securepassword", } resp = testRequest(t, server, "POST", "/api/users/login", loginData) assert.Equal(t, http.StatusOK, resp.StatusCode) // Extract token and test profile access var loginResp map[string]interface{} json.NewDecoder(resp.Body).Decode(&loginResp) token := loginResp["token"].(string) // Test profile retrieval req := httptest.NewRequest("GET", "/api/users/profile", nil) req.Header.Set("Authorization", "Bearer " + token) resp = httptest.NewRecorder() server.ServeHTTP(resp, req) assert.Equal(t, http.StatusOK, resp.Code) var profile models.UserProfile json.NewDecoder(resp.Body).Decode(&profile) assert.Equal(t, "test@example.com", profile.Email) assert.Equal(t, "John", profile.FirstName) } ``` -------------------------------- ### CPU Profiling with Go Tooling Source: https://github.com/hengadev/encx/blob/main/docs/PERFORMANCE.md Guides on how to perform CPU profiling for Go applications using the `go test` command and `go tool pprof`. It covers running benchmarks with CPU profiling enabled, analyzing the generated profile data to identify performance bottlenecks, and common commands within the `pprof` interactive tool like `top10`, `list`, and `web`. ```bash # Run benchmarks with CPU profiling go test -bench=BenchmarkEncryptData -cpuprofile=cpu.out ./test/benchmarks # Analyze profile go tool pprof cpu.out # Commands in pprof: # - top10: Show top 10 functions by CPU time # - list EncryptData: Show line-by-line breakdown # - web: Generate call graph (requires graphviz) ``` -------------------------------- ### Collect ENCX Version Information Source: https://github.com/hengadev/encx/blob/main/docs/TROUBLESHOOTING.md Command-line instruction to retrieve the specific version of the `github.com/hengadev/encx` library being used in a Go project. This is crucial for reporting issues and ensuring compatibility. ```bash go list -m github.com/hengadev/encx ``` -------------------------------- ### Collect Go Version Information Source: https://github.com/hengadev/encx/blob/main/docs/TROUBLESHOOTING.md Command-line instruction to display the currently installed Go compiler version. This information is often required when reporting bugs or seeking support for Go-based projects. ```bash go version ``` -------------------------------- ### Unit Testing User Service with Mocks (Go) Source: https://github.com/hengadev/encx/blob/main/docs/EXAMPLES.md Demonstrates unit testing for a Go UserService using testify mocks for the encx.CryptoService. It covers setting up the mock, defining expectations, and asserting the service's behavior. ```go package service import ( "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/hengadev/encx" ) type UserService struct { crypto encx.CryptoService } func NewUserService(crypto encx.CryptoService) *UserService { return &UserService{crypto: crypto} } func (s *UserService) CreateUser(email, password string) error { user := &User{ Email: email, Password: password, } return s.crypto.ProcessStruct(context.Background(), user) } func TestUserService_CreateUser(t *testing.T) { // Create mock mockCrypto := encx.NewCryptoServiceMock() mockCrypto.On("ProcessStruct", mock.Anything, mock.MatchedBy(func(user *User) bool { return user.Email == "test@example.com" && user.Password == "secret" })).Return(nil) // Test service service := NewUserService(mockCrypto) err := service.CreateUser("test@example.com", "secret") assert.NoError(t, err) mockCrypto.AssertExpectations(t) } ``` -------------------------------- ### ENCX Crypto Initialization: Before v0.6.0 (Go) Source: https://github.com/hengadev/encx/blob/main/docs/MIGRATION_GUIDE_V0.6.0.md Illustrates the initialization of ENCX crypto with HashiCorp Vault in versions prior to v0.6.0. It shows how the Vault provider was used directly and pepper was loaded from the filesystem. Dependencies include the 'encx' and 'encx/providers/hashicorpvault' packages. ```go package main import ( "context" "log" "github.com/hengadev/encx" "github.com/hengadev/encx/providers/hashicorpvault" ) func main() { ctx := context.Background() // Initialize Vault vault, err := hashicorpvault.New() if err != nil { log.Fatal(err) } // Load pepper from filesystem pepper, err := os.ReadFile(".encx/pepper.secret") if err != nil { log.Fatal(err) } // Initialize crypto crypto, err := encx.NewCrypto(ctx, encx.WithKMSService(vault), encx.WithKEKAlias("my-app-kek"), encx.WithPepper(pepper), ) if err != nil { log.Fatal(err) } // Use crypto... } ``` -------------------------------- ### encx Package-Specific Configuration Source: https://github.com/hengadev/encx/blob/main/docs/CODE_GENERATION_GUIDE.md Example of package-specific configuration within `encx.yaml`. This allows setting options like `skip` (to disable generation for a package) or `output_dir` for custom output locations. ```yaml packages: "./models": skip: false # Generate code for this package output_dir: "./generated" # Custom output directory (optional) "./test": skip: true # Skip code generation ``` -------------------------------- ### Testing Encryption Logic in Go with ENCX Source: https://github.com/hengadev/encx/blob/main/docs/README.md Provides an example of how to set up and perform unit tests for ENCX encryption. It shows the creation of a test crypto instance, processing a User struct, and asserting that the encryption was successful and produced non-empty encrypted data. ```go func TestUserEncryption(t *testing.T) { crypto, _ := encx.NewTestCrypto(t) user := &User{Email: "test@example.com"} userEncx, err := ProcessUserEncx(ctx, crypto, user) assert.NoError(t, err) assert.NotEmpty(t, userEncx.EmailEncrypted) } ``` -------------------------------- ### Get Blob Column Type for Database Source: https://github.com/hengadev/encx/blob/main/docs/API_REFERENCE.md Returns the appropriate SQL data type for BLOB columns based on the specified `DatabaseType`. For example, returns 'BYTEA' for PostgreSQL. ```go func (dt DatabaseType) GetBlobColumnType() string ``` -------------------------------- ### Get JSON Column Type for Database Source: https://github.com/hengadev/encx/blob/main/docs/API_REFERENCE.md Returns the appropriate SQL data type for JSON columns based on the specified `DatabaseType`. For example, returns 'JSONB' for PostgreSQL. ```go func (dt DatabaseType) GetJSONColumnType() string ``` -------------------------------- ### Define Valid Encx Struct for Validation Source: https://github.com/hengadev/encx/blob/main/docs/TROUBLESHOOTING.md Go code example demonstrating the correct structure for a struct to be validated by the encx validation tool, including fields for encryption, hashing, and key management. ```go // Make sure struct follows ENCX requirements type ValidUser struct { Email string `encx:"encrypt,hash_basic"` EmailEncrypted []byte EmailHash string DEK []byte DEKEncrypted []byte KeyVersion int } ``` -------------------------------- ### Bash: Running encx-gen with Go Run Source: https://github.com/hengadev/encx/blob/main/docs/CODE_GENERATION_GUIDE.md Demonstrates how to execute the encx-gen CLI tool directly using 'go run' without prior building. This is presented as a reliable method for development and testing. ```bash # Run directly from source (no building needed) go run ./cmd/encx-gen generate . go run ./cmd/encx-gen validate -v . ``` -------------------------------- ### Process Encx Struct in Isolation for Debugging Source: https://github.com/hengadev/encx/blob/main/docs/TROUBLESHOOTING.md Go code example for creating and processing a minimal struct using encx.ProcessStruct to isolate runtime issues related to DEK management or complex struct processing. ```go // Test with minimal struct type TestUser struct { Name string `encx:"encrypt"` NameEncrypted []byte DEK []byte DEKEncrypted []byte KeyVersion int } testUser := &TestUser{Name: "Test"} err := crypto.ProcessStruct(ctx, testUser) ``` -------------------------------- ### Initialize ENCX with Simple Test KMS and In-Memory Store Source: https://github.com/hengadev/encx/blob/main/docs/MIGRATION_GUIDE_V0.6.0.md This Go code initializes the ENCX crypto service using simple test implementations for both KMS and the secret store. This is suitable for unit testing scenarios where external dependencies should be mocked. ```go kms := encx.NewSimpleTestKMS() secrets := encx.NewInMemorySecretStore() crypto, _ := encx.NewCrypto(ctx, kms, secrets, cfg) ``` -------------------------------- ### Update Vault Provider Initialization (Go) Source: https://github.com/hengadev/encx/blob/main/docs/MIGRATION_GUIDE_V0.6.0.md This snippet demonstrates the update in initializing HashiCorp Vault providers, transitioning from hashicorpvault.New to separate initializations for NewTransitService and NewKVStore. This change reflects a more granular approach to Vault service integration. ```go // Before (Vault): vault, err := hashicorpvault.New() ``` ```go // After (Vault): // Initialize both services transit, err := hashicorp.NewTransitService() if err != nil { log.Fatal(err) } kvStore, err := hashicorp.NewKVStore() if err != nil { log.Fatal(err) } ``` -------------------------------- ### Custom Integration with encx-gen (Bash) Source: https://github.com/hengadev/encx/blob/main/docs/CODE_GENERATION_GUIDE.md Provides examples of custom integration with the `encx-gen` tool, focusing on conditional execution based on validation results and error handling. Includes a dry-run option for verification. ```bash # Check if generation is needed encx-gen validate . && echo "Valid" || exit 1 # Generate with error handling encx-gen generate . || exit 1 # Verify nothing changed (for CI) encx-gen generate -dry-run . | grep "Would generate" && exit 1 || echo "Up to date" ``` -------------------------------- ### Configuration Management for encx Source: https://github.com/hengadev/encx/blob/main/docs/ARCHITECTURE.md Illustrates two methods for configuring the encx library. The first shows explicit configuration for library code using a Config struct, while the second demonstrates environment-based configuration for application code. ```go import ( "context" "github.com/hengadev/encx" ) var ctx context.Context var kms encx.KMSService var secrets encx.SecretStore // Library code - explicit config kekAlias := "my-kek-alias" pepperAlias := "my-pepper-alias" cfg := encx.Config{ KEKAlias: kekAlias, PepperAlias: pepperAlias, } crypto, _ := encx.NewCrypto(ctx, kms, secrets, cfg) // Application code - environment config crypto, _ := encx.NewCryptoFromEnv(ctx, kms, secrets) ``` -------------------------------- ### Define User Struct for encx Source: https://github.com/hengadev/encx/blob/main/docs/CODE_GENERATION_GUIDE.md Example Go struct definition demonstrating how to use encx struct tags for field encryption and hashing. It shows the `encx` tag with options like `encrypt`, `hash_basic`, and `hash_secure`. ```go package models type User struct { ID int `json:"id"` Email string `json:"email" encx:"encrypt,hash_basic"` Phone string `json:"phone" encx:"encrypt"` SSN string `json:"ssn" encx:"hash_secure"` // No companion fields needed! Code generation creates separate output struct } ``` -------------------------------- ### Go: Verify ENCX Tag Syntax Source: https://github.com/hengadev/encx/blob/main/docs/TROUBLESHOOTING.md Demonstrates correct ENCX tag syntax in Go, emphasizing the need for proper quoting and the exact tag name. It shows examples of incorrect syntax variations that can lead to fields not being processed. ```Go // ❌ Wrong syntax variations Name string `encx: "encrypt"` // Extra space Name string `enc:"encrypt"` // Wrong tag name Name string `encx:encrypt` // Missing quotes // ✅ Correct syntax Name string `encx:"encrypt"` ``` -------------------------------- ### Go: Ensure Exported Fields for ENCX Processing Source: https://github.com/hengadev/encx/blob/main/docs/TROUBLESHOOTING.md Explains the requirement for fields to be exported (start with an uppercase letter) for the ENCX library to process them in Go. It contrasts unexported fields (lowercase) which are ignored, with exported fields that are correctly processed. ```Go // ❌ Wrong - unexported field (lowercase) type User struct { name string `encx:"encrypt"` // Won't be processed } // ✅ Correct - exported field (uppercase) type User struct { Name string `encx:"encrypt"` // Will be processed } ``` -------------------------------- ### HashiCorp Vault KV Store Setup using Vault CLI Source: https://github.com/hengadev/encx/blob/main/docs/MIGRATION_GUIDE_V0.6.0.md This snippet shows how to store a base64 encoded pepper secret in a HashiCorp Vault KV store. It assumes that Vault is accessible and the necessary authentication is in place. ```bash # Ensure Vault is accessible vault kv put secret/encx/my-app-service/pepper \ value="$(cat .encx/pepper.secret | base64)" ```