{"id":17310504,"url":"https://github.com/kpcyrd/d3xs","last_synced_at":"2025-04-14T14:11:46.099Z","repository":{"id":208690201,"uuid":"669647743","full_name":"kpcyrd/d3xs","owner":"kpcyrd","description":"Physical access control (Rust firmware)","archived":false,"fork":false,"pushed_at":"2023-11-29T23:12:28.000Z","size":171,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-27T23:33:32.142Z","etag":null,"topics":["embedded-rust","iot","rust","security"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kpcyrd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"github":["kpcyrd"]}},"created_at":"2023-07-23T01:15:06.000Z","updated_at":"2024-10-09T13:46:31.000Z","dependencies_parsed_at":"2023-11-27T19:27:37.310Z","dependency_job_id":"134d1297-62e1-4777-b5d9-fa10c249c790","html_url":"https://github.com/kpcyrd/d3xs","commit_stats":null,"previous_names":["kpcyrd/d3xs"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kpcyrd%2Fd3xs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kpcyrd%2Fd3xs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kpcyrd%2Fd3xs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kpcyrd%2Fd3xs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kpcyrd","download_url":"https://codeload.github.com/kpcyrd/d3xs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248894938,"owners_count":21179152,"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":["embedded-rust","iot","rust","security"],"created_at":"2024-10-15T12:37:26.811Z","updated_at":"2025-04-14T14:11:46.062Z","avatar_url":"https://github.com/kpcyrd.png","language":"Rust","funding_links":["https://github.com/sponsors/kpcyrd"],"categories":[],"sub_categories":[],"readme":"# d3xs 🔑🚪🧀\n\n**Grant access to rooms with links instead of physical keys**\n\nThis project consists of the following components:\n\n- A webserver for hosting assets and accepting websocket connections from the public internet\n- A bridge that keeps track of configuration, authorization, connects to both the public websocket server and any microcontrollers\n- A firmware for an **esp32c3** (riscv32, fairly affordable at about 6-8€ each) to control GPIO pins with a challenge/response protocol over bluetooth low energy\n\nAll components including the microcontroller firmware are written in Rust.\n\n## 🏗️ Compiling\n\nTo build this project you need:\n\n- A Rust compiler\n- pkg-config\n- make\n- The dbus library and header files (`dbus` on Arch Linux, `libdbus-1-dev` on Debian, `dbus-dev` on Alpine)\n    - For MacOS and Windows you don't need extra libraries, but are both untested\n    - For MacOS you need to give [your terminal permission to bluetooth](https://github.com/deviceplug/btleplug#macos) to fully use the d3xs-bridge binary\n- [wasm-pack](https://github.com/rustwasm/wasm-pack)\n- [cargo-espflash](https://github.com/esp-rs/espflash) (optional)\n\n```sh\ngit clone https://github.com/kpcyrd/d3xs\ncd d3xs\nmake binaries\n```\n\nIt's also possible to build just the bridge without needing `wasm-pack`:\n\n```sh\ngit clone https://github.com/kpcyrd/d3xs\ncd d3xs\ncargo build --release --locked -p d3xs-bridge\n```\n\nThe built binaries are then available at `./target/release/d3xs` and `./target/release/d3xs-bridge` respectively. You can copy them to `/usr/bin/` or `~/bin/` in your home folder.\n\n## 🔑 Generating a bridge key\n\nWith the `d3xs-bridge` binary you can now generate yourself a bridge key (this is also the starting point of your configuration file):\n\n```\n$ d3xs-bridge keygen --bridge\n[system]\n# public_key = \"cW49lkXDeM0wOT8N7QxAWePmWs8xZK1FXt1uQT/pcG4=\"\nsecret_key = \"D6Ir3Ql7jYStdzIiIgCEZuc0L/TFNqQhH08kSNP3gpM=\"\n```\n\nSee `example.toml` for further configuration.\n\n## 📟 Compiling and flashing firmware\n\nThe firmware has the relevant keypairs baked into itself, so they need to be provided in environment variables during build. You can generate one like this:\n\n```\n$ d3xs-bridge keygen --firmware\n# [doors.building]\n# label = \"Building\"\n# mac = \"ec:da:3b:ff:ff:ff\"\n# public_key = \"iNg2AUD8ONIHzqd7jqJt9aP8k04o1ZyZ7UyCo5OQmDQ=\"\nD3XS_DOOR_KEY=\"w/CSnPJnWTaEIYpEvXvF+ktwh236iSDZfSx6hExB4bM=\"\n```\n\nThe output outputs a secret key and example configuration on how to add this microcontroller to your configuration file.\n\nBuilding the firmware using the secret key we just generated, and the bridge key of the previous step:\n\n```sh\nD3XS_DOOR_KEY=\"w/CSnPJnWTaEIYpEvXvF+ktwh236iSDZfSx6hExB4bM=\" \\\nD3XS_BRIDGE_KEY=\"cW49lkXDeM0wOT8N7QxAWePmWs8xZK1FXt1uQT/pcG4=\" \\\nmake firmware\n```\n\nIf `D3XS_DOOR_KEY` is not provided, a random one will be generated during build, the public key can be read from serial output during boot (as well as the bluetooth mac address). The `D3XS_BRIDGE_KEY` variable however is important or you won't be able to send any commands to the microcontroller.\n\nYou can also customize the bluetooth name by adding something like `D3XS_BLE_NAME=d3xs1`.\n\nTo flash the firmware to an attached esp32c3 use:\n\n```sh\n$ espflash flash target-firmware/riscv32imc-esp-espidf/release/d3xs-firmware --monitor\n```\n\nWith `--monitor` espflash is automatically going to open the serial interface after flashing to read the boot log, this flag is optional and can be omitted though.\n\nFor more documentation see the [firmware folder](firmware/).\n\n## 👥 Adding users\n\nTo add a user you can generate them a keypair:\n\n```\n$ d3xs-bridge keygen -pn alice\n[users.alice]\n# https://example.com/alice#ctkuV7vV8lSv6EpZt/e9tR9l1NqjF9A4Le8W8VlyZoQ=\npublic_key = \"Ewok6RkMPbwbN3Vvdq5ajImlqks9uoBTvPBCfzOYKSg=\"\nauthorize = []\n```\n\nTo grant access to rooms add the room id to the `authorize` list. Your final configuration may look like this:\n\n```toml\n[system]\n# public_key = \"cW49lkXDeM0wOT8N7QxAWePmWs8xZK1FXt1uQT/pcG4=\"\nsecret_key = \"D6Ir3Ql7jYStdzIiIgCEZuc0L/TFNqQhH08kSNP3gpM=\"\n\n[doors.home]\nlabel = \"Home\"\nmac = \"ec:da:3b:ff:ff:ff\"\npublic_key = \"iNg2AUD8ONIHzqd7jqJt9aP8k04o1ZyZ7UyCo5OQmDQ=\"\n\n[users.alice]\n# https://example.com/alice#ctkuV7vV8lSv6EpZt/e9tR9l1NqjF9A4Le8W8VlyZoQ=\npublic_key = \"Ewok6RkMPbwbN3Vvdq5ajImlqks9uoBTvPBCfzOYKSg=\"\nauthorize = [\"home\"]\n```\n\nThe bridge automatically syncs the relevant parts of the configuration to the public webserver.\n\n## ☁️ Setting up network access\n\nThe d3xs binary contains a webserver with embedded assets for the web interface. It has no configuration besides the port to bind to, and a uuid that is used as shared secret to authenticate the bridge.\n\n```sh\nd3xs -B 127.0.0.1:5000 2120a559-2fbd-4595-be57-4e78changeme\n```\n\nFor security reasons this interface should be secured with https instead of exposing it directly to the network.\n\nAfter this is setup you can start the bridge and connect it to the public webserver:\n\n```sh\nd3xs-bridge connect --config example.toml wss://example.com/bridge/2120a559-2fbd-4595-be57-4e78changeme\n```\n\nThe url can also be configured in the config file:\n\n```toml\n[bridge]\n# public_key = \"cW49lkXDeM0wOT8N7QxAWePmWs8xZK1FXt1uQT/pcG4=\"\nsecret_key = \"D6Ir3Ql7jYStdzIiIgCEZuc0L/TFNqQhH08kSNP3gpM=\"\nurl = \"wss://example.com/bridge/2120a559-2fbd-4595-be57-4e78changeme\"\n```\n\nTo start the bridge automatically at boot there's a reference openrc config at `contrib/d3xs-bridge.init`.\n\n## ⚖️ License\n\n`GPL-3.0-or-later`\n\nTHERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkpcyrd%2Fd3xs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkpcyrd%2Fd3xs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkpcyrd%2Fd3xs/lists"}