# 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// ``` 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// $HOME/.dat/secret_keys// ``` The public halves remain in `/.dat/metadata.key` and `/.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// ``` 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 ` prints the two keypairs as hexadecimal; treat that output as secret. `dat keys import ` 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).