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]

A simple tool to manage secrets in Dhall configuration


[Skip to Readme]

Properties

Versions 0.5.50, 0.5.52, 0.5.53, 0.5.62
Change log None available
Dependencies amazonka (>=2.0 && <2.1), amazonka-kms (>=2.0 && <2.1), base (>=4.18.2.1 && <4.19), base64-bytestring (>=1.2.1.0 && <1.3), bech32 (>=1.1.7 && <1.2), bytestring (>=0.11.5.3 && <0.12), cryptonite (>=0.30 && <0.31), dhall (>=1.42.1 && <1.43), dhall-secret, lens (>=5.3.2 && <5.4), memory (>=0.18.0 && <0.19), optparse-applicative (>=0.18.1.0 && <0.19), pem (>=0.2.4 && <0.3), text (>=2.0.2 && <2.1), unordered-containers (>=0.2.20 && <0.3) [details]
License BSD-3-Clause
Author Jichao Ouyang
Maintainer oyanglulu@gmail.com
Category Data
Home page https://github.com/jcouyang/dhall-secret
Source repo head: git clone https://github.com/jcouyang/dhall-secret
Uploaded by oyanglulu at 2024-12-17T06:01:13Z

Modules

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for dhall-secret-0.5.62

[back to package description]

dhall-secret

Build and Test

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

Install

nix

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

binary

Download binary according to your OS from releases channel

docker

docker images are avail here

docker run ghcr.io/jcouyang/dhall-secret:latest

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 empty =
      https://prelude.dhall-lang.org/Map/empty

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 to stdout

> dhall-secret encrypt
dhall-secret.AgeDecrypted
  { Recipients =
    [ "age1rl8j26etwulmav6yn8p4huu6944n7hsr2pyu2dr0evjzsj2tq92q48arjp" ]
    , PlainText = "hello age!"
  }
[Ctrl-D]
let dhall-secret =
      https://raw.githubusercontent.com/jcouyang/dhall-secret/master/Type.dhall
        sha256:d7b55a2f433e19cf623d58c339346a604d96989f60cffdecee125a504a068dc9

in  dhall-secret.AgeEncrypted
      { Recipients =
        [ "age1rl8j26etwulmav6yn8p4huu6944n7hsr2pyu2dr0evjzsj2tq92q48arjp" ]
      , CiphertextBlob =
          ''
          -----BEGIN AGE ENCRYPTED FILE-----
          YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEUHJPRnJzV2JVL2VKTDE3
          VFpOVFZqOHhIMlhsNCtrNjQ4ZU95cjQ1T25rCk42cFBjcVRUV3ZZYkd0dUxBakN6
          YVNzY1k5WEtNRUJNbjI5YUs3RThlQWcKLS0tIHNObWFIZW9MR2FsekQwY0dyZ3hF
          VmdVYzVGRDRDUWFzWTN3N3RGRWVCbG8KSwwDZ5d+O1w0U8AQB4TRdbA7V20dk2kk
          5P1QNjxYMEyHyJKiijRyltq+
          -----END AGE ENCRYPTED FILE-----
          ''
      }

encrypt file 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

you can update a encrypted file with dhall expr without needing to decrypt the file

dhall-secret encrypt <<< './test/example02.dhall with plain = dhall.AgeDecrypted {PlainText = "not plain any more", Recipients = ["age1xmcwr5gpzkaxdwz2udww7lht2j4evp4vpl0ujeu64pe5ncpsk9zqhkfw5y"]}'

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

--plain-text 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