Documentation ¶
Overview ¶
Example ¶
This example demonstrates how to use the encryption package to encrypt and decrypt data.
package main import ( "fmt" "github.com/terramate-io/hcl/v2" "github.com/terramate-io/opentofulib/internal/configs" "github.com/terramate-io/opentofulib/internal/encryption" "github.com/terramate-io/opentofulib/internal/encryption/config" "github.com/terramate-io/opentofulib/internal/encryption/keyprovider/static" "github.com/terramate-io/opentofulib/internal/encryption/method/aesgcm" "github.com/terramate-io/opentofulib/internal/encryption/registry/lockingencryptionregistry" ) var ( ConfigA = ` state { enforced = true } ` ConfigB = ` key_provider "static" "basic" { key = "6f6f706830656f67686f6834616872756f3751756165686565796f6f72653169" } method "aes_gcm" "example" { keys = key_provider.static.basic } state { method = method.aes_gcm.example } ` ) // This example demonstrates how to use the encryption package to encrypt and decrypt data. func main() { // Construct a new registry // the registry is where we store the key providers and methods reg := lockingencryptionregistry.New() if err := reg.RegisterKeyProvider(static.New()); err != nil { panic(err) } if err := reg.RegisterMethod(aesgcm.New()); err != nil { panic(err) } // Load the 2 different configurations cfgA, diags := config.LoadConfigFromString("Test Source A", ConfigA) handleDiags(diags) cfgB, diags := config.LoadConfigFromString("Test Source B", ConfigB) handleDiags(diags) // Merge the configurations cfg := config.MergeConfigs(cfgA, cfgB) // Construct static evaluator to pass additional values into encryption configuration. staticEval := configs.NewStaticEvaluator(nil, configs.RootModuleCallForTesting()) // Construct the encryption object enc, diags := encryption.New(reg, cfg, staticEval) handleDiags(diags) sfe := enc.State() // Encrypt the data, for this example we will be using the string `{"serial": 42, "lineage": "magic"}`, // but in a real world scenario this would be the plan file. sourceData := []byte(`{"serial": 42, "lineage": "magic"}`) encrypted, err := sfe.EncryptState(sourceData) if err != nil { panic(err) } if string(encrypted) == `{"serial": 42, "lineage": "magic"}` { panic("The data has not been encrypted!") } // Decrypt decryptedState, err := sfe.DecryptState(encrypted) if err != nil { panic(err) } fmt.Printf("%s\n", decryptedState) } func handleDiags(diags hcl.Diagnostics) { for _, d := range diags { println(d.Error()) } if diags.HasErrors() { panic(diags.Error()) } }
Output: {"serial": 42, "lineage": "magic"}
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultRegistry = lockingencryptionregistry.New()
Functions ¶
func IsEncryptionPayload ¶
Types ¶
type Encryption ¶
type Encryption interface { // State produces a StateEncryption overlay for encrypting and decrypting state files for local storage. State() StateEncryption // Plan produces a PlanEncryption overlay for encrypting and decrypting plan files. Plan() PlanEncryption // RemoteState produces a StateEncryption for reading remote states using the terraform_remote_state data // source. RemoteState(string) StateEncryption }
Encryption contains the methods for obtaining a StateEncryption or PlanEncryption correctly configured for a specific purpose. If no encryption configuration is present, it should return a pass through method that doesn't do anything.
func Disabled ¶
func Disabled() Encryption
func New ¶
func New(reg registry.Registry, cfg *config.EncryptionConfig, staticEval *configs.StaticEvaluator) (Encryption, hcl.Diagnostics)
New creates a new Encryption provider from the given configuration and registry.
type PlanEncryption ¶
type PlanEncryption interface { // EncryptPlan encrypts a plan file and returns the encrypted form. // // When implementing this function: // // Plan files are opaque values. You may expect a valid plan file on the input, but you can produce binary data // that is not necessarily a valid plan file. If no encryption is configured, this function should pass through // any data it receives without modification, even if the plan file is invalid. // // When using this function: // // Make sure that you pass a valid plan file as an input. Failing to provide a valid plan file may result in an // error. However, output values may not be valid plan files and you should not pass the encrypted plan file to any // additional functions that normally work with plan files. EncryptPlan([]byte) ([]byte, error) // DecryptPlan decrypts an encrypted plan file. // // When implementing this function: // // If the user has configured no encryption, pass through any input unmodified regardless if the input is a valid // plan file. If the user configured encryption, decrypt the plan file and return the decrypted plan file as a // binary without further evaluating its validity. // // When using this function: // // Pass a potentially encrypted plan file as an input, and you will receive the decrypted plan file or an error as // a result. DecryptPlan([]byte) ([]byte, error) }
PlanEncryption describes the methods that you can use for encrypting a plan file. Plan files are opaque values with no standardized format, so the encrypted form should be treated equally an opaque value.
func PlanEncryptionDisabled ¶
func PlanEncryptionDisabled() PlanEncryption
type StateEncryption ¶
type StateEncryption interface { // DecryptState decrypts a potentially encrypted state file and returns a valid JSON-serialized state file. // // When implementing this function: // // If the user configured no encryption, also return the input as-is regardless if the state file is valid. If the // user configured encryption unserialize the input as JSON and check for the presence of the field specified in the // StateEncryptionMarkerField. If the field is not present, return the input as-is and return a warning that an // unexpected unencrypted state file was encountered. Otherwise, decrypt the state file and return the decrypted // state file as serialized JSON. If the state file cannot be decrypted, return an error in the diagnostics. // // When using this function: // // After reading the state file from its source (local file, remote backend, etc.), pass in the state file to this // function. Do not attempt to determine if the state file is encrypted as this function will take care of any // and all encryption-related matters. After the function returns, use the returned byte array as a normal state // file. DecryptState([]byte) ([]byte, error) // EncryptState encrypts a state file and returns the encrypted form. // // When implementing this function: // // The file should take a JSON-serialized state file as an input and encrypt it according to the configuration. // The encrypted form should also return a JSON which contains, at least, the key specified in // StateEncryptionMarkerField to identify the state file as encrypted. This is necessary because some backends // expect a state file to always be a JSON file. // // If the user configured no encryption, this function should be a no-op and return the input unchanged. If the // input is not a valid state file, this function should return an error in the diagnostics return. // // When using this function: // // Pass in a valid JSON-serialized state file as an input and store the output. Note that you should not pass the // output to any additional functions that require a valid state file as it may not contain the fields typically // present in a state file. EncryptState([]byte) ([]byte, error) }
StateEncryption describes the interface for encrypting state files.
func StateEncryptionDisabled ¶
func StateEncryptionDisabled() StateEncryption
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
pbkdf2
Package pbkdf2 contains a key provider that takes a passphrase and emits a PBKDF2 hash of the configured length.
|
Package pbkdf2 contains a key provider that takes a passphrase and emits a PBKDF2 hash of the configured length. |
static
Package static contains a key provider that emits a static key.
|
Package static contains a key provider that emits a static key. |