{"id":32529888,"url":"https://github.com/tanin47/backdoor","last_synced_at":"2026-01-22T13:38:44.643Z","repository":{"id":319956560,"uuid":"1080236974","full_name":"tanin47/backdoor","owner":"tanin47","description":"Self-hostable database querying and editing tool for you and your team. Supports Postgres, SQLite, and ClickHouse","archived":false,"fork":false,"pushed_at":"2026-01-02T07:34:40.000Z","size":10464,"stargazers_count":40,"open_issues_count":4,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-08T03:42:43.383Z","etag":null,"topics":["clickhouse","database","database-management","postgres","sqlite"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tanin47.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-21T04:27:00.000Z","updated_at":"2026-01-04T02:46:20.000Z","dependencies_parsed_at":"2025-12-06T16:01:51.353Z","dependency_job_id":null,"html_url":"https://github.com/tanin47/backdoor","commit_stats":null,"previous_names":["tanin47/backdoor"],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/tanin47/backdoor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanin47%2Fbackdoor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanin47%2Fbackdoor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanin47%2Fbackdoor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanin47%2Fbackdoor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tanin47","download_url":"https://codeload.github.com/tanin47/backdoor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tanin47%2Fbackdoor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28477507,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T03:13:13.607Z","status":"ssl_error","status_checked_at":"2026-01-16T03:11:47.863Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["clickhouse","database","database-management","postgres","sqlite"],"created_at":"2025-10-28T11:54:20.231Z","updated_at":"2026-01-22T13:38:44.619Z","avatar_url":"https://github.com/tanin47.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"Backdoor: Database Querying and Editing Tool\n==============================================================\n\n[![Sonatype Central](https://maven-badges.sml.io/sonatype-central/io.github.tanin47/backdoor/badge.png)](https://central.sonatype.com/artifact/io.github.tanin47/backdoor)\n[![Github Actions](https://github.com/tanin47/backdoor/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/tanin47/backdoor/actions/workflows/ci.yml?query=branch%3Amain)\n[![codecov](https://codecov.io/gh/tanin47/backdoor/graph/badge.svg?token=SODPQLLTDM)](https://codecov.io/gh/tanin47/backdoor)\n\n_Explore, edit, and investigate data faster and more securely with a better database tool_\n\nGet\nstarted: [\u003cins\u003eSelf-hostable version (great for teams)\u003c/ins\u003e](#self-hostable-version-great-for-teams) | [\u003cins\u003eDesktop app version (great for personal use)\u003c/ins\u003e](#desktop-app-version-great-for-personal-use) | [Website](https://backdooradmin.app)\n\nBackdoor is a database querying and editing tool for you and your team.\n\n* 🔥 __\u003cins\u003eEasy to setup:\u003c/ins\u003e__ -- Takes minutes to set up for you and your team to edit, explore, and investigate\n  data quickly.\n* 💵 __\u003cins\u003eCost Saving:\u003c/ins\u003e__ -- Reduces the need to build an admin dashboard. Saves weeks and months in effort.\n* 🔒 __\u003cins\u003eSecure:\u003c/ins\u003e__ -- Supports masked users, so you don't have to share the database credentials. The best\n  security practices\n  are implemented e.g. encrypted cookies with AES-256 and proof-of-work captcha.\n* ✨ __\u003cins\u003eModern UI:\u003c/ins\u003e__ -- Exploring and investigating large data is a breeze and enjoyable. Offers modern UI with\n  infinitely scrollable table.\n\nTry the live demo at: [backdooradmin.app](https://backdooradmin.app)\n\n| ![View and write SQL](readme/view-write.png)        | ![Filter data](readme/filter-data.png)              | ![New data source](readme/new-data-source.png) |\n|-----------------------------------------------------|-----------------------------------------------------|------------------------------------------------|\n| ![Multi Data Sources](readme/multi-data-source.png) | ![Filter data with SQL](readme/filter-data-sql.png) | ![Rename Table](readme/rename-table.png)       |\n\n### Supported Databases\n\n| Database      | Status         |\n|---------------|----------------|\n| PostgreSQL    | ✅ Supported    |\n| ClickHouse    | ✅ Supported    |\n| SQLite        | ✅ Supported    |\n| DuckDB        | 🔜 Coming Soon |\n| MySQL         | 🔜 Coming Soon |\n| Oracle        | 🔜 Coming Soon |\n| MS SQL Server | 🔜 Coming Soon |\n| IBM DB2       | 🔜 Coming Soon |\n| MariaDB       | 🔜 Coming Soon |\n\nDesktop app version (great for personal use)\n---------------------------------------------\n\n| Platform              | Direct Download                                                                                 | App Store                                                                                                                               |\n|-----------------------|-------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------|\n| MacOS (Apple Silicon) | 🟢 [Link](https://github.com/tanin47/backdoor/releases/download/desktop-1.1.3/Backdoor-1.1.dmg) | [![Download from Mac App Store](./readme/download-button.svg)](https://apps.apple.com/us/app/backdoor-database-tool/id6755612631?mt=12) |\n| Windows               | 🟢 [Link](https://github.com/tanin47/backdoor/releases/download/desktop-1.1.3/Backdoor-1.1.msi) | [![Download from Microsoft Store](https://get.microsoft.com/images/en-us%20dark.svg)](https://apps.microsoft.com/detail/xpffkhnn08lsrn) |\n| Linux                 | 🟡 In Progress                                                                                  | N/A                                                                                                                                     |\n| MacOS (Intel)         | 🔜 Coming Soon                                                                                  | 🔜 Coming Soon                                                                                                                          |\n\nPlease see our [Privacy Policy](./PRIVACY_POLICY.md)\n\nSelf-hostable version (great for teams)\n----------------------------------------\n\nThere are 3 ways:\n\n1. Run as a standalone: JAR file, Docker, and Render.com.\n2. Embed into your Java application and serve on a specific port.\n3. Embed into your Java application and serve on your main port but at a specific path.\n\nBackdoor is based on [Embeddable Java Web Framework](https://github.com/tanin47/embeddable-java-web-framework) and\npublished as a fat jar. Therefore, there is no external dependency. Its jar is self-contained and suitable for embedding\ninto your JVM application.\n\n### 1. Run as a standalone\n\n__\u003cins\u003eUse Docker\u003c/ins\u003e__\n\nThe docker image is here: https://hub.docker.com/repository/docker/tanin47/backdoor\n\n```\ndocker run -p 9999:9999 \\\n           --entrypoint \"\" \\\n           --pull always \\\n           tanin47/backdoor:web-latest \\\n           java -jar backdoor.jar \\\n           -port 9999 \\\n           -url \"postgres://127.0.0.1:5432/backdoor_test,jdbc:ch://localhost:8123?user=backdoor\u0026password=test_ch\" \\\n           -secret-key SbZlbmJIXh \\\n           -user test_user:test_pass,another_user:another_pass\n```\n\n__\u003cins\u003eRun from the JAR file\u003c/ins\u003e__\n\nFirst, you can download the `backdoor-VERSION.jar` file from\nthe [Maven Central](https://central.sonatype.com/artifact/io.github.tanin47/backdoor) page.\n\nThen, you can run the command below:\n\n```\njava -jar backdoor-VERSION.jar \\\n  -port 9999 \\\n  -url \"postgres://127.0.0.1:5432/backdoor_test,jdbc:ch://localhost:8123?user=backdoor\u0026password=test_ch\" \\\n  -secret-key SbZlbmJIXh \\\n  -user test_user:test_pass,another_user:another_pass\n```\n\nYou can visit http://localhost:9999 and login with a Postgres user, a ClickHouse user, or a masked user (e.g.\n`test_user` and `another_user`).\n\nSee FAQ for how authentication works.\n\n__\u003cins\u003eUse Render.com\u003c/ins\u003e__\n\nThe file [render.yaml](./render.yaml) shows a blueprint example of how to run Backdoor on Render.\n\n### 2. Embed and serve on a specific port\n\nFirst, you see the latest version in\nthe [Maven Central](https://central.sonatype.com/artifact/io.github.tanin47/backdoor) page.\n\nAdd the dependency to your project:\n\n```\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.tanin47\u003c/groupId\u003e\n    \u003cartifactId\u003ebackdoor\u003c/artifactId\u003e\n    \u003cversion\u003eLATEST_VERSION\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nThen, initialize Backdoor when your Java application starts:\n\n```\nvar server = new BackdoorServerBuilder()\n  .addDatabaseConfig(\"postgres\", \"postgres://127.0.0.1:5432/backdoor_test\", null, null)\n  .addDatabaseConfig(\"clickhouse\", \"jdbc:ch://localhost:8123\", \"backdoor\", \"test_ch\")\n  .withPort(9999)\n  .withSecretKey(\"SbZlbmJIXh\")\n  .addUser(\"test_user\", \"test_pass\")\n  .addUser(\"another_user\", \"another_pass\")\n  .build();\n\nserver.start();\n```\n\nThen, when your Java application stops, make sure to stop Backdoor with:\n\n```\nserver.stop();\n```\n\n### 3. Embed and serve on a specific path\n\nFirst, you must follow the steps above in order to serve Backdoor at a specific internal port.\n\nThen, you can designate a specific path and use the below code to proxy requests to Backdoor:\n\n```\nvar client = HttpClient.newHttpClient();\nvar httpRequest = HttpRequest\n  .newBuilder()\n  .uri(URI.create(\"http://localhost:9999\" + path)) \n  .method(\"GET\", HttpRequest.BodyPublishers.ofByteArray(new byte[0])) // Set the method and body in bytes\n  .headers(/* ... */) // Forward the headers as-is.    \n  .build();\nvar response = client.send(httpRequest, HttpResponse.BodyHandlers.ofByteArray());\n```\n\nThe above code uses the HTTP client offered by Java. It doesn't require any external dependency.\n\n\nFeatures\n---------\n\n* Support multi-databases.\n* Edit a field, delete a row, sort, and filter\n* Rename and drop table\n* Run arbitrary SQLs\n* Activity history (through regular logs).\n* Support its own users, so you don't have to share the database credentials.\n* Support database users e.g. logging in with Postgres or ClickHouse users.\n\nSecure your Backdoor instance\n------------------------------\n\nWhile Backdoor comes with strong security limiting the session lengths and deterring brute-force attacks through a\nProof-of-Work Captcha through [altcha](https://github.com/altcha-org/altcha), you can add more layers of security.\nHere are 2 more ways:\n\n### 1. SSH tunneling\n\nYou can block your port using a firewall and use SSH tunneling to allow you to connect to a Backdoor instance.\n\nYou can run: `ssh -L \u003clocal_port\u003e:\u003cremote_backdoor_host\u003e:\u003cremote_backdoor_port\u003e \u003cuser\u003e@\u003cssh_server\u003e` and visit:\n`http://localhost:\u003clocal_port\u003e` to access Backdoor.\n\n### 2. VPN\n\nYour company might already use VPN. It's a great option to connect to a server that hosts a Backdoor instance.\n\nThe setup might be complicated and overkilled, so I'd recommend using this option if your company already have a\nVPN. [Tailscale](https://tailscale.com/) is one example that provides a company VPN.\n\nFAQ\n-----\n\n### How does the authentication work?\n\nBackdoor supports __masked users__ and __database users__.\n\n1. __Masked users__ are the users you set on Backdoor through `BackdoorServerBuilder.addUser(..)` or `-user`.\n2. __Database users__ are the users that you set on the databases\n   e.g. [Postgres users](https://www.postgresql.org/docs/16/sql-createuser.html), [ClickHouse users](https://clickhouse.com/docs/operations/settings/settings-users).\n\nThese 2 types of users work in conjunction with the database configurations as follows:\n\n1. Any 2 type of users can login into the dashboard.\n2. Any logged-in user can access any database whose config contains valid credentials.\n3. If a database config doesn't contain credentials, then the logged-in user can click on the \"locked\" database to\n   provide valid credentials for that database.\n\nWith these combinations, you can configure the authentication to fit your needs.\n\nFor simplicity, I'd recommend using masked users and providing valid credentials in all database configurations.\n\n### How to configure the loggers?\n\nBackdoor uses `java.util.logging`. The default logging config is at\n`./web/src/main/java/resources/logging.properties`.\n\nIf you have your own log config file, you can load it using:\n\n```\ntry (var configFile = YourClass.class.getResourceAsStream(\"/YOUR_LOG_CONFIG_FILE\")) {\n  LogManager.getLogManager().readConfiguration(configFile);\n  logger.info(\"The log config) has been loaded.\");\n} catch (IOException e) {\n  logger.warning(\"Could not load the log config file: \"+e.getMessage());\n}\n```\n\nContributing\n==============\n\nHow to develop\n---------------\n\n1. Run `npm install` to install all dependencies.\n2. Change the target database URL in `tanin.backdoor.BackdoorServier.main(..)`\n2. Run `./gradlew run` in order to run the web server.\n3. On a separate terminal, run `npm run hmr` in order to hot-reload the frontend code changes.\n\nHow to run tests\n-----------------\n\n1. Run `./setup/setup_db.sh` in order to set the postgres database.\n2. Set up the ClickHouse instance as follows:\n\n- The HTTP port is 8123\n- The database `backdoor_test` is created.\n- The username is `backdoor_test`.\n- The password is `test_ch`\n\n1. Run `npm install` to install all dependencies.\n3. On a separate terminal, run `npm run hmr`.\n2. Run `./gradlew test` in order to run all the tests.\n\nPublish JAR\n------------\n\nThis flow has been set up as the Github Actions workflow: `publish-jar`.\n\n1. Run `./gradlew clean publish`. It is *IMPORTANT* to include *clean*.\n\nThe far JAR is built at `./build/libs/backdoor-VERSION.jar`\n\nYou can run your server with: `java -jar ./build/libs/backdoor-VERSION.jar`\n\nTo publish to a Maven repository, please follow the below steps:\n\n1. Set up `~/.jreleaser/config.toml` with `JRELEASER_MAVENCENTRAL_USERNAME` and `JRELEASER_MAVENCENTRAL_PASSWORD`\n2. Run `./gradlew jreleaserDeploy`\n\nTest Docker locally\n--------------------\n\nThis flow has been set up as a part of the Github Actions workflow: `create-release-web`.\n\n1. Run `./gradlew clean publish`. It is *IMPORTANT* to include *clean*.\n2. Run `docker buildx build --platform linux/amd64,linux/arm64 -t backdoor:web-latest .`\n3. Test locally with: `docker run -p 9092:9092 backdoor:web-latest -port 9092`\n\nRelease a new self-hostable version\n------------------------------------\n\n1. Create an empty release with a new tag. The tag must follow the format: `web-X.Y.Z`.\n2. Go to Actions and wait for the `create-release-web` (which is triggered automatically) workflow to finish.\n3. Test the docker with `docker run -p 9090:9090 tanin47/backdoor:web-latest -port 9090`.\n4. Go to Actions and trigger the workflow `publish-web-jar` on the tag `web-X.Y.Z` in order to publish the JAR to\n   Central Sonatype.\n\nRelease a new desktop version\n------------------------------------\n\n1. Create an empty release with a new tag. The tag must follow the format: `desktop-X.Y.Z`.\n2. Go to Actions and wait for the `create-release-desktop` (which is triggered automatically) workflow to finish.\n3. Download the DMG and test it locally.\n4. Go to Actions and trigger the workflow `publish-desktop-testflight` on the tag `desktop-X.Y.Z` in order to publish\n   the JAR to Central Sonatype.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftanin47%2Fbackdoor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftanin47%2Fbackdoor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftanin47%2Fbackdoor/lists"}