{"id":13576262,"url":"https://github.com/thebugcatcher/heimdall","last_synced_at":"2026-01-18T04:38:36.476Z","repository":{"id":204056472,"uuid":"709515427","full_name":"thebugcatcher/heimdall","owner":"thebugcatcher","description":"Share secrets in a secure way with paswords, ttl, IP allowlisting and encryption","archived":false,"fork":false,"pushed_at":"2023-10-29T23:50:10.000Z","size":455,"stargazers_count":26,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-01T20:27:38.823Z","etag":null,"topics":["encryption","passwords","security","share-secrets"],"latest_commit_sha":null,"homepage":"https://heimdall.thebugcatcher.com/","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thebugcatcher.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2023-10-24T20:49:26.000Z","updated_at":"2024-12-16T18:03:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"ac454055-1ea8-47cf-aaa7-26ce8daef058","html_url":"https://github.com/thebugcatcher/heimdall","commit_stats":null,"previous_names":["spawnfest/heimdall","thebugcatcher/heimdall"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thebugcatcher%2Fheimdall","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thebugcatcher%2Fheimdall/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thebugcatcher%2Fheimdall/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thebugcatcher%2Fheimdall/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thebugcatcher","download_url":"https://codeload.github.com/thebugcatcher/heimdall/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247294261,"owners_count":20915332,"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":["encryption","passwords","security","share-secrets"],"created_at":"2024-08-01T15:01:08.583Z","updated_at":"2026-01-18T04:38:36.441Z","avatar_url":"https://github.com/thebugcatcher.png","language":"Elixir","funding_links":[],"categories":["Elixir"],"sub_categories":[],"readme":"# Heimdall\n\n[![CI](https://github.com/spawnfest/heimdall/actions/workflows/ci.yml/badge.svg)](https://github.com/spawnfest/heimdall/actions/workflows/ci.yml)\n[![Coverage: 100%](https://img.shields.io/badge/coverage-100%25-green)](https://github.com/spawnfest/heimdall/blob/main/coveralls.json#L15)\n\nA web application that lets you share sensitive data in a secure and easy way.\n\nWhether it's wanting to share a password to a team account or share your health\ninsurance subscription ID with your doctor, Heimdall has you covered.\n\nWith Heimdall instead of sharing your passwords or sensitive data via emails/texts,\nyou could instead share a short-lived link via emails/texts. These links can be configured\nto not work either after a time or after a number of reads so if someone gets a hold\noff those links later, they won't work and your information will remain secure.\n\nFurthermore, Heimdall also supports encrypting your data which means you can effectively\npassword-protect what you're sharing. So, by sharing a link to you sensitive data\nvia email and password needed to view that data via text, on top of adding an expiration\ntime to the link, you're adding several layers of security to your information. And best news is\nHeimdall makes doing all the above very easy, so it's a win-win for security and ease!\n\n[__VIDEO DEMO LINK__](https://drive.google.com/file/d/19fuT5-A-rtDx-m336HVY3zjN7yxmpjTC/view?usp=sharing)\n\n[__LIVE_SITE_LINK__](https://heimdall.thebugcatcher.com/)\n\n## Example\n\nA sender first navigates to Heimdall to create a new secret. The sender can choose\nan encryption algorithm (to encrypt the secret at rest), expiration time and\nother parameters before hitting the \"Create\" button. Upon creation, Heimdall will\ngive the sender an option to copy a shareable link to the secret. The sender can\nthen share the link with a receiver, who upon navigating to the page will be\nprompted for a password (or a key) which is needed for decrypting the secret. If\nthe receiver uses the correct key within the expiration period, the receiver\ncan get the secret.\n\nIf the receiver enters the wrong password or tries to access the link after it\nhas expired, the receiver won't be able to view the secret.\n\n[![Diagram](https://mermaid.ink/img/pako:eNqFUr1uwjAQfpWTZ3iBDAxtqmbqQNYsR3wQq_5J7QsIId6954TQFKQ2k-P7_vzZF9UGTapQib4G8i2VBg8RXeNBPmw5RKgBE9TkNcXl9jZvb6klc8yDadRjZNOaHj1DlQEVGafR2udxmcclMu4w0cyvYb3ZQFXAayRkAgRPJ0jURmI4Ge6A2QJ6LVIpnULU90jmmAnV9F_BOguVBdSSlRJwRyDni-eeSc-CxkP5cicIvi7gnTiJbepQEuwsgTX-c8JoWtosA2_FJxMmn8yQRQzDoRMpSyllxyESONJmcH-R53P9CPgg-_GBup2L-sCjOUgkYYdRYEyupxC5KPJM8bf2f52NHTy1tY_BPfQl_iWNsMlgQi4RcrjSpN7i-Rmx7FOtlKPo0Gh5jJc8b5TgHTWqkKWmPQ6WG9X4q0CHXgvrTRu5XFXs0SZaKRw41GffqoLjQDPo9qBvqOs3hAH3NA?type=png)](https://mermaid.live/edit#pako:eNqFUr1uwjAQfpWTZ3iBDAxtqmbqQNYsR3wQq_5J7QsIId6954TQFKQ2k-P7_vzZF9UGTapQib4G8i2VBg8RXeNBPmw5RKgBE9TkNcXl9jZvb6klc8yDadRjZNOaHj1DlQEVGafR2udxmcclMu4w0cyvYb3ZQFXAayRkAgRPJ0jURmI4Ge6A2QJ6LVIpnULU90jmmAnV9F_BOguVBdSSlRJwRyDni-eeSc-CxkP5cicIvi7gnTiJbepQEuwsgTX-c8JoWtosA2_FJxMmn8yQRQzDoRMpSyllxyESONJmcH-R53P9CPgg-_GBup2L-sCjOUgkYYdRYEyupxC5KPJM8bf2f52NHTy1tY_BPfQl_iWNsMlgQi4RcrjSpN7i-Rmx7FOtlKPo0Gh5jJc8b5TgHTWqkKWmPQ6WG9X4q0CHXgvrTRu5XFXs0SZaKRw41GffqoLjQDPo9qBvqOs3hAH3NA)\n\n```mermaid\nsequenceDiagram\n    actor S as Sender\n    actor R as Receiver\n\n    participant H as Heimdall\n    participant D as Database\n\n    S -\u003e\u003e H: Create a new secret with ttl and password\n    activate H\n    H --\u003e\u003e D: Stores the encrypted secret in DB\n    H -\u003e\u003e S: Gets a shareable link\n    deactivate H\n\n    S -\u003e\u003e R: Shares the link through a less secure medium\n\n    S -\u003e\u003e R: Shares the password through another medium\n\n    R -\u003e\u003e H: Navigates to the shared link and enters the password\n    activate H\n    H --\u003e\u003e D: Gets encrypted secret from DB\n    H -\u003e\u003e H: Decrypts the secret\n    H -\u003e\u003e R: Displays the secret\n    deactivate H\n```\n\nYou might think if I need to share a URL with the receiver why not just share\nthe secret directly instead of using Heimdall? Heimdall's power comes with two\nmain features:\n* Ability to share URL with TLL, max reads, IP address filtering etc\n* Ability to encrypt secret as an added layer of protection\n\n## Installation\n\n### Quick Setup for Demo/Testing (tested on Linux and Mac)\n\n__Recommeded for judges__\n\nPull the app and run with default config values:\n\n__NOTE: Make sure other already running containers don't interfere with system\nports `5432` and `4000`__\n\n* Run `make demo`\n    * This will start up docker containers needed to run the app\n    * Includes `postgres` and `phoenix` containers\n    * This is the app and this container needs to keep running\n\n* Without stopping the one above, in a separate terminal session, run `make setup`\n    * This will run the DB migrations needed and setup your app\n    * This command will probably give you an error at the end about starting\n      `Ranch` process but that's okay.\n\n* Refer to [Configurations](#configurations) sections for default values.\n\n### Proper setup\n\nKeep the following things in mind:\n\n* Ability to run Elixir or built erlang release\n\n* Postgres DB server.\n    * __Make sure to set environment variable `DATABASE_URL`__ at runtime\n\n* Check out [Configurations](#configurations) section of this README.\n    * You might want to at least tweak `ADMIN_` related env vars\n    * Set up `PHX_HOST` and `PORT` env vars accordingly\n    * Would be ideal if you could generate a new secret listed in\n      `SECRET_KEY_BASE` part of that section\n\n### Elixir (ASDF) + Postgres (via Docker)\n\nIf you have Elixir on your machine, simply pull the app locally and do the\nfollowing:\n\n* `asdf install` to install `elixir`, `erlang` and `nodejs` versions.\n    * This should install what the app needs\n\n* Run `mix deps.get` to fetch the dependencies\n\n* Make sure `docker` is started and run `make start-infra`.\n    * This will start a new postgres container. Ignore if you already have\n      postgres running.\n      * Update `HEIMDALL_DB_USERNAME`, `HEIMDALL_DB_PASSWORD`, `HEIMDALL_DB_HOST`\n        and `HEIMDALL_DB_NAME` accordingly to if you're setting up your own\n        Postgres\n\n* Run using `mix phx.server` and enjoy!\n\n### Deploy container to a Cloud Provider (example: Heroku)\n\n* This app comes up its `Dockerfile` ready for `Heroku`. Make sure to set up\n  environments as expected and deploy this to Heroku by following container\n  deployment instructions.\n\n## Features\n\n* Ability to share information as a URL with a TLL.\n* Ability to encrypt information using encryption algorithms.\n* Supported encryption algoritms:\n    * `aes_gcm`: Symmetric-key encryption. Can use any (but same) password to encrypt/send and decrypt/receive information\n    * `plaintext`: No password needed to encrypt/send or decrypt/receive\n    * `rsa`: Asymmetric-key encryption. Use public key to encrypt/send and private key to decrypt/receive information.\n* Encryption of secure information at rest (even when sharing using `plaintext` algo)\n* Ability to provide Max failed decryption attempts, after which the secret is effectively stale.\n* Ability to provide Max successful reads, after which the secret is effectively stale.\n* Ability to whitelist received IP addresses using IP Regex.\n* Auto deletion of expired secrets\n* Admin interface for ease of management (`/admin`) path\n\n\n## Configurations\n\nHeimdall is built with both ease-of-setup and _some_ configurability in mind. We know\nthat people approach security differently and will have their own use cases\nthat Heimdall could serve, so we have exposed some common configuration\nparameters for Heimdall, powered by environment variables that take affect\nat container/application start-time.\n\n| env var name                            | description                                                                                        | default     |\n|:---------------------------------------:|:--------------------------------------------------------------------------------------------------:|:-----------:|\n|`DATABASE_URL`                           | URL for the Postgres DB to be used for the app                                                     | N/A         |\n|`SECRET_KEY_BASE`                        | Secret key used by Phoenix (use `mix phx.gen.secret` for a new one)                                | \u003csomekey\u003e   |\n|`PHX_HOST`                               | Host for phoenix's use (example: `heimdall.thebugcatcher.com`)                                     | empty       |\n|`PORT`                                   | HTTP Port for phoenix's use                                                                        | 4000        |\n|`ADMIN_USER`                             | Username for HTTP Basic auth for admin interface                                                   | admin       |\n|`ADMIN_PASSWORD`                         | Password for HTTP Basic auth for admin interface                                                   | admin       |\n|`ADMIN_SECRETS_SHOW_LIMIT`               | Upper limit of number of secrets to display in Admin interface                                     | 200         |\n|`PRUNE_OLD_SECRETS`                      | Deletes expired/stale (past max attempts) secrets                                                  | true        |\n|`SECRETS_PRUNER_INTERVAL_MS`             | Time interval in milliseconds between each prune if `PRUNE_OLD_SECRETS` is `true`                  | 30000       |\n|`DELETE_QUERY_TIMEOUT_MS`                | Maximum time in milliseconds each prune query should take if `PRUNE_OLD_SECRETS` is `true`         | 1500        |\n|`SECRET_EXPIRATION_CHECK_PERIOD_MS`      | Time interval in milliseconds to check whether a secret is expired when trying to decrypt it       | 5000        |\n\n## Quality + Security\n\n* __Extensive automated tests__: Even though Heimdall is a product of a hackathon, we've made sure to test it as\n  well as we could in the given time. We've made sure to have 100% code coverage, and while we recognize it\n  doesn't mean 100% real test coverage, we still feel it speaks for the quality of the application.\n\n* __Security post decryption__: We've spent some time coming up with ways people could break into this app.\n  For example, we've leveraged `LiveView` to make sure once a secret is decrypted, we keep checking at\n  a periodic interval to make sure it cannot be viewed after it's expired. This happens even though\n  the receiver doesn't refresh the page, or forgets to close the page after decryption.\n\n* __Security post expiration__: Once a secret has expired, we've made sure to have a Pruner process to\n  delete expired secrets from the Heimdall database. It helps keep the app even more secure and also ensures\n  the performance of the app doesn't degrade over time.\n\nAnd many more security-related things we didn't have time to point out.. 😅\n\n## Naming\n\n\u003e Heimdall, Old Norse Heimdallr, in Norse mythology, the watchman of the gods\n\nJust the way Heimdall protects the Norse gods and Bifrost, the bridge between realms,\nthis app protects your sensitive data while providing a channel to share it with\nothers.\n\n\u003e ![Heimdall](https://media.giphy.com/media/XbPPSwVMWwisg/giphy.gif)\n\u003e\n\u003e Credit: giphy/gifs/marvel-thor-idris-elba-XbPPSwVMWwisg\n\n## About the Team\n\nThis app was built as part of Spawnfest 2023 by a wife + husband team: Susan Walker and Adi Iyengar.\nSusan has always been interested in Elixir and BEAM-based languages, and Adi being comfortable with\nthem thought it would be a fun couple's activity to try and build Heimdall at Spawnfest.\n\n* [@thebugcatcher](https://github.com/thebugcatcher)\n* [@susanwalker](https://github.com/susanwalker)\n\n## Similar Apps\n\n* [snappass](https://github.com/pinterest/snappass): SnapPass is a great app, but it doesn't have many of\n  Heimdall's features. It doesn't have the ability to password-protect the secret, auto-refresh after expiration,\n  IP-address whitelisting etc. Also, it's not powered by BEAM!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthebugcatcher%2Fheimdall","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthebugcatcher%2Fheimdall","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthebugcatcher%2Fheimdall/lists"}