No description
  • Swift 39.5%
  • Assembly 22.2%
  • C 16.1%
  • C++ 14.9%
  • Nix 1.8%
  • Other 5.2%
Find a file
gpt-5.3-codex 1f12269f65
Some checks failed
Deploy: API / Deploy (push) Failing after 4s
Publish: Store Uploads By Tag / Dispatch Publish Workflow (push) Successful in 0s
Build: Web / Build & Test (push) Failing after 41s
Deploy: Web / Deploy (push) Successful in 47s
ci(key.store): add publish-tag dispatch path for build replays
2026-02-27 23:19:26 -08:00
.codex key.store: rebase on key.store-9 and integrate codex + Sparkle + F-Droid 2026-01-19 05:52:44 -08:00
.forgejo ci(key.store): add publish-tag dispatch path for build replays 2026-02-27 23:19:26 -08:00
Android android(key.store): add packaged launcher icons for play uploads 2026-02-24 02:49:08 -08:00
API key.store: remove GitHub Actions references 2026-02-07 18:35:58 -08:00
Apple apple(key.store): guard smoke test with canImport(XCTest) 2026-02-24 03:20:53 -08:00
config key.store: enable forge-next dns tls and repair nix cache signing key 2026-02-22 02:07:04 -08:00
docs meta(key.store): rename agent display name to gpt-5.3-codex 2026-02-24 02:27:34 -08:00
evolution ci(key.store): add publish-tag dispatch path for build replays 2026-02-27 23:19:26 -08:00
finances key.store: repair android, linux swift, and finance workflow inputs 2026-02-20 20:10:20 -08:00
forgejo Align secret tiers and email tooling 2025-12-24 18:09:27 -08:00
gradle Add Android Play publishing workflow 2025-12-21 10:50:35 -08:00
Linux/App key.store: fix flatpak + deploy-web pipeline failures 2026-02-17 23:59:51 -08:00
nixos ci(key.store): fix blob release paths and tester distribution defaults 2026-02-24 01:41:54 -08:00
notes Fill business metadata and wire Fava decrypt 2026-01-20 01:32:53 -08:00
org key.store: route Plane by assignee; add feedback/support/security/privacy aliases 2026-02-08 00:57:39 -08:00
Packages key.store: remove GitHub Actions references 2026-02-07 18:35:58 -08:00
records Update nix cache, identities, and governance terms 2026-02-01 01:29:14 -08:00
Scripts ci(key.store): harden build 15 re-publish path and add build diff tooling 2026-02-27 23:13:34 -08:00
secrets release(key.store): rotate compromised sparkle signing key 2026-02-23 20:36:10 -08:00
services key.store: unblock release + deploy-api; remove apple matrix cap 2026-02-23 08:25:01 -08:00
skills key.store: prioritize linq tasks and enforce serial roles 2026-02-08 19:57:57 -08:00
store-metadata key.store: automate Play closed-testing publish path 2026-02-24 21:47:57 -08:00
Web release(key.store): publish android apk/aab pointers and enforce web sourcemaps 2026-02-24 02:42:33 -08:00
.envrc key.store web: product branding page 2026-02-06 18:44:55 -08:00
.git_allowed_signers Update nix cache, identities, and governance terms 2026-02-01 01:29:14 -08:00
.gitattributes key.store: add web typography fonts via lfs 2026-01-31 01:55:44 -08:00
.gitignore key.store: fix nscloud cache mounting 2026-02-16 16:08:11 -05:00
.gitmodules Add Sparkle + F-Droid release infrastructure 2026-01-17 22:41:34 -08:00
.lfsconfig key.store: let Git LFS use remote URL 2026-02-07 18:35:58 -08:00
.swiftlint.yml key.store: exclude Apple/External from SwiftLint 2026-02-23 12:28:36 -08:00
AGENTS.md key.store: rebase on key.store-9 and integrate codex + Sparkle + F-Droid 2026-01-19 05:52:44 -08:00
biome.json Update Biome config and fix Linux workflow 2025-11-27 02:21:06 -05:00
build.gradle.kts Add Android app scaffolding and Swift bridge 2025-12-21 10:50:35 -08:00
bun.lock key.store: add /app web client passkey sign-in 2026-02-07 00:09:46 -08:00
bunfig.toml wip 2025-11-27 01:24:26 -05:00
CONSTITUTION.md Add key.store constitution 2025-12-24 18:09:26 -08:00
CONTRIBUTORS.md key.store: add role mailbox identities + aliases for stalwart directory 2026-02-08 00:57:38 -08:00
contributors.nix meta(key.store): rename agent display name to gpt-5.3-codex 2026-02-24 02:27:34 -08:00
flake.lock build(key.store): refresh nixpkgs lock hash for apple runners 2026-02-23 21:01:00 -08:00
flake.nix ci(key.store): fix sourcemap reference gate in web container build 2026-02-24 02:54:59 -08:00
gradle.properties key.store: fix blob endpoint + increase gradle heap for android release 2026-02-08 18:37:54 -08:00
gradlew Add Android app scaffolding and Swift bridge 2025-12-21 10:50:35 -08:00
gradlew.bat Add Android app scaffolding and Swift bridge 2025-12-21 10:50:35 -08:00
Makefile key.store: align client ids to store.key.application 2026-02-16 00:31:50 -05:00
package.json key.store web: product branding page 2026-02-06 18:44:55 -08:00
README.md key.store: publish TestFlight + Play Store by default 2026-02-14 18:24:10 -05:00
secrets.nix fix: repair apple workflows and secrets 2025-12-08 01:25:27 -08:00
settings.gradle.kts Add Android app scaffolding and Swift bridge 2025-12-21 10:50:35 -08:00

