-
Notifications
You must be signed in to change notification settings - Fork 1k
Encrypt in a package and export method encrypt to be used in import "go.mozilla.org/sops/v3/encrypt" #1174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…go.mozilla.org/sops/v3/encrypt".
…go.mozilla.org/sops/v3/decrypt".
hiddeco
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What justifies exposing this while the underlying API mechanics are publicly available and allow you to reconstruct the behavior with precision?
|
@hiddeco appreciate for reviewing the code. What I wanted is to include sops as a library in a Go project and then use it for encryption (also decryption) but couldn't achieve that with public API. Hence, exported encrypt.Encrypt and encrypt.EncryptOpts. Have I missed something and I could do it with API? My PR allows me to do: |
|
You can absolutely achieve this using the public API by using the lower-level APIs as they are used within the (now private) encrypt function, the key service client you need to replicate SOPS is available in: Lines 14 to 17 in 7138185
With this, it should be possible using something like: // One of https://github.com/getsops/sops/tree/main/stores,
// for the file type you are working with. There are some utilities to figure
// out what store to used based on a path, see e.g.
// common.DefaultStoreForPathOrFormat()
inputStore := &yaml.Store{}
inputB := []byte(`<your bytes to encrypt>`)
branches, err := inputStore.LoadPlainFile(inputB)
if err != nil {
return nil, fmt.Errorf("could not load plain file: %w", err)
}
tree := sops.Tree{
Branches: branches,
Metadata: sops.Metadata{
// Your options from your own comment.
},
// In most scenarios, FilePath is not strictly required if you solely want to encrypt
// bytes. Internally, they are used for auditing purposes which is not really actively
// being utilized by 99% of the users.
// FilePath: "",
}
// Local client which is basically how `sops` behaves. If you want to make custom
// configurations for client secrets, etc. There is a `NewCustomLocalClient()`.
ks := keyservice.NewLocalClient()
dataKey, errs := tree.GenerateDataKeyWithKeyServices(ks)
if len(errs) > 0 {
return nil, fmt.Errorf("could not generate data key: %s", errs)
}
// Perform the encrypt operation.
if err = common.EncryptTree(common.EncryptTreeOpts{
DataKey: dataKey,
Tree: &tree,
Cipher: opts.Cipher,
}); err != nil {
return nil, err
}
// Output the encrypted bytes.
encryptedB, err := inputStore.EmitEncryptedFile(tree)
if err != nil {
return nil, fmt.Errorf("could not marshal tree: %w", err)
}Which will break you free from all sorts of assumptions around returned error codes, etc. specifically designed for the CLI, which do currently exist in the |
|
@hiddeco I think you're pointing me to the right direction. Although still not sure how to set up groups (as I did in my original solution): |
|
Key groups are for encryption instructions (and the loading looks pretty much like Line 1088 in 7b3a032
However, the further private parts are by default resolved from the runtime environment (via |
In Go projects where you need encrypting with sops it'd be nice to have a direct access to the method
func encrypt(opts encryptOpts) (encryptedFile []byte, err error)in cmd/sops/encrypt.go. In that manner you could do something like: