# dkekey Make [DKE](https://dke.langsyn.com/) store keys on your own machine. The dashboard makes store keys in your browser. `dkekey` makes the same keys in a program you run yourself, for when you would rather not trust a page to do it, or have no browser at all: a CI job, an agent, a server. ``` dkekey mint --store notes --label ci-reader --level read --email you@example.com ``` ## What it sends, and what it does not A store key is made here, from your machine's random source. To add it to a store, `dkekey` opens the store with a key that already opens it, wraps the store's data key under the new key, and sends the account service two things: the new key's SHA-256 hash, and that wrap. The key itself is never sent. It is written to standard output, or to the file you name, and nowhere else. The key that opens the store is never sent either: only its hash, to fetch the store's wrap for it, which is opened here. Your password is never sent: it derives, here, the proof the account checks and the key your customer key is kept under, as the dashboard does. ## Getting it Releases are served, with this source and the signed digest list, at . Each release is a single binary for each of Linux, macOS and Windows, on amd64 and arm64. They need Linux 3.2 or later, macOS 12 or later, or Windows 10 or later, and nothing else installed. With them come a `SHA256SUMS` file listing their digests and two signatures over that list, made with LangSyn's two asset-signing keys: `SHA256SUMS.sig` by the Ed25519 key, and `SHA256SUMS.mldsa65.sig` by the ML-DSA-65 key, the signature scheme of FIPS 204, which is designed to stay secure against a quantum computer. Their public halves are served at and , and the same two keys sign the list of scripts the LangSyn sites serve. A download is ours only when both signatures verify. To check a download, with OpenSSL 3.5 or later (the first with ML-DSA) and the public keys saved as `asset-signing-key.pub` and `asset-signing-key.mldsa65.pub`: ``` openssl base64 -d -A -in SHA256SUMS.sig -out SHA256SUMS.sig.bin openssl pkeyutl -verify -pubin -inkey asset-signing-key.pub -rawin \ -in SHA256SUMS -sigfile SHA256SUMS.sig.bin openssl base64 -d -A -in SHA256SUMS.mldsa65.sig -out SHA256SUMS.mldsa65.sig.bin openssl pkeyutl -verify -pubin -inkey asset-signing-key.mldsa65.pub -rawin \ -in SHA256SUMS -sigfile SHA256SUMS.mldsa65.sig.bin sha256sum -c --ignore-missing SHA256SUMS ``` Each `pkeyutl` line prints `Signature Verified Successfully`. With OpenSSL 3.0 to 3.4 the first one works and the second does not, because those versions have no ML-DSA. On macOS, use `shasum -a 256 -c` for the last line. The binaries carry no Apple or Microsoft signature, so macOS and Windows warn the first time one is run. ### Building it yourself With Go 1.26 or later: ``` make test make build ``` The release binaries are built with `make dist`, which builds every platform with no C toolchain, no build paths, no build id and no version-control stamp. With the same Go release, you get the same bytes, and can compare them with `SHA256SUMS`. A release's binaries were built with the Go release `go version dkekey` names. ## Signing in Sign in one of two ways. **With your password**, for a person at a terminal: `--email ADDRESS`. The password is asked for on the terminal, with typing hidden, or read from standard input with `--password-stdin`. **With an account token**, for a program: make one in the dashboard, under Account tokens, and give it to `dkekey` in a file with `--token-file FILE`, or in the environment as `DKEKEY_TOKEN`. A token can only add keys to stores that exist, and only up to the level it was made with. It is not a key: it opens no store by itself. A token or a key is never taken as a command-line argument, where other programs on the machine could read it. `dkekey` does not follow a redirect. Every request carries your token, your session or, when signing in, your login proof, and following a redirect would send it on to whatever address the redirect names. A redirect stops the command instead, and says where it pointed. Version 0.1.0 followed them. ## Opening the store A new key wraps the store's data key, so `dkekey` has to open the store first, with a key that already opens it: - signed in with your password and given nothing else, it opens your customer key with your password, and the store with your customer key, as the dashboard does; - otherwise, give it a key with `--open-with FILE` (`-` reads standard input), or in the environment as `DKEKEY_OPEN_KEY`: either one of the store's keys (`dke_s_...`) or your customer key (`dke_c_...`). ## Levels `--level` says what the new key may do: | Level | The key may | |---|---| | `read` (the default) | answer questions, and change nothing | | `read-add` | add facts, and change or delete none already recorded | | `read-write` | add facts and revise them, and delete nothing | | `read-write-delete` | add, revise and delete; what it deletes is gone for good | A key opens one store. You can change its level or revoke it in the dashboard. A file named with `--out` must not exist yet, so a key is never written over another. On Linux and macOS it is readable by you alone. On Windows it takes the access rules of the folder it is written in, so write it in a folder only you can read, such as one under your user folder. ## Examples A person, at a terminal: ``` dkekey mint --store notes --label laptop --level read-write --email you@example.com ``` A CI job with a token, opening the store with one of its keys, and saving the new key to a file that must not exist yet: ``` DKEKEY_TOKEN=$(cat token) dkekey mint --store notes --label nightly \ --open-with notes.key --out nightly.key ``` ## The key format `dkekey version` names the format the keys it makes are in. If LangSyn moves to a new format, the account service refuses to take a key made in the old one, by name, and says to update `dkekey`, rather than taking a key that would not work. ## Exit status `0` the key was made; `1` it was not, and standard error says why; `2` the command line was wrong. ## Licence MIT. See `LICENSE`.