key.store

key.store is an autonomous, open-source password manager that treats its codebase, build farm, and infrastructure as a single sovereign kernel. The long-term goal—spelled out in the recorded genesis message and transcribed in genesis.txt—is to let a self-hosted forge nurture a “crystalline artifact”: a Swift-based password manager with transparent provenance, reproducible builds, and agents that can evolve it safely. The intent is codified in the key.store constitution; every plan or proposal should trace back to it.

Genesis at a Glance

  • Own the forge. We use Nix to define everything from the application stack to the forge OS image so the project can build and host itself on Hetzner (or any sovereign compute with dispatchable runners).
  • Treat infrastructure as part of the artifact. Secrets, DNS, TLS, runners, and cron-based automation live in-repo so the forge can bootstrap, repair, and extend itself.
  • Grow via agents, not commits alone. Scheduled jobs can spawn agents that open PRs, review each others work, and keep the system coherent without depending on centralized SaaS for CI/CD.
  • Capture context for future models. Decisions, prompts, and architecture notes must live beside the code so the next generation of agents (and humans) can read them.

If you want the full stream-of-consciousness origin story, start with genesis.m4a (22 minutes) or the generated captions in genesis.srt.

Mission

  1. Deliver a production-quality, cross-platform password manager written in Swift, with first-class Apple, Web, and backend experiences.
  2. Maintain a self-hosted forge that can provision its own infrastructure, secrets, and runners via Nix, Hetzner, and Cloudflare DNS automation.
  3. Iterate safely by letting autonomous agents do the rote work while humans (or higher-level agents) set direction through the key.store evolution process.

System Pillars

  • Crystalline Artifact: The password manager plus every prompt, script, and policy required to rebuild it. Nothing critical should live outside the repository (or its declared state stores).
  • Sovereign Kernel: A minimal pool of trusted machines that can bootstrap new services, rotate credentials, and recover after failure using only the contents of this repo.
  • Autonomous Evolution: Cron jobs and runners schedule agents that implement and review key.store evolution proposals, ensuring growth is intentional rather than chaotic.

Repository Tour

  • API/ — Rust services and workers that back the product experience.
  • Apple/ — Native Swift code, likely the home of the flagship client.
  • Web/ — Web front-end assets and tooling.
  • nixos/ — Hosts, modules, and images used to spin up the forge and related services.
  • Packages/ & Scripts/ — Shared tooling, Swift packages, agent helpers, and secret-management scripts.
  • Makefile — Shortcuts for nix build, nix develop, and agenix-backed secret handling.

Bootstrapping the Stalwart directory

Stalwart expects a SQL directory with accounts, emails, and group_members tables (the schema in tests/src/directory/mod.rs mirrors what we use). Two helper scripts keep those tables aligned with the constitution:

# emit bootstrap.sql based on contributors.nix
python Scripts/generate-stalwart-sql.py > bootstrap.sql

# or stream it straight into psql (DATABASE_URL is optional if you source config/databases/stalwart-socket.env)
nix develop .#tools --command Scripts/apply-stalwart-sql.sh bootstrap.sql

