ddat interop with dat js cable interop with cabal js ddat's frontend = dat-thang cable fe = cable-thang dillo support based on cel's dillo-dat bootstrap node xplatform support Signed-off-by: divo <418@cryspace.space>
86 lines
4.1 KiB
Markdown
86 lines
4.1 KiB
Markdown
# Archive addresses, keys, and write access
|
|
|
|
## ELI5
|
|
|
|
A Dat address is like a mailbox number that is also a read capability: anyone
|
|
who knows it can request the archive. The address is not the pen. The private
|
|
metadata signing key is the pen that lets a writer append new archive history.
|
|
Dat Desktop's `dat-node` exposes this distinction as `archive.writable`; its
|
|
file importer requires a writable archive. A reader can download and serve the
|
|
archive without being able to change its history.
|
|
|
|
The historical address
|
|
`dat://59d8099399510e23a3c693fb5887b7bba1586f4117f7ef1c5872622ada0c1181`
|
|
contains the public metadata key. It does not contain or reveal the private
|
|
signing key. Losing that secret does not make the archive unreadable; it means
|
|
you cannot write as its existing owner. Making a new keypair creates a different
|
|
archive address. Dat's original archive model is single-writer: a reader does
|
|
not gain write permission by downloading a copy.
|
|
|
|
## How Dat Desktop stores the secret
|
|
|
|
Dat Desktop's `dat-secret-storage` indexes each Hypercore feed's secret by its
|
|
**discovery key**, not by the `dat://` metadata public key. The discovery key
|
|
is BLAKE2b of `hypercore`, keyed by that feed's public key. The Unix path is
|
|
sharded:
|
|
|
|
```text
|
|
$HOME/.dat/secret_keys/<first-two-discovery-key-hex>/<remaining-discovery-key-hex>
|
|
```
|
|
|
|
The file is random-access storage for the feed's raw 64-byte Ed25519 secret.
|
|
The C client reads and writes that same file path and byte format. Dat Desktop
|
|
also uses a separate local owner marker to avoid competing local writers; the
|
|
C client does not currently maintain that marker. See the
|
|
[archived dat-secret-storage implementation](https://github.com/dat-ecosystem-archive/dat-secret-storage/blob/master/index.js)
|
|
and [dat-storage documentation](https://www.skypack.dev/view/dat-storage).
|
|
|
|
## What this C implementation does
|
|
|
|
The C implementation now uses the same per-feed discovery-key paths and raw
|
|
64-byte secret format. Both the metadata feed and content feed have their own
|
|
files:
|
|
|
|
```text
|
|
$HOME/.dat/secret_keys/<first-two-metadata-discovery-hex>/<remaining-metadata-discovery-hex>
|
|
$HOME/.dat/secret_keys/<first-two-content-discovery-hex>/<remaining-content-discovery-hex>
|
|
```
|
|
|
|
The public halves remain in `<archive>/.dat/metadata.key` and
|
|
`<archive>/.dat/content.key`. The C client validates each secret against its
|
|
matching public key before using it. This discovery-key layout and raw secret
|
|
file format are the sole supported secret store.
|
|
|
|
When the C client opens an archive, its public metadata remains readable
|
|
without local signing keys. Writing requires the matching metadata and content
|
|
keypairs in the C secret directory, plus normal operating-system write access
|
|
to the local archive directory. A local filesystem being writable does not
|
|
grant Dat write authority; the matching signing secrets are still required.
|
|
Conversely, having the secrets does not override read-only filesystem
|
|
permissions.
|
|
|
|
## Finding the historical key
|
|
|
|
The historical metadata secret's Dat Desktop path is derived from the address
|
|
above. Compute its `hypercore` discovery key, then use:
|
|
|
|
```text
|
|
$HOME/.dat/secret_keys/<first-two-metadata-discovery-hex>/<remaining-metadata-discovery-hex>
|
|
```
|
|
|
|
The matching content-feed secret is stored by its own content discovery key.
|
|
The C implementation searches both paths directly; it does not need a
|
|
conversion step for Dat Desktop's raw secret files. Preserve the original
|
|
`~/.dat/secret_keys` tree while testing access.
|
|
|
|
`dat keys export <archive-directory>` prints the two keypairs as hexadecimal;
|
|
treat that output as secret. `dat keys import <metadata-keypair-hex>
|
|
<content-keypair-hex> <archive-directory>` checks that both public halves match
|
|
the archive before saving their secret bytes in the shared format. Importing newly generated
|
|
keypairs cannot restore write access to an existing address.
|
|
|
|
For context, the archived [dat-node documentation](https://awesome.datproject.org/dat-node)
|
|
describes `archive.writable` and notes that importing files requires a writable
|
|
archive. The historical Dat model is single-writer; see the
|
|
[Dat security FAQ](https://dat-ecosystem.github.io/docs/docs/security-faq).
|