Skip to content
hagelsoftPublic

About

Self-hosted, locked-by-default secret vault. No key at rest. Built to be opened by someone who isn't you.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

52 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Delilah

A locked-by-default store for small, high-value secrets — seed phrases, passphrases, recovery codes, key material. It runs on hardware you already own and holds no key at rest, ever.

It is not a document store and not a password manager. It holds things you retrieve whole, and rarely. If you need to search inside it, browse it, or work with it day to day, this is the wrong program.

Status: working, not audited, not released. The format is at version 0.7. The core is built and passes its own conformance tests, including on real FIDO2 hardware — but it has had no outside review and no real-world recovery test by someone other than its author. Nothing here should hold a secret you cannot afford to lose.


What it actually does

Adding a secret needs no password. The vault publishes a write key, so anything — a script, a phone, a web form — can encrypt a new secret to it and drop it in while the vault stays sealed. This is the operation that happens most often, and requiring a ritual for it is how vaults stop being used.

Reading a secret is a deliberate act. It requires a passphrase or a hardware token, the session is short and lives only in memory, and you are told when it happens.

You cannot browse a sealed vault. The index is encrypted too, because a title like "Bitcoin cold wallet seed, 2019" is itself a secret. That is a real daily annoyance and it is the correct trade.

It can be opened without this software. A printed page and the standard age tool are enough. That is the point of the whole design: the format is the deliverable, and this program is one implementation of it.

It tells you when it is touched. The host reports key-slot fetches, manifest reads, item reads and refused requests — see the limits below for exactly what that does and does not mean.


What this does not protect you from

Read this part. A project that states its limits can be trusted about the rest; one that claims to be unbreakable cannot.

Coercion. Currently undefended. There is no duress passphrase and no decoy vault. An earlier design carried the structure for one and it was removed, because it could not be made to work: a decoy's history could not be kept plausible without handing over the key that made it a decoy. If someone can compel you, they get what you can get.

Your own machine, while the vault is open. If the computer doing the unlocking belongs to an attacker, they get what you get. No amount of design survives that.

A weak passphrase. Nothing here saves you from one.

Anyone with an account on the vault host. The daemon reports network access. It cannot see local reads — anything with filesystem access reads the vault directory without passing through it, and a read leaves no trace on a filesystem. Catching that needs operating-system auditing, which is outside this program.

Knowing whether an unlock succeeded. The host holds no key, so it can tell you someone tried — that key slots were fetched — but never whether they got in. Alerts say so rather than implying certainty. And a notification your own client sends can be switched off by whoever is holding your client.

Metadata on a stolen disk. An attacker with the directory learns that it is a Delilah vault, its identifier and public keys, when it was created, how many items it holds, roughly how large each one is, and how often it changes. Item names, notes and contents are encrypted. Sizes are rounded into buckets but not hidden.

Removing a factor does not revoke it. It rewrites one small file and leaves the vault's keys alone, so anyone who copied that file beforehand can still open the vault with the removed factor, forever. Genuinely revoking means re-keying and re-encrypting everything, which this does not do.

Hardware attackers, cold-boot and DMA attacks. There is no secure element and no tamper detection. Dedicated hardware buys things software cannot.

Guaranteed erasure of keys from memory. The implementation is written in Go, which is garbage collected, so "wipe on lock" is best-effort rather than guaranteed. Mitigated by short sessions, no swap and disabled core dumps. Not eliminated.

Supply chain. Three external dependencies sit in security-critical positions: age itself, an age plugin for hardware tokens, and a SLIP-39 implementation for paper shares. None is under this project's control or its audit.

A hostile hosting provider. This is designed to run on a machine you control. On a rented VPS the operator is outside the model.

Anything requiring the maintainer to still be around. Deliberately: no signing subscription, no certificate to expire, no server to keep paying for. A defence that lapses is worse than none, because you plan around it and discover its absence at the worst moment. The binaries are therefore unsigned, and macOS will warn you about that.

It has never been audited. Correctness is checked by conformance — running the published test vectors and decrypting a vault by hand — which catches deviation from the specification but not a flaw the specification shares.


The format is the deliverable

docs/10-Format-Specification.md describes the on-disk format independently of this program, with test vectors that can be generated and verified using nothing but age, openssl, sha256sum, jq and tr.

spec/vectors/verify.sh      # fifteen checks, stock tools, no project code

An implementation is conformant when it passes those checks against a vault it produced. That is how this project is verified, and it is why the specification is dedicated to the public domain while the code is not: anyone may implement the format, forever, without asking.


Building

make        # fmt, vet, test, build
make cross  # binaries for macOS, Linux and Windows, plus SHA256SUMS
make verify # the conformance harness

Go 1.27+. No cgo, no C compiler, no build tags. Cross-compiles to macOS from Linux, which is a requirement rather than a convenience — the person who needs this most may be using hardware you have never seen.


Licences

The code MIT — see LICENSE
The format specification and test vectors CC0-1.0 — see spec/LICENSE

The split is deliberate. A specification only some people are permitted to implement cannot outlive its software, and outliving its software is the entire point.


Name

After the portable voice encryptor Alan Turing built at Hanslope Park with Donald Bayley between 1943 and 1945. Turing ran a competition to name it; Robin Gandy's entry won, after the biblical deceiver of men. Gandy later became Turing's executor — which is precisely the person this program is designed for.

Also a dog.

About

Self-hosted, locked-by-default secret vault. No key at rest. Built to be opened by someone who isn't you.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages