dhall-secret: Encrypt Decrypt Dhall expressions

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

Please see the README on GitHub at https://github.com/jcouyang/dhall-secret#readme


[Skip to Readme]

Properties

Versions 0.4.28, 0.5.50, 0.5.52, 0.5.53
Change log ChangeLog.md
Dependencies amazonka (<1.7), amazonka-kms (<1.7), base (>=4.7 && <5), base64 (==0.3.1.1), bech32 (<1.2), bytestring (<0.11), cryptonite (<0.30), dhall (<1.40), dhall-secret, lens (<4.20), memory (<0.16), optparse-applicative (<0.17), pem (<0.3), text (<1.3), unordered-containers (<0.3) [details]
License BSD-3-Clause
Copyright 2022 Jichao Ouyang
Author Jichao Ouyang
Maintainer oyanglulu@gmail.com
Category Compiler
Home page https://github.com/jcouyang/dhall-secret#readme
Bug tracker https://github.com/jcouyang/dhall-secret/issues
Source repo head: git clone https://github.com/jcouyang/dhall-secret
Uploaded by oyanglulu at 2022-10-21T11:36:47Z

Modules

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for dhall-secret-0.4.28

[back to package description]

dhall-secret

Build and Test

A simple tool to manage secrets in Dhall configuration, inspired by sops

Install

Download binary according to your OS from releases channel, or if you have nix

nix-env -f https://github.com/jcouyang/dhall-secret/archive/master.tar.gz -iA dhall-secret.components.exes.dhall-secret

Usage

Usage: dhall-secret (encrypt | decrypt | gen-types) [-v|--version]

Available options:
-h,--help                Show this help text
-v,--version             print version

Available commands:
encrypt                  Encrypt a Dhall expression
decrypt                  Decrypt a Dhall expression
gen-types                generate types

Example

create a unencrypted version of Dhall file ./test/example.dhall, put the plain text secret in PlainText

let dhall-secret =
      https://raw.githubusercontent.com/jcouyang/dhall-secret/38fc27c7da185dda1ddae67c389080154c2336fc/Type.dhall

let empty =
      https://raw.githubusercontent.com/dhall-lang/dhall-lang/v22.0.0/Prelude/Map/empty.dhall

in  { kmsExample =
        dhall-secret.AwsKmsDecrypted
          { KeyId = "alias/dhall-secret/test"
          , PlainText = "a-secret"
          , EncryptionContext = empty Text Text
          }
    , ageSecret =
        dhall-secret.AgeDecrypted
          { Recipients =
            [ "age1rl8j26etwulmav6yn8p4huu6944n7hsr2pyu2dr0evjzsj2tq92q48arjp"
            , "age1xmcwr5gpzkaxdwz2udww7lht2j4evp4vpl0ujeu64pe5ncpsk9zqhkfw5y"
            ]
          , PlainText = "another-secret"
          }
    , somethingElse = "not-secret"
    }

The file contains two secrets to be encrypted

AWS KMS

  1. login to your AWS account, either through ~/.aws/credentials or AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY environment

  2. probably need to also export AWS_REGION=<your-kms-key-region>

Age

You will need to export AGE-SECRET-KEY to DHALL_SECRET_AGE_KEYS env to decrypt a dhall

export DHALL_SECRET_AGE_KEYS=AGE-SECRET-KEY-1GLAZ75TDSSR647WXD0MH3RUU8XGRK6R5SD8UGQ6C6R9MCYR03ULQSUC7D6
dhall-secret decrypt -f ./test/example02.encrypted.dhall

or export multiple keys in multiple lines

export DHALL_SECRET_AGE_KEYS="AGE-SECRET-KEY-1HKC2ZRPFFY66049G5EWYLT2PMYKTPN6UW6RFEEEN3JEEWTFFFDNQ2QTC8M
AGE-SECRET-KEY-1GLAZ75TDSSR647WXD0MH3RUU8XGRK6R5SD8UGQ6C6R9MCYR03ULQSUC7D6"
dhall-secret decrypt -f ./test/example02.encrypted.dhall

you don't need to have the secret key to encrypt the file.

Encrypt

from stdin

> dhall-secret encrypt
let dhall-secret =
      https://github.com/jcouyang/dhall-secret/raw/38fc27c7da185dda1ddae67c389080154c2336fc/Type.dhall

