### Example gRPC Key Service Server Setup Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keyservice.md Demonstrates how to set up and run a gRPC key service server. This includes creating a gRPC server, registering the key service implementation, and starting the server to listen for incoming connections. ```go import ( "net" "google.golang.org/grpc" "github.com/getsops/sops/v3/keyservice" ) // Create gRPC server grpcServer := grpc.NewServer() // Create key service keyService := &MyKeyService{} // Register key service keyservice.RegisterKeyServiceServer(grpcServer, keyService) // Listen on port listener, err := net.Listen("tcp", ":5000") if err != nil { log.Fatal(err) } // Serve if err := grpcServer.Serve(listener); err != nil { log.Fatal(err) } ``` -------------------------------- ### Install SOPS using Go Get Source: https://github.com/getsops/sops/blob/main/_autodocs/README.md Installs the SOPS library version 3 using the go get command. ```bash go get github.com/getsops/sops/v3 ``` -------------------------------- ### Initialize and Run SOPS Example Source: https://github.com/getsops/sops/blob/main/examples/all_in_one/README.rst Commands to import the test key, navigate to the example directory, and execute the decryption and application scripts. ```bash # From the `sops` root directory # Import the test key gpg --import tests/sops_functional_tests_key.asc # Navigate to our example directory cd examples/all_in_one # Decrypt our secrets bin/decrypt-config.sh # Optionally edit a secret # bin/edit-secret.sh config/secret.enc.json # Run a script that uses our decrypted secrets python main.py ``` -------------------------------- ### Initialize and Run SOPS Example Source: https://github.com/getsops/sops/blob/main/examples/per_file/README.rst Commands to import the test PGP key, navigate to the example directory, and execute the decryption and main scripts. ```bash # From the `sops` root directory # Import the test key gpg --import pgp/sops_functional_tests_key.asc # Navigate to our example directory cd examples/per_file # Decrypt our secrets bin/decrypt-config.sh # Optionally edit a secret # bin/edit-secret.sh config.enc/static_github.json # Run our script python main.py ``` -------------------------------- ### Complete Age Encryption/Decryption Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/age-keys.md Demonstrates the full lifecycle of encrypting and decrypting data using age keys with SOPS. Includes key creation, encryption, metadata setup, and decryption. ```go import ( "log" "github.com/getsops/sops/v3" "github.com/getsops/sops/v3/age" "github.com/getsops/sops/v3/aes" ) func main() { // Create age key from recipient key, err := age.MasterKeyFromRecipient("age1...") if err != nil { log.Fatal(err) } // Encrypt data key dataKey := make([]byte, 32) // ... fill with random data ... if err := key.Encrypt(dataKey); err != nil { log.Fatal(err) } // Create metadata with age key metadata := sops.Metadata{ KeyGroups: []sops.KeyGroup{{key}}, } // Create tree and encrypt values tree := &sops.Tree{ Metadata: metadata, Branches: ..., } cipher := aes.NewCipher() _, err = tree.Encrypt(dataKey, cipher) if err != nil { log.Fatal(err) } // Later, to decrypt: key.SetEncryptedDataKey(encryptedKeyFromFile) var identities age.ParsedIdentities // Load identities from default location... identities.ApplyToMasterKey(key) decryptedKey, err := key.Decrypt() if err != nil { log.Fatal(err) } _, err = tree.Decrypt(decryptedKey, cipher) if err != nil { log.Fatal(err) } } ``` -------------------------------- ### Connecting to the Key Service (Go) Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keyservice.md Example of how to establish a gRPC connection to a SOPS key service and create a client. ```APIDOC ## Connecting to a Key Service ```go import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "github.com/getsops/sops/v3/keyservice" ) // Connect to key service conn, err := grpc.Dial( "localhost:5000", grpc.WithTransportCredentials(insecure.NewCredentials()), ) if err != nil { log.Fatal(err) } defer conn.Close() // Create client client := keyservice.NewKeyServiceClient(conn) ``` ``` -------------------------------- ### Example KeyServiceClient Usage Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keyservice.md Example of how to use the KeyServiceClient to decrypt data. This involves creating a client, calling the Decrypt method with necessary parameters, and handling the response or error. ```go import ( "context" "github.com/getsops/sops/v3/keyservice" ) client := keyservice.NewKeyServiceClient(conn) resp, err := client.Decrypt(context.Background(), &keyservice.DecryptRequest{ Ciphertext: []byte("..."), KeyType: "kms", Metadata: map[string]string{"arn": "..."}, }) if err != nil { log.Fatal(err) } dataKey := resp.Plaintext ``` -------------------------------- ### Example: Convert Tree Branches to Map Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/metadata.md Demonstrates how to use EmitAsMap to get a map representation of decrypted SOPS data. ```go dataMap, err := sops.EmitAsMap(tree.Branches) if err != nil { log.Fatal(err) } // dataMap now contains the decrypted document as a Go map ``` -------------------------------- ### Tree.GenerateDataKey Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/tree.md Shows how to generate a data key and handle potential errors during the encryption process with master keys. ```go dataKey, errs := tree.GenerateDataKey() if len(errs) > 0 { for _, err := range errs { log.Printf("Key encryption error: %v", err) } } ``` -------------------------------- ### Implementing a Key Service Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keyservice.md Example implementation of the KeyService interface. This shows how to define a struct and its methods to handle Decrypt and Encrypt operations. ```go type MyKeyService struct{} func (s *MyKeyService) Decrypt(ctx context.Context, req *keyservice.DecryptRequest) (*keyservice.DecryptResponse, error) { // Decrypt the ciphertext plaintext, err := decryptKey(req.Ciphertext, req.KeyType, req.Metadata) if err != nil { return &keyservice.DecryptResponse{Error: err.Error()}, nil } return &keyservice.DecryptResponse{Plaintext: plaintext}, nil } func (s *MyKeyService) Encrypt(ctx context.Context, req *keyservice.EncryptRequest) (*keyservice.EncryptResponse, error) { // Encrypt the plaintext ciphertext, err := encryptKey(req.Plaintext, req.KeyType, req.Metadata) if err != nil { return &keyservice.EncryptResponse{Error: err.Error()}, nil } return &keyservice.EncryptResponse{Ciphertext: ciphertext}, nil } ``` -------------------------------- ### Complete SOPS File Loading Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/stores.md Demonstrates reading an encrypted YAML file, creating a store, loading the file, and extracting metadata using SOPS. ```go import ( "log" "os" "github.com/getsops/sops/v3/cmd/sops/common" "github.com/getsops/sops/v3/cmd/sops/formats" "github.com/getsops/sops/v3/config" "github.com/getsops/sops/v3/stores" ) func main() { // Read encrypted file data, err := os.ReadFile("secrets.yaml") if err != nil { log.Fatal(err) } // Create store for YAML format cfg := config.NewStoresConfig() store := common.StoreForFormat(formats.Yaml, cfg) // Load encrypted file tree, err := store.LoadEncryptedFile(data) if err != nil { log.Fatal(err) } log.Printf("Loaded SOPS file: %d key groups", len(tree.Metadata.KeyGroups)) // Extract metadata plainBranches, metadata, err := stores.ExtractMetadata( tree.Branches, stores.MetadataOpts{Flatten: stores.MetadataFlattenNone}, ) if err != nil { log.Fatal(err) } log.Printf("File version: %s", metadata.Version) log.Printf("Data key count: %d", metadata.MasterKeyCount()) } ``` -------------------------------- ### path_regex Examples Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md Illustrates different ways to use regular expressions to match file paths for SOPS encryption rules. ```yaml path_regex: '^secrets/' # Files in secrets/ directory ``` ```yaml path_regex: 'prod' # Any path containing 'prod' ``` ```yaml path_regex: '\.secrets\..*\.ya?ml$' # .secrets.prod.yaml, .secrets.staging.yml ``` -------------------------------- ### Custom Key Service Implementation (Go) Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keyservice.md Example of creating a custom key service that integrates with AWS KMS, implementing the `keyservice.KeyServiceServer` interface. ```APIDOC ## Example: Custom Key Service ```go import ( "context" "log" "net" "google.golang.org/grpc" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/kms" "github.com/getsops/sops/v3/keyservice" ) type KMSKeyService struct { kmsClient *kms.Client } func (s *KMSKeyService) Decrypt( ctx context.Context, req *keyservice.DecryptRequest, ) (*keyservice.DecryptResponse, error) { // Call AWS KMS to decrypt result, err := s.kmsClient.Decrypt(ctx, &kms.DecryptInput{ CiphertextBlob: req.Ciphertext, }) if err != nil { return &keyservice.DecryptResponse{Error: err.Error()}, nil } return &keyservice.DecryptResponse{Plaintext: result.Plaintext}, nil } func (s *KMSKeyService) Encrypt( ctx context.Context, req *keyservice.EncryptRequest, ) (*keyservice.EncryptResponse, error) { arn := req.Metadata["arn"] // Call AWS KMS to encrypt result, err := s.kmsClient.Encrypt(ctx, &kms.EncryptInput{ KeyId: aws.String(arn), Plaintext: req.Plaintext, }) if err != nil { return &keyservice.EncryptResponse{Error: err.Error()}, nil } return &keyservice.EncryptResponse{Ciphertext: result.CiphertextBlob}, nil } func main() { // Create KMS client (AWS SDK v2) cfg, err := config.LoadDefaultConfig(context.Background()) if err != nil { log.Fatal(err) } kmsClient := kms.NewFromConfig(cfg) // Create key service keyService := &KMSKeyService{kmsClient: kmsClient} // Create gRPC server grpcServer := grpc.NewServer() keyservice.RegisterKeyServiceServer(grpcServer, keyService) // Listen listener, err := net.Listen("tcp", ":5000") if err != nil { log.Fatal(err) } log.Println("Key service listening on :5000") if err := grpcServer.Serve(listener); err != nil { log.Fatal(err) } } ``` ``` -------------------------------- ### Age Keys File Format Example Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md Example of an age identities file format. Each line can be a comment (starting with #) or an age secret key. ```text # Age identities file # Created: 2023-01-01T00:00:00Z AGE-SECRET-KEY-1ABC... AGE-SECRET-KEY-1DEF... ``` -------------------------------- ### Tree.Encrypt Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/tree.md Demonstrates how to encrypt a SOPS tree using a provided data key and AES-GCM cipher. Ensure necessary imports are included. ```go import ( "github.com/getsops/sops/v3" "github.com/getsops/sops/v3/aes" ) tree := &sops.Tree{ Metadata: sops.Metadata{}, Branches: sops.TreeBranches{}, } cipher := aes.NewCipher() mac, err := tree.Encrypt(dataKey, cipher) if err != nil { log.Fatal(err) } ``` -------------------------------- ### StoreForFormat Go Function Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/stores.md Instantiates a SOPS store for a specific file format using provided configuration. Requires imports for common, formats, and config. ```go import ( "github.com/getsops/sops/v3/cmd/sops/common" . "github.com/getsops/sops/v3/cmd/sops/formats" "github.com/getsops/sops/v3/config" ) func StoreForFormat(format Format, config *config.StoresConfig) Store ``` ```go import ( "github.com/getsops/sops/v3/cmd/sops/common" . "github.com/getsops/sops/v3/cmd/sops/formats" "github.com/getsops/sops/v3/config" ) cfg := config.NewStoresConfig() store := common.StoreForFormat(Yaml, cfg) // Use store tree, err := store.LoadEncryptedFile(data) ``` -------------------------------- ### PGP Encryption Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/pgp-keys.md Demonstrates how to create a PGP MasterKey from a fingerprint, encrypt a data key, and prepare SOPS metadata for encryption. Requires importing necessary SOPS packages. ```go import ( "log" "github.com/getsops/sops/v3" "github.com/getsops/sops/v3/pgp" "github.com/getsops/sops/v3/aes" ) func main() { // Create PGP key from fingerprint key := pgp.NewMasterKeyFromFingerprint("E5E7C85F6A90B7A7EB8D2B9EF4F9C8A7B6E5D4C3") // Encrypt data key dataKey := make([]byte, 32) // ... fill with random data ... if err := key.Encrypt(dataKey); err != nil { log.Fatal(err) } // Create metadata metadata := sops.Metadata{ KeyGroups: []sops.KeyGroup{{key}}, } // Create tree and encrypt tree := &sops.Tree{ Metadata: metadata, Branches: ..., } cipher := aes.NewCipher() _, err := tree.Encrypt(dataKey, cipher) if err != nil { log.Fatal(err) } } ``` -------------------------------- ### PGP/GPG Environment Variables Example Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md Configure GPG by setting the GNUPGHOME environment variable to a custom directory and specifying the GPG_TTY for interactive prompts. ```bash export GNUPGHOME=/custom/gpg/home export GPG_TTY=$(tty) ``` -------------------------------- ### Handle SopsKeyNotFound Error Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/metadata.md Example of how to check for and handle a SopsKeyNotFound error when unsetting a branch. ```go newBranch, err := branch.Unset(path) if err != nil { if sopsErr, ok := err.(*sops.SopsKeyNotFound); ok { log.Printf("Key %v not found", sopsErr.Key) } } ``` -------------------------------- ### Catching SopsKeyNotFound Error Source: https://github.com/getsops/sops/blob/main/_autodocs/errors.md This example demonstrates how to specifically catch and handle errors when a key is not found during operations like Unset or Truncate. ```go newBranch, err := branch.Unset([]interface{}{"temp_key"}) if err != nil { if keyErr, ok := err.(*sops.SopsKeyNotFound); ok { log.Printf("Key %v not found", keyErr.Key) } } ``` -------------------------------- ### dotenv SOPS Metadata Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/stores.md Illustrates SOPS metadata storage in dotenv files using 'SOPS_' prefixed keys for configuration. ```env # Database configuration DB_PASSWORD=ENC[AES256_GCM,...] SOPS_KMS_ARN=arn:aws:kms:... SOPS_VERSION=3.7.0 ``` -------------------------------- ### INI SOPS Metadata Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/stores.md Demonstrates how SOPS metadata is represented in INI files within a dedicated '[sops]' section. ```ini [sops] kms=arn:aws:kms:... version=3.7.0 [database] password=ENC[AES256_GCM,...] ``` -------------------------------- ### NewServer Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keyservice.md Creates a new gRPC key service server instance. This is used on the server-side to register and start the key service. ```APIDOC ## NewServer Creates a new gRPC key service server. **Available in:** keyservice package ```go type Server struct { // Private fields } func NewServer() *Server ``` **Returns:** `*Server` - New key service server instance **Example:** ```go import ( "net" "google.golang.org/grpc" "github.com/getsops/sops/v3/keyservice" ) // Create gRPC server grpcServer := grpc.NewServer() // Create key service keyService := &MyKeyService{} // Register key service keyservice.RegisterKeyServiceServer(grpcServer, keyService) // Listen on port listener, err := net.Listen("tcp", ":5000") if err != nil { log.Fatal(err) } // Serve if err := grpcServer.Serve(listener); err != nil { log.Fatal(err) } ``` ``` -------------------------------- ### SOPS Configuration File Warning Example Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md Illustrates the warning message SOPS displays when it finds a '.sops.yml' file but expects '.sops.yaml'. ```text Warning: ignoring '.sops.yml' when searching for config file; the config file must be called '.sops.yaml'; using '.sops.yaml' instead ``` -------------------------------- ### GCP KMS Environment Variables Example Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md Configure GCP KMS by setting the path to your service account JSON file and the GCP project ID. ```bash export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json ``` -------------------------------- ### EmitAsMap Go Function Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/stores.md Converts SOPS tree branches into a Go map representation. Requires importing 'github.com/getsops/sops/v3'. ```go func EmitAsMap(in sops.TreeBranches) (map[string]interface{}, error) ``` ```go import "github.com/getsops/sops/v3" dataMap, err := sops.EmitAsMap(tree.Branches) if err != nil { log.Fatal(err) } // Use as Go map dbPassword := dataMap["database"].(map[string]interface{})["password"] ``` -------------------------------- ### JSON SOPS Metadata Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/stores.md Illustrates how SOPS metadata is stored within JSON files under the 'sops' key. ```json { "sops": { "kms": [...], "pgp": [...], "lastmodified": "2023-01-01T...", "mac": "ENC[...]", "version": "3.7.0" }, "database": { "password": "ENC[AES256_GCM,...]" } } ``` -------------------------------- ### SOPS Configuration File Example Source: https://github.com/getsops/sops/blob/main/_autodocs/README.md A sample .sops.yaml configuration file specifying creation rules for files matching a regex, including KMS and age key identifiers. It also configures indentation for YAML and JSON stores. ```yaml creation_rules: - path_regex: '^secrets/' kms: arn:aws:kms:us-east-1:123456789012:key/12345678-... age: age1ckxzfpxdhvxwdwvd5j0y7kkl5mh0p0v3x2lw2hxdrdvp0p5s5d2v stores: yaml: indent: 2 json: indent: 2 ``` -------------------------------- ### Configure SOPS for Multiple Environments with KMS Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md Set up SOPS to use different KMS keys for staging and production environments. Includes an example of a key group with PGP. ```yaml creation_rules: - path_regex: '^secrets/staging/' kms: arn:aws:kms:us-east-1:111111111111:key/staging - path_regex: '^secrets/production/' kms: arn:aws:kms:us-east-1:222222222222:key/production shamir_threshold: 2 key_groups: - kms: - arn: arn:aws:kms:us-east-1:222222222222:key/production - pgp: - ABCD1234EFGH5678 ``` -------------------------------- ### YAML SOPS Metadata Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/stores.md Shows the structure of SOPS metadata in YAML files, including comments and encrypted values. ```yaml # Database configuration database: password: ENC[AES256_GCM,...] sops: kms: - arn: arn:aws:kms:... enc: AQADAXe2Qx... version: '3.7.0' ``` -------------------------------- ### Complete AES Cipher Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/aes-cipher.md Demonstrates generating a data key, creating an AES cipher instance, encrypting a value, and then decrypting it. It also shows expected errors when using incorrect additional authenticated data (AAD) or an incorrect key. ```go import ( "crypto/rand" "log" "time" "github.com/getsops/sops/v3" "github.com/getsops/sops/v3/aes" ) func main() { // Generate a random data key dataKey := make([]byte, 32) if _, err := rand.Read(dataKey); err != nil { log.Fatal(err) } // Create cipher cipher := aes.NewCipher() // Encrypt a value timestamp := time.Now().UTC().Format(time.RFC3339) encrypted, err := cipher.Encrypt("password123", dataKey, timestamp) if err != nil { log.Fatal(err) } log.Printf("Encrypted: %s", encrypted) // Decrypt the value decrypted, err := cipher.Decrypt(encrypted, dataKey, timestamp) if err != nil { log.Fatal(err) } log.Printf("Decrypted: %v", decrypted) // Different AAD fails decryption wrongTimestamp := "2000-01-01T00:00:00Z" _, err = cipher.Decrypt(encrypted, dataKey, wrongTimestamp) if err != nil { log.Printf("Expected error with wrong AAD: %v", err) } // Wrong key fails decryption wrongKey := make([]byte, 32) _, err = cipher.Decrypt(encrypted, wrongKey, timestamp) if err != nil { log.Printf("Expected error with wrong key: %v", err) } } ``` -------------------------------- ### Destination Rules Example Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md Defines encryption keys to be used when rotating keys in existing files matching a specific path regex. ```yaml destination_rules: - path_regex: '^secrets/production/' kms: arn:aws:kms:us-east-1:123456789012:key/... pgp: ABCD1234... ``` -------------------------------- ### AWS KMS Environment Variables Example Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md Set AWS environment variables for authentication and region selection when using AWS KMS. This example sets the profile to 'production' and region to 'us-east-1'. ```bash export AWS_PROFILE=production export AWS_REGION=us-east-1 ``` -------------------------------- ### SOPS Key Group Encryption and Decryption Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keys.md Demonstrates creating a SOPS KeyGroup with different MasterKey implementations (age, KMS) and performing encryption and decryption operations. ```Go import ( "github.com/getsops/sops/v3" "github.com/getsops/sops/v3/age" "github.com/getsops/sops/v3/kms" ) func main() { // Create master keys ageKeys, err := age.MasterKeysFromRecipients("age1...") if err != nil { log.Fatal(err) } kmsKey := kms.NewMasterKey("arn:aws:kms:...", "", nil) // Create key group keyGroup := sops.KeyGroup{ageKeys[0], kmsKey} // Encrypt data key with both dataKey := make([]byte, 32) rand.Read(dataKey) for _, key := range keyGroup { if err := key.Encrypt(dataKey); err != nil { log.Printf("Failed to encrypt with %s: %v", key.ToString(), err) } } // Decrypt with the first available key decrypted, err := keyGroup[0].Decrypt() if err != nil { log.Fatal(err) } } ``` -------------------------------- ### Secret Splitting Example: Polynomial Evaluation Source: https://github.com/getsops/sops/blob/main/shamir/README.md An example demonstrating how to split a secret number (123) into parts using a polynomial of a specified degree (2) and threshold (2). It shows the calculation of points (parts) by evaluating the polynomial at different x values. ```mathematica y = ax^2 + bx + 123 ``` ```mathematica a = 7 b = 1 ``` ```mathematica y = 7x^2 + x + 123 ``` ```mathematica x = 1 -> y = 131 x = 2 -> y = 153 x = 3 -> y = 189 x = 4 -> y = 239 x = 5 -> y = 303 ``` -------------------------------- ### Tree.Decrypt Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/tree.md Demonstrates how to decrypt a SOPS tree using a provided data key and AES-GCM cipher. This operation verifies the MAC upon completion. ```go cipher := aes.NewCipher() computedMac, err := tree.Decrypt(dataKey, cipher) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Lookup SOPS Config File Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/config.md Searches for a SOPS configuration file starting from a given directory. Returns the result including the path and any warnings, or an error if not found. ```Go import ( "log" "github.com/getsops/sops/v3/config" ) func main() { result, err := config.LookupConfigFile(".") if err != nil { log.Fatal(err) } if result.Warning != "" { log.Printf("Warning: %s", result.Warning) } log.Printf("Found config file at: %s", result.Path) } ``` -------------------------------- ### Lagrange Interpolation Example: Polynomial Calculation Source: https://github.com/getsops/sops/blob/main/shamir/README.md A step-by-step calculation demonstrating Lagrange interpolation for three given points to derive the polynomial y = x^2. ```mathematica x_0 = 1 y_0 = 1 x_1 = 2 y_1 = 4 x_2 = 3 y_2 = 9 ``` ```mathematica L(x) = y_0 * l_0(x) + y_1 * l_1(x) + y_2 * l_2(x) ``` ```mathematica L(x) = 1 * l_0(x) + 4 * l_1(x) + 9 * l_2(x) ``` ```mathematica l_0(x) = (x - 2)/(1 - 2) * (x - 3)/(1 - 3) = 0.5x^2 - 2.5x + 3 l_1(x) = (x - 1)/(2 - 1) * (x - 3)/(2 - 3) = - x^2 + 4x - 3 l_2(x) = (x - 1)/(3 - 1) * (x - 2)/(3 - 2) = 0.5x^2 - 1.5x + 1 ``` ```mathematica L(x) = 1 * ( 0.5x^2 - 2.5x + 3) + 4 * ( -x^2 + 4x - 3) + 9 * ( 0.5x^2 - 1.5x + 1) = x^2 + 0x + 0 = x^2 ``` -------------------------------- ### Age Key Identity Environment Variables Example Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md Specify the path to your age identities file or provide a direct age identity string using environment variables. This is useful for automated environments. ```bash export SOPS_AGE_KEYFILE=/home/user/.config/sops/age/keys.txt # OR export SOPS_AGE_KEY="AGE-SECRET-KEY-1..." ``` -------------------------------- ### LoadEncryptedFile Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/stores.md Demonstrates parsing encrypted file data using a SOPS store to obtain a Tree structure. This function parses the file format, extracts metadata, and returns the tree with encrypted values without decrypting them. ```go encryptedData := []byte(`{ "sops": {...}, "password": "ENC[AES256_GCM,...]" }`) tree, err := store.LoadEncryptedFile(encryptedData) if err != nil { log.Fatal(err) } ``` -------------------------------- ### ExtractMetadata Function Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/stores.md Demonstrates how to extract SOPS metadata from tree branches using specified options. This function is crucial for separating metadata from encrypted content. ```go import ( "github.com/getsops/sops/v3/stores" "github.com/getsops/sops/v3" ) brances, metadata, err := stores.ExtractMetadata( loadedBranches, stores.MetadataOpts{Flatten: stores.MetadataFlattenNone}, ) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Implement Custom AWS KMS Key Service Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keyservice.md Provides a custom key service implementation that integrates with AWS KMS for decryption and encryption operations. This example requires AWS SDK v2. ```go import ( "context" "log" "net" "google.golang.org/grpc" "github.com/aws/aws-sdk-go-v2/service/kms" "github.com/getsops/sops/v3/keyservice" ) type KMSKeyService struct { kmsClient *kms.Client } func (s *KMSKeyService) Decrypt( ctx context.Context, req *keyservice.DecryptRequest, ) (*keyservice.DecryptResponse, error) { // Call AWS KMS to decrypt result, err := s.kmsClient.Decrypt(ctx, &kms.DecryptInput{ CiphertextBlob: req.Ciphertext, }) if err != nil { return &keyservice.DecryptResponse{Error: err.Error()}, nil } return &keyservice.DecryptResponse{Plaintext: result.Plaintext}, nil } func (s *KMSKeyService) Encrypt( ctx context.Context, req *keyservice.EncryptRequest, ) (*keyservice.EncryptResponse, error) { arn := req.Metadata["arn"] // Call AWS KMS to encrypt result, err := s.kmsClient.Encrypt(ctx, &kms.EncryptInput{ KeyId: aws.String(arn), Plaintext: req.Plaintext, }) if err != nil { return &keyservice.EncryptResponse{Error: err.Error()}, nil } return &keyservice.EncryptResponse{Ciphertext: result.CiphertextBlob}, nil } func main() { // Create KMS client (AWS SDK v2) cfg, err := config.LoadDefaultConfig(context.Background()) if err != nil { log.Fatal(err) } kmsClient := kms.NewFromConfig(cfg) // Create key service keyService := &KMSKeyService{kmsClient: kmsClient} // Create gRPC server grpcServer := grpc.NewServer() keyservice.RegisterKeyServiceServer(grpcServer, keyService) // Listen listener, err := net.Listen("tcp", ":5000") if err != nil { log.Fatal(err) } log.Println("Key service listening on :5000") if err := grpcServer.Serve(listener); err != nil { log.Fatal(err) } } ``` -------------------------------- ### LookupConfigFile Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/config.md Searches for a SOPS configuration file starting from a specified directory and moving up through parent directories. It returns the result including the path and any warnings, or an error if no configuration file is found. ```APIDOC ## LookupConfigFile ### Description Searches for a SOPS configuration file in the current directory and parent directories. ### Method Go Function ### Signature `func LookupConfigFile(start string) (ConfigFileResult, error)` ### Parameters #### Path Parameters - **start** (string) - Required - Starting directory path for the search ### Returns - **ConfigFileResult** - Contains path and optional warning - **error** - Error if no config file found ### Throws - **error** - "config file not found" if no .sops.yaml found within maxDepth (100) directories ### Example ```go import ( "log" "github.com/getsops/sops/v3/config" ) func main() { result, err := config.LookupConfigFile(".") if err != nil { log.Fatal(err) } if result.Warning != "" { log.Printf("Warning: %s", result.Warning) } log.Printf("Found config file at: %s", result.Path) } ``` ``` -------------------------------- ### Shamir's Secret Sharing with key_groups Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md Configure Shamir's Secret Sharing by explicitly defining key groups. Each group is an OR condition, and multiple groups are ANDed. This example requires 2 of the 3 defined groups to decrypt. ```yaml creation_rules: - path_regex: '^secrets/' key_groups: - kms: - arn: arn:aws:kms:us-east-1:123456789012:key/aaa - arn: arn:aws:kms:us-east-1:123456789012:key/bbb - pgp: - ABCD1234 - 5678EFGH - age: - age1abc... shamir_threshold: 2 ``` -------------------------------- ### AES Encrypted DateTime Value Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/aes-cipher.md Example of a datetime value encrypted using AES-256-GCM within SOPS. Illustrates the format for timestamp types. ```plaintext ENC[AES256_GCM,data:O0g1/YNbrt2zz/Q==,iv:cde/f4g5h6i7j==,tag:k8l9m0n1o2p3q4==,type:datetime] ``` -------------------------------- ### AES Encrypted Boolean Value Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/aes-cipher.md Example of a boolean value encrypted using AES-256-GCM within SOPS. Shows the structure for boolean types. ```plaintext ENC[AES256_GCM,data:N9f0/XMaqs1yy/Q==,iv:bcd/e3f4g5h6i==,tag:j7k8l9m0n1o2p3==,type:bool] ``` -------------------------------- ### AES Encrypted Integer Value Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/aes-cipher.md Example of an integer value encrypted using AES-256-GCM within SOPS. It demonstrates the format for numeric types. ```plaintext ENC[AES256_GCM,data:M8e9/WLZr0axx/Q==,iv:abc/d2e3f4g5h==,tag:i6j7k8l9m0n1o2==,type:int] ``` -------------------------------- ### AES Encrypted String Value Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/aes-cipher.md Example of a string value encrypted using AES-256-GCM within SOPS. It shows the structure including algorithm, data, IV, tag, and type. ```plaintext ENC[AES256_GCM,data:L7d8/VKYq9zw/Q==,iv:9b/x2c5d6e/f7g==,tag:h8i/j9k0l1m2n3==,type:str] ``` -------------------------------- ### Lookup SOPS Configuration File Programmatically Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/config.md Demonstrates how to use the SOPS Go library to find the configuration file in the current working directory. ```go import ( "log" "os" "github.com/getsops/sops/v3/config" ) func main() { cwd, err := os.Getwd() if err != nil { log.Fatal(err) } result, err := config.LookupConfigFile(cwd) if err != nil { log.Printf("No config file found: %v", err) // Proceed with defaults return } log.Printf("Using config file: %s", result.Path) if result.Warning != "" { log.Printf("Warning: %s", result.Warning) } } ``` -------------------------------- ### JSON Store Initialization and Loading Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/stores.md Shows how to create a new JSON store with custom indentation and load encrypted JSON data. This is used for handling JSON formatted encrypted files. ```go import ( "github.com/getsops/sops/v3/stores/json" "github.com/getsops/sops/v3/config" ) cfg := &config.JSONStoreConfig{Indent: 2} store := json.NewStore(cfg) // Load encrypted JSON tree, err := store.LoadEncryptedFile(data) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Get Key Type Identifier Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keys.md Returns the string identifier for the key type. Used internally for key routing and configuration. ```Go keyType := key.TypeToIdentifier() log.Printf("Key type: %s", keyType) ``` -------------------------------- ### Store Interface Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/metadata.md Combines loading, emitting, and checking capabilities for SOPS files. ```go type Store interface { LoadEncryptedFile(data []byte) (*Tree, error) LoadPlainFile(data []byte) (*Tree, error) EmitEncryptedFile(tree *Tree) ([]byte, error) EmitPlainFile(branch TreeBranches) ([]byte, error) CheckEncrypted(data []byte) (encrypted bool, err error) } ``` -------------------------------- ### Get Encrypted Data Key from MasterKey Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/age-keys.md Retrieves the encrypted data key that has been set on the MasterKey. This is useful for inspecting the encrypted payload. ```go func (key *MasterKey) EncryptedDataKey() []byte ``` -------------------------------- ### Using Key Service with SOPS Code (Go) Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keyservice.md Demonstrates how to integrate a connected key service client into SOPS decryption options. ```APIDOC ## Usage with SOPS ### 2. Via SOPS Code ```go import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "github.com/getsops/sops/v3/keyservice" "github.com/getsops/sops/v3/internal/common" "crypto/aes" ) conn, err := grpc.Dial( "localhost:5000", grpc.WithTransportCredentials(insecure.NewCredentials()), ) if err != nil { log.Fatal(err) } defer conn.Close() client := keyservice.NewKeyServiceClient(conn) // Use with DecryptTreeOpts opts := common.DecryptTreeOpts{ Tree: tree, // Assuming 'tree' is defined elsewhere KeyServices: []keyservice.KeyServiceClient{client}, Cipher: aes.NewCipher(), // Assuming AES cipher is used } dataKey, err := common.DecryptTree(opts) ``` ``` -------------------------------- ### Key Service Configuration via Environment Variables Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keyservice.md Details on how to configure SOPS to use key services by setting environment variables. ```APIDOC ## Configuration ### Environment Variables ```bash SOPS_KEYSERVICE=tcp://host:port # Single TCP service SOPS_KEYSERVICE=unix:///path/to/socket # Unix socket SOPS_ENABLE_LOCAL_KEYSERVICE=true # Also use local keys ``` Multiple services (semicolon-separated): ```bash SOPS_KEYSERVICE="tcp://ks1:5000;tcp://ks2:5000" ``` ``` -------------------------------- ### PGP/GPG Configuration for Headless Environments Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md Configure GPG for headless environments by setting GNUPGHOME, importing public and private keys. ```bash export GNUPGHOME=/path/to/gpg/home gpg --import /path/to/public/key.asc gpg --import /path/to/private/key.asc ``` -------------------------------- ### Configure SOPS Key Service via Environment Variables Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keyservice.md Shows various ways to configure SOPS key services using environment variables, including single TCP, Unix sockets, enabling local services, and multiple services. ```bash SOPS_KEYSERVICE=tcp://host:port # Single TCP service SOPS_KEYSERVICE=unix:///path/to/socket # Unix socket SOPS_ENABLE_LOCAL_KEYSERVICE=true # Also use local keys SOPS_KEYSERVICE="tcp://ks1:5000;tcp://ks2:5000" ``` -------------------------------- ### Import PGP Key from File Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/pgp-keys.md Imports a PGP key from a specified file path into the managed GPG home directory. Use this when keys are stored in separate files. ```go if err := gnuPGHome.ImportFile("/home/user/.gnupg/pubring.gpg"); err != nil { log.Fatal(err) } ``` -------------------------------- ### TreeBranch.Set Example Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/tree.md Demonstrates setting a new secret value at a nested path within a TreeBranch. The function returns the updated branch if the value was changed. ```go path := []interface{}{"database", "password"} newBranch, changed := branch.Set(path, "newsecret") if changed { log.Println("Value was updated") } ``` -------------------------------- ### Use Key Service Client with DecryptTreeOpts Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/keyservice.md Demonstrates how to use a key service client within SOPS code for decrypting data. Requires setting up the gRPC connection and client beforehand. ```go import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "github.com/getsops/sops/v3/keyservice" ) conn, err := grpc.Dial( "localhost:5000", grpc.WithTransportCredentials(insecure.NewCredentials()), ) if err != nil { log.Fatal(err) } deferr conn.Close() client := keyservice.NewKeyServiceClient(conn) // Use with DecryptTreeOpts opts := common.DecryptTreeOpts{ Tree: tree, KeyServices: []keyservice.KeyServiceClient{client}, Cipher: aes.NewCipher(), } dataKey, err := common.DecryptTree(opts) ``` -------------------------------- ### Dotenv Store Configuration Source: https://github.com/getsops/sops/blob/main/_autodocs/types.md Configuration structure for .env files. Currently has no configurable options. ```go type DotenvStoreConfig struct{} ``` -------------------------------- ### Configure SOPS with a Single KMS Key Source: https://github.com/getsops/sops/blob/main/_autodocs/configuration.md A basic SOPS configuration using a single AWS KMS key for encryption. This is suitable for simple setups. ```yaml creation_rules: - path_regex: '.*' kms: arn:aws:kms:us-east-1:123456789012:key/12345678-... ``` -------------------------------- ### ApplyToMasterKey Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/kms-keys.md Applies the credentials provider to a master key. ```APIDOC ## ApplyToMasterKey Applies the credentials provider to a master key. ### Function Signature ```go func (c CredentialsProvider) ApplyToMasterKey(key *MasterKey) ``` ### Parameters #### Path Parameters - **key** (*MasterKey) - The master key to apply the credentials provider to. ``` -------------------------------- ### Get Data Key Locally Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/metadata.md Decrypts the data key using only locally available master keys. Use this when all keys are managed within the local environment. ```go func (m Metadata) GetDataKey() ([]byte, error) ``` ```go dataKey, err := tree.Metadata.GetDataKey() if err != nil { log.Fatal("Failed to decrypt data key:", err) } ``` -------------------------------- ### Create New HTTP Client Wrapper Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/kms-keys.md Creates a wrapper for a custom HTTP client to be used with KMS operations. This allows for custom HTTP configurations like timeouts. ```go import "net/http" client := &http.Client{ Timeout: 30 * time.Second, } httpClient := kms.NewHTTPClient(client) httpClient.ApplyToMasterKey(key) ``` -------------------------------- ### KMS Encryption with Context in Go Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/kms-keys.md Demonstrates how to create a KMS master key with encryption context and use it to encrypt a data key within SOPS. Ensure the KMS key ARN and context values are correctly set for your environment. ```go import ( "log" "github.com/aws/aws-sdk-go-v2/aws" "github.com/getsops/sops/v3" "github.com/getsops/sops/v3/kms" "github.com/getsops/sops/v3/aes" ) func main() { // Create KMS key with encryption context context := map[string]*string{ "Environment": aws.String("production"), "Application": aws.String("myapp"), } key := kms.NewMasterKeyWithProfile( "arn:aws:kms:us-east-1:123456789012:key/12345678-...", "", context, "production", ) // Encrypt data key dataKey := make([]byte, 32) // ... fill with random data ... if err := key.Encrypt(dataKey); err != nil { log.Fatal(err) } // Create metadata metadata := sops.Metadata{ KeyGroups: []sops.KeyGroup{{key}}, } // Create tree and encrypt tree := &sops.Tree{ Metadata: metadata, Branches: ..., } cipher := aes.NewCipher() _, err := tree.Encrypt(dataKey, cipher) if err != nil { log.Fatal(err) } } ``` -------------------------------- ### StoreForFormat Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/stores.md Instantiates a SOPS store configured for a specific file format and store configuration. ```APIDOC ## StoreForFormat ### Description Retrieves a SOPS `Store` instance configured for a specific file format. This function is essential for initializing the correct store to handle encrypted files of a given type. ### Method `StoreForFormat` ### Signature ```go func StoreForFormat(format Format, config *config.StoresConfig) Store ``` ### Parameters #### Path Parameters - `format` (Format) - The file format enum (e.g., `Yaml`, `Json`). - `config` (*config.StoresConfig) - The store configuration. ### Returns - `Store` - An initialized `Store` instance for the specified format. ``` -------------------------------- ### Get Master Key as Map Source: https://github.com/getsops/sops/blob/main/_autodocs/api-reference/kms-keys.md Returns the KMS MasterKey details as a map, suitable for serialization. Includes ARN, creation timestamp, encrypted key, and AWS profile. ```go map[string]interface{}{ "arn": "arn:aws:kms:ப்புகளை", "created_at": "2023-01-01T...". "enc": "base64_encrypted_key", "aws_profile": "default", } ```