No description
  • Swift 37.9%
  • Assembly 21.1%
  • C 15.3%
  • C++ 14.1%
  • Nix 2.7%
  • Other 8.5%
Find a file
gpt-5.3-codex 7be248f9df
All checks were successful
Deploy: API / Deploy (push) Successful in 1m36s
Build: Linux / Build keystore-forge (x86_64) (push) Has been skipped
Build: Apple / SwiftLint (push) Successful in 2m24s
Deploy: Web / Deploy (push) Successful in 1m47s
Build: Linux / Build (Linux x86_64) (push) Successful in 2m7s
Build: Apple / Build (iOS) (push) Successful in 1m7s
Build: Apple / Build (visionOS) (push) Successful in 39s
Build: Apple / Build (macOS) (push) Successful in 3m53s
Build: Web / Build & Test (push) Successful in 45s
key.store: fix Apple associated domains
2026-04-11 14:36:55 -07:00
.agents/plugins key.store: harden forge command plane control surfaces 2026-03-30 19:10:37 -07:00
.codex key.store: rebase on key.store-9 and integrate codex + Sparkle + F-Droid 2026-01-19 05:52:44 -08:00
.forgejo key.store: fix Apple associated domains 2026-04-11 14:36:55 -07:00
Android key.store: use internal Play testing for release uploads 2026-04-10 23:01:19 -07:00
API key.store: remove GitHub Actions references 2026-02-07 18:35:58 -08:00
Apple key.store: close Apple and PostHog takeoff gates 2026-04-05 15:55:05 -07:00
bazel key.store: fix posthog mcp and macos smoke gates 2026-04-05 20:10:57 -07:00
config key.store: harden web rollout analytics and CI signals 2026-04-05 00:04:54 -07:00
docs key.store: stabilize forge runner control plane 2026-04-05 14:52:39 -07:00
evolution key.store: fix Apple associated domains 2026-04-11 14:36:55 -07:00
finances key.store: repair android, linux swift, and finance workflow inputs 2026-02-20 20:10:20 -08:00
fleet fleet: fix Apple MDM bootstrap path 2026-03-15 18:26:18 -07: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
infra/proxmox infra: add proxmox runner keepalive and windows e2e lane 2026-03-09 00:15:22 -07:00
Linux/App key.store: unblock bazel linux release closure 2026-03-19 22:07:50 -07:00
nixos key.store: pin forgejo-nsc host packages locally 2026-04-10 23:58:29 -07:00
notes Fill business metadata and wire Fava decrypt 2026-01-20 01:32:53 -08:00
org infra: land redmine and authentik control-plane hardening 2026-03-22 22:42:03 -07:00
Packages key.store: fix shared PKCS11 slot enumeration build break 2026-04-05 16:08:10 -07:00
plugins/key-store-forge-control-plane key.store: extend MCP hub work creation surfaces 2026-04-04 14:53:12 -07:00
records Update nix cache, identities, and governance terms 2026-02-01 01:29:14 -08:00
Scripts key.store: stabilize runner age identity resolution 2026-04-11 00:21:20 -07:00
secrets key.store: refresh forge auth seeds and role tokens 2026-04-03 01:58:38 -07:00
services key.store: fix Apple associated domains 2026-04-11 14:36:55 -07:00
skills infra: land redmine and authentik control-plane hardening 2026-03-22 22:42:03 -07:00
store-metadata key.store: stabilize runner age identity resolution 2026-04-11 00:21:20 -07:00
Web key.store: fix Apple associated domains 2026-04-11 14:36:55 -07:00
Windows/App infra: add proxmox runner keepalive and windows e2e lane 2026-03-09 00:15:22 -07:00
.bazelignore key.store: close Apple and PostHog takeoff gates 2026-04-05 15:55:05 -07:00
.bazelrc ci: scope bazel runner caches and raise forge capacity 2026-03-20 18:33:59 -07: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: store web fonts directly in git 2026-04-05 17:17:30 -07:00
.gitignore key.store: ignore local intake staging 2026-03-30 19:44:56 -07: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.bazel key.store: unblock bazel release fanout 2026-03-19 00:12:18 -07:00
build.gradle.kts Add Android app scaffolding and Swift bridge 2025-12-21 10:50:35 -08:00
bun.lock key.store: roll out site-wide PostHog and official MCP 2026-04-04 19:10:36 -07: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: finish Huly cutover and retire Plane ops 2026-03-09 00:34:13 -07:00
contributors.nix key.store: finish Huly cutover and retire Plane ops 2026-03-09 00:34:13 -07:00
flake.lock key.store: let forgejo-nsc pre-start read runner keys 2026-04-05 18:28:09 -07:00
flake.nix key.store: fix Apple associated domains 2026-04-11 14:36:55 -07: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 mail: add fleet mobile bootstrap and tighten intake 2026-03-15 16:58:43 -07:00
MODULE.bazel key.store: restore bazel-first ci graph 2026-03-18 23:45:01 -07:00
MODULE.bazel.lock key.store: drive release through bazel wrappers 2026-03-18 23:59:42 -07:00
package.json key.store web: product branding page 2026-02-06 18:44:55 -08:00
README.md key.store: remove stale Huly and Plane operator references 2026-03-09 02:53:24 -07: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.

SSH defaults in the dev shell are now repo-local (config/ssh/config + .home/ssh/*) so scripts and Git do not depend on user-global ~/.ssh/config. See docs/ssh-devshell.md for the 1Password-agent flow and Codex shell behavior.

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 Redmine bootstrap) 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.