in  dhall-secret.AgeDecrypted
      { Recipients =
        [ "age1rl8j26etwulmav6yn8p4huu6944n7hsr2pyu2dr0evjzsj2tq92q48arjp" ]
      , PlainText = "hello age!"
      }
[Ctrl-D]
let dhall-secret =
      < AgeDecrypted : { PlainText : Text, Recipients : List Text }
      | AgeEncrypted : { CiphertextBlob : Text, Recipients : List Text }
      | AwsKmsDecrypted :
          { EncryptionContext : List { mapKey : Text, mapValue : Text }
          , KeyId : Text
          , PlainText : Text
          }
      | AwsKmsEncrypted :
          { CiphertextBlob : Text
          , EncryptionContext : List { mapKey : Text, mapValue : Text }
          , KeyId : Text
          }
      >

in  dhall-secret.AgeEncrypted
      { Recipients =
        [ "age1rl8j26etwulmav6yn8p4huu6944n7hsr2pyu2dr0evjzsj2tq92q48arjp" ]
      , CiphertextBlob =
          ''
          -----BEGIN AGE ENCRYPTED FILE-----
          YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMcGt0cEY1TDIyZUszbyt3
          KzFWUHVEY2prUnd3S0RTTzdZMlNaWFJJRkE0CnQ3SG1zWHRnVHlRY3F2dTlDdTEw
          dE1FVElud3RqSG9HN2VlOG1xSGtrUzQKLS0tIGQvazYzc3dCMnN4V0FsRU9sZkQ0
          UnBxVlhBYUtHNkxXR3N5S3NNR0l2WnMKThbkWEbxqbwe+2VSSk5XwtekePESIYE1
          47+XTReJ2UEt6UPqp20XmvKk
          -----END AGE ENCRYPTED FILE-----
          ''
      }

to stdout

> dhall-secret encrypt -f test/example.dhall

in place

dhall-secret encrypt -f test/example.dhall --inplace

to a new file

dhall-secret encrypt -f test/example.dhall -o test/example.encrypted.dhall

update a encrypted file

let dhall-secret = ...
in  { foo =
      { aes256 =
          dhall-secret.Aes256Encrypted
            { KeyEnvName = "MY_AES_SECRET"
            , CiphertextBlob = "QBwc5A=="
            , IV = "6HNitzH9f3xf27t99XZa9g=="
            }
      , plain = "hello world"
      }
    }
+  with foo.aes256
+       =
+      dhall-secret.Aes256Decrypted
+        { KeyEnvName = "MY_AES_SECRET", PlainText = "hello AES" }

then

dhall-secret encrypt -f test/example.dhall -i

Decrypt

to stdout

> dhall-secret decrypt -f test/example.encrypted.dhall
let dhall-secret = ...
in  { aesExample =
        dhall-secret.Aes256Decrypted
          { KeyEnvName = "MY_AES_SECRET"
          , PlainText = "another secret to be encrypted"
          }
    , kmsExample =
        dhall-secret.AwsKmsDecrypted
          { KeyId =
              "arn:aws:kms:ap-southeast-2:930712508576:key/5d2e1d54-c2e6-49a8-924d-bed828e792ed"
          , PlainText = "a secret to be encrypted"
          , EncryptionContext = [] : List { mapKey : Text, mapValue : Text }
          }
    , somethingElse = "not secret"
    }

in place

dhall-secret decrypt -f test/example.encrypted.dhall --inplace

to a new file

dhall-secret decrypt -f test/example.encrypted.dhall -o test/example.dhall

plaintext

--plaintext will output dhall without types

> dhall-secret decrypt -f ./test/example02.encrypted.dhall -p
{ foo =
  { ageSecret =
      dhall-secret.AgeDecrypted
        { Recipients =
          [ "age1rl8j26etwulmav6yn8p4huu6944n7hsr2pyu2dr0evjzsj2tq92q48arjp"
          , "age1xmcwr5gpzkaxdwz2udww7lht2j4evp4vpl0ujeu64pe5ncpsk9zqhkfw5y"
          ]
        , PlainText = "hello age!"
        }
  , plain = "hello world"
  }
}

it is very useful when you want to convert it to yaml/json

dhall-secret decrypt -f ./test/example02.encrypted.dhall -p | dhall-to-yaml
foo:
  ageSecret: "hello age!"
  plain: hello world

Re-encrypt

dhall-secret decrypt -f test/example.encrypted.dhall | dhall-secret encrypt --in-place