{"id":21399395,"url":"https://github.com/jcouyang/dhall-secret","last_synced_at":"2025-06-10T15:34:32.291Z","repository":{"id":61854771,"uuid":"454747662","full_name":"jcouyang/dhall-secret","owner":"jcouyang","description":"Manage secrets in dhall config file","archived":false,"fork":false,"pushed_at":"2025-05-20T09:06:58.000Z","size":146,"stargazers_count":11,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-20T10:25:48.920Z","etag":null,"topics":["age-encryption","aws","dhall","kms","secret-management"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jcouyang.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-02-02T11:27:43.000Z","updated_at":"2025-05-20T09:07:02.000Z","dependencies_parsed_at":"2023-10-15T05:44:07.839Z","dependency_job_id":"2a82d3f1-0d8a-487a-b517-d6901ced585a","html_url":"https://github.com/jcouyang/dhall-secret","commit_stats":{"total_commits":72,"total_committers":1,"mean_commits":72.0,"dds":0.0,"last_synced_commit":"c32a2932ec484f893edfa56da3c5020e943a8a25"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcouyang%2Fdhall-secret","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcouyang%2Fdhall-secret/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcouyang%2Fdhall-secret/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcouyang%2Fdhall-secret/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jcouyang","download_url":"https://codeload.github.com/jcouyang/dhall-secret/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcouyang%2Fdhall-secret/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259102242,"owners_count":22805436,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["age-encryption","aws","dhall","kms","secret-management"],"created_at":"2024-11-22T15:14:23.360Z","updated_at":"2025-06-10T15:34:32.265Z","avatar_url":"https://github.com/jcouyang.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dhall-secret\n[![Build and Test](https://github.com/jcouyang/dhall-secret/actions/workflows/build.yml/badge.svg)](https://github.com/jcouyang/dhall-secret/actions/workflows/build.yml)\n\nA simple tool to manage secrets in Dhall configuration, inspired by [sops](https://github.com/mozilla/sops)\n\n## Install\n### nix\n```\nnix-env -f https://github.com/jcouyang/dhall-secret/archive/master.tar.gz -iA dhall-secret.components.exes.dhall-secret\n```\n\n### binary\nDownload binary according to your OS from [releases channel](https://github.com/jcouyang/dhall-secret/releases)\n\n### docker\ndocker images are avail [here](https://github.com/jcouyang/dhall-secret/pkgs/container/dhall-secret)\n```\ndocker run ghcr.io/jcouyang/dhall-secret:latest\n```\n\n## Usage\n\n```\nUsage: dhall-secret (encrypt | decrypt | gen-types) [-v|--version]\n\nAvailable options:\n-h,--help                Show this help text\n-v,--version             print version\n\nAvailable commands:\nencrypt                  Encrypt a Dhall expression\ndecrypt                  Decrypt a Dhall expression\ngen-types                generate types\n```\n\n## Example\ncreate a unencrypted version of Dhall file `./test/example.dhall`, put the plain text secret in `PlainText`\n```dhall\nlet empty =\n      https://prelude.dhall-lang.org/Map/empty\n\nin  { kmsExample =\n        dhall-secret.AwsKmsDecrypted\n          { KeyId = \"alias/dhall-secret/test\"\n          , PlainText = \"a-secret\"\n          , EncryptionContext = empty Text Text\n          }\n    , ageSecret =\n        dhall-secret.AgeDecrypted\n          { Recipients =\n            [ \"age1rl8j26etwulmav6yn8p4huu6944n7hsr2pyu2dr0evjzsj2tq92q48arjp\"\n            , \"age1xmcwr5gpzkaxdwz2udww7lht2j4evp4vpl0ujeu64pe5ncpsk9zqhkfw5y\"\n            ]\n          , PlainText = \"another-secret\"\n          }\n    , somethingElse = \"not-secret\"\n    }\n\n```\n\nThe file contains two secrets to be encrypted\n- `a-secret` is `dhall-secret.AwsKmsDecrypted` needs to be encrypted via KMS with key id `alias/dhall-secret/test`\n- `another-secret` is a `dhall-secret.AgeDecrypted` needs to be encrypted via Age, only who from `Recipients` can decrypt the message.\n- `not-a-secret` won't be encrypted\n\n### AWS KMS\n\n1. login to your AWS account, either through `~/.aws/credentials` or `AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY` environment\n\n2. probably need to also `export AWS_REGION=\u003cyour-kms-key-region\u003e`\n\n### Age\n\nYou will need to export AGE-SECRET-KEY to `DHALL_SECRET_AGE_KEYS` env to decrypt a dhall\n```\nexport DHALL_SECRET_AGE_KEYS=AGE-SECRET-KEY-1GLAZ75TDSSR647WXD0MH3RUU8XGRK6R5SD8UGQ6C6R9MCYR03ULQSUC7D6\ndhall-secret decrypt -f ./test/example02.encrypted.dhall\n```\n\nor export multiple keys in multiple lines\n```\nexport DHALL_SECRET_AGE_KEYS=\"AGE-SECRET-KEY-1HKC2ZRPFFY66049G5EWYLT2PMYKTPN6UW6RFEEEN3JEEWTFFFDNQ2QTC8M\nAGE-SECRET-KEY-1GLAZ75TDSSR647WXD0MH3RUU8XGRK6R5SD8UGQ6C6R9MCYR03ULQSUC7D6\"\ndhall-secret decrypt -f ./test/example02.encrypted.dhall\n```\n\nyou don't need to have the secret key to encrypt the file.\n\n### Encrypt\n#### from stdin to stdout\n```\n\u003e dhall-secret encrypt\ndhall-secret.AgeDecrypted\n  { Recipients =\n    [ \"age1rl8j26etwulmav6yn8p4huu6944n7hsr2pyu2dr0evjzsj2tq92q48arjp\" ]\n    , PlainText = \"hello age!\"\n  }\n[Ctrl-D]\nlet dhall-secret =\n      https://raw.githubusercontent.com/jcouyang/dhall-secret/master/Type.dhall\n        sha256:d7b55a2f433e19cf623d58c339346a604d96989f60cffdecee125a504a068dc9\n\nin  dhall-secret.AgeEncrypted\n      { Recipients =\n        [ \"age1rl8j26etwulmav6yn8p4huu6944n7hsr2pyu2dr0evjzsj2tq92q48arjp\" ]\n      , CiphertextBlob =\n          ''\n          -----BEGIN AGE ENCRYPTED FILE-----\n          YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEUHJPRnJzV2JVL2VKTDE3\n          VFpOVFZqOHhIMlhsNCtrNjQ4ZU95cjQ1T25rCk42cFBjcVRUV3ZZYkd0dUxBakN6\n          YVNzY1k5WEtNRUJNbjI5YUs3RThlQWcKLS0tIHNObWFIZW9MR2FsekQwY0dyZ3hF\n          VmdVYzVGRDRDUWFzWTN3N3RGRWVCbG8KSwwDZ5d+O1w0U8AQB4TRdbA7V20dk2kk\n          5P1QNjxYMEyHyJKiijRyltq+\n          -----END AGE ENCRYPTED FILE-----\n          ''\n      }\n```\n\n#### encrypt file in place\n```\ndhall-secret encrypt -f test/example.dhall --inplace\n```\n#### to a new file\n```\ndhall-secret encrypt -f test/example.dhall -o test/example.encrypted.dhall\n```\n#### update a encrypted file\nyou can update a encrypted file with dhall expr without needing to decrypt the file\n```\ndhall-secret encrypt \u003c\u003c\u003c './test/example02.dhall with plain = dhall.AgeDecrypted {PlainText = \"not plain any more\", Recipients = [\"age1xmcwr5gpzkaxdwz2udww7lht2j4evp4vpl0ujeu64pe5ncpsk9zqhkfw5y\"]}'\n```\n\n### Decrypt\n#### to stdout\n```\n\u003e dhall-secret decrypt -f test/example.encrypted.dhall\nlet dhall-secret = ...\nin  { aesExample =\n        dhall-secret.Aes256Decrypted\n          { KeyEnvName = \"MY_AES_SECRET\"\n          , PlainText = \"another secret to be encrypted\"\n          }\n    , kmsExample =\n        dhall-secret.AwsKmsDecrypted\n          { KeyId =\n              \"arn:aws:kms:ap-southeast-2:930712508576:key/5d2e1d54-c2e6-49a8-924d-bed828e792ed\"\n          , PlainText = \"a secret to be encrypted\"\n          , EncryptionContext = [] : List { mapKey : Text, mapValue : Text }\n          }\n    , somethingElse = \"not secret\"\n    }\n```\n#### in place\n```\ndhall-secret decrypt -f test/example.encrypted.dhall --inplace\n```\n#### to a new file\n```\ndhall-secret decrypt -f test/example.encrypted.dhall -o test/example.dhall\n```\n#### plaintext\n`--plain-text` will output dhall without types\n```\n\u003e dhall-secret decrypt -f ./test/example02.encrypted.dhall -p\n{ foo =\n  { ageSecret =\n      dhall-secret.AgeDecrypted\n        { Recipients =\n          [ \"age1rl8j26etwulmav6yn8p4huu6944n7hsr2pyu2dr0evjzsj2tq92q48arjp\"\n          , \"age1xmcwr5gpzkaxdwz2udww7lht2j4evp4vpl0ujeu64pe5ncpsk9zqhkfw5y\"\n          ]\n        , PlainText = \"hello age!\"\n        }\n  , plain = \"hello world\"\n  }\n}\n```\nit is very useful when you want to convert it to yaml/json\n```\ndhall-secret decrypt -f ./test/example02.encrypted.dhall -p | dhall-to-yaml\nfoo:\n  ageSecret: \"hello age!\"\n  plain: hello world\n```\n### Re-encrypt\n```\ndhall-secret decrypt -f test/example.encrypted.dhall | dhall-secret encrypt --in-place\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcouyang%2Fdhall-secret","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjcouyang%2Fdhall-secret","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcouyang%2Fdhall-secret/lists"}