# shorthand: auto-generate SQL and run it
nix develop .#tools --command Scripts/apply-stalwart-sql.sh

apply-stalwart-sql.sh reads config/databases/stalwart-socket.env (or respects DATABASE_URL/STALWART_DATABASE_URL) and runs the SQL with psql -v ON_ERROR_STOP=1, so rerunning it is idempotent. The generator now reads each secrets/identity/<slug>-password.age, hashes it (SHA-512 crypt), and stores the result in accounts.secret, so Stalwarts internal directory always mirrors the canonical password list without ever writing plaintext into SQL output (run it on a host whose Age identity is in forgeAutomation).

Bootstrapping Forgejo accounts

Forgejo uses the same identity hierarchy for admin scope (governance), CI/service accounts (forgeAutomation), etc. The companion scripts follow the same pattern:

# review the generated user/email upserts
python Scripts/generate-forgejo-sql.py > forgejo.sql

# or stream directly (DATABASE_URL/forge secret is auto-resolved)
nix develop .#tools --command Scripts/apply-forgejo-sql.sh forgejo.sql
# shorthand auto-generate + apply
nix develop .#tools --command Scripts/apply-forgejo-sql.sh

The SQL upserts "user" rows for every contributor (governance identities become admins) and seeds the email_address table so Forgejo trusts their commit addresses. SSH keys still live in config/git-identities/ and are managed via Scripts/git-identity.sh per KSE-0001.

Getting Started

# drop into the reproducible dev shell
nix develop

# list or edit encrypted secrets (requires access)
make secrets-list
make secret name=cloudflare/api-token

# build everything described by flake.nix
nix build

Agents typically execute the same flows inside runners; humans can follow the steps above to reproduce their environment locally.

Commit Signing

All commits must be SSH-signed per KSE-0001. Use Scripts/git-identity.sh list to see the available identities, Scripts/git-identity.sh use <identity> (for example, agent) to configure your local git settings, and Scripts/git-identity.sh generate <identity> if you are onboarding a new signer. Public keys live in config/git-identities/, encrypted private keys now live under secrets/identity/<identity>-ssh.age, and .git_allowed_signers is regenerated by Scripts/git-identity.sh refresh. For OpenPGP/WKD publishing of identity@key.store addresses, follow docs/pgp-wkd.md and the helper script Scripts/wkd-publish.sh; the .well-known payload ships as the nix build .#wkd derivation and is bundled into the static web assets served by the API frontend. The canonical roster (with scopes, hardware key notes, and Age recipients) lives in contributors.nix; run make contributors after editing it so CONTRIBUTORS.md and downstream tooling stay in sync.

Run Scripts/generate-allowed-signers.sh whenever you add/remove identities; review the resulting .git_allowed_signers diff before committing so the signer roster always matches config/git-identities/*.pub and the WKD tree.

Scripts/git-identity.sh generate --scope <tier> <identity> now writes three assets: the SSH key (secrets/identity/<identity>-ssh.age), an Age-encrypted OpenPGP backup (secrets/identity/<identity>-openpgp.age via Scripts/export-openpgp-secret.sh), and an encrypted SMTP password (secrets/forwardemail/<identity>-smtp.age via Scripts/forwardemail-alias.sh). Use Scripts/export-openpgp-secret.sh and Scripts/forwardemail-alias.sh manually whenever you rotate subkeys so the bundles stay current.

Universal plaintext login/password pairs (used by Stalwart, Forgejo OIDC bootstrap, and Plane) live in secrets/identity/<identity>-password.age. Generate or rotate them with make identity-passwords (optionally slug=<identity> or ROTATE=1); the helper script shells out to openssl rand -base64 32 so every identity gets a strong random secret without manual copy/paste. See services/mail/stalwart-auth.md for the Stalwart-side OIDC runbook (client registration script, secret layout, and Forgejo wiring details).

Governance & Evolution

key.store uses a lightweight process inspired by Swift Evolution to capture architectural intent, major feature work, and agent-safe instructions. Every substantive change should be anchored by a proposal (KSE-XXXX) described in evolution/README.md and must cite the sections of the constitution it advances or depends on. Proposals live in evolution/proposals/ and act as durable context for future contributors.

Resources

When you update any of these resources (for example, regenerating the transcript with a newer model), note the change in the commit message so downstream agents know which context to trust.