A replica of Keytrace
at main 152 lines 6.5 kB view raw view rendered
1# Keytrace 2 3Identity verification for ATProto. Link your decentralized identity (DID) to external accounts like GitHub, LinkedIn, Instagram, DNS, and Mastodon with cryptographically signed attestations. 4 5## What is Keytrace? 6 7Keytrace allows Bluesky users to prove ownership of external accounts by: 8 91. **Creating a claim** - Post a verification token to your GitHub gist, DNS TXT record, or other supported platform 102. **Verification** - Keytrace fetches and validates the proof contains your DID 113. **Attestation** - A cryptographic signature is created and stored in your ATProto repo as a `dev.keytrace.claim` record 12 13Claims are user-owned, portable, and stored directly in your ATProto repository. 14 15## Project Structure 16 17```text 18keytrace/ 19├── apps/ 20│ └── keytrace.dev/ # Nuxt 3 web application 21├── packages/ 22│ ├── runner/ # Core verification library (@keytrace/runner) 23│ └── lexicon/ # ATProto lexicon schemas 24``` 25 26## Development 27 28```bash 29# Install dependencies 30yarn install 31 32# Start development server 33yarn dev 34 35# Run tests 36yarn test 37 38# Type checking 39yarn typecheck 40 41# Format code 42yarn format 43``` 44 45## How Verification Works 46 47The runner package implements a recipe-based verification system: 48 491. **Service Providers** match claim URIs to verification strategies 502. **Recipes** define verification steps as JSON specifications 513. **Verification Steps** are composable actions: `http-get`, `dns-txt`, `css-select`, `json-path`, `regex-match` 52 53Example flow: 54 55```text 56User submits gist URL 57 → Match URI to GitHub provider 58 → Execute recipe: HTTP GET → CSS select → regex match for DID 59 → Extract identity metadata (username, avatar) 60 → Create attestation signature 61 → Write dev.keytrace.claim to user's ATProto repo 62``` 63 64## ATProto Lexicons 65 66- `dev.keytrace.claim` - Identity claim linking a DID to an external account 67- `dev.keytrace.recipe` - Verification recipe specification 68- `dev.keytrace.key` - Daily signing key for attestations 69- `dev.keytrace.signature` - Cryptographic attestation structure 70 71## Deployment 72 73### Publishing Packages 74 75Use the deploy script to bump versions and publish all packages to npm: 76 77```bash 78./scripts/deploy.sh patch # 0.0.1 → 0.0.2 79./scripts/deploy.sh minor # 0.0.2 → 0.1.0 80./scripts/deploy.sh major # 0.1.0 → 1.0.0 81``` 82 83This will: 841. Bump versions in `@keytrace/runner`, `@keytrace/claims`, and `@keytrace/lexicon` 852. Build all packages 863. Publish to npm 874. Create a git commit and tag 88 89After running, push to remote: 90 91```bash 92git push && git push --tags 93``` 94 95 96## Adding a New Service Provider 97 98Want to add support for a new platform (e.g., GitLab, Codeberg, Tangled.) The key requirement is that the platform must have some way for users to **publicly post text content** that Keytrace can fetch and verify — things like profile bios, public posts, gists, comments, or files. 99 100### Proof of Identity Pattern 101 102Every service provider follows the same pattern: 103 1041. The user places a **proof string** (containing their DID) somewhere publicly readable on the service 1052. Keytrace fetches that public URL and checks that the proof string is present 1063. Metadata (username, avatar, profile URL) is extracted from the response 107 108Good proof locations include: public gists/snippets, profile bios, DNS TXT records, public repos, pinned posts, or any content the user controls that's fetchable via HTTP. 109 110You need to be careful that it's a place where only the identity can post. For example you can post a GitHub gist with a keytrace DID but the comments can also contain keytrace DIDs for other people. This could be used to make a false claim. 111 112### What You Need to Create 113 114All you need to touch is the `packages/runner/` package — the web app picks up new providers automatically via the `/api/services` endpoint and a shared `useServiceRegistry` composable. 115 1161. **Create a provider file** in `packages/runner/src/serviceProviders/` implementing the `ServiceProvider` interface: 117 - `id`, `name`, `homepage` — basic metadata 118 - `reUri` — regex to match claim URIs 119 - `ui` — wizard configuration (icon, instructions, proof template, input labels) 120 - `processURI()` — converts a matched URI into fetch + verification config 121 - `postprocess()` — extracts identity metadata (username, avatar, profile URL) 122 - `getProofText()` — generates the proof string for the user 123 - `tests` — URI match test cases 124 1252. **Register it** in `packages/runner/src/serviceProviders/index.ts` 126 1273. **Icon**: Set `ui.icon` to a [Lucide](https://lucide.dev/icons/) icon name (e.g., `"github"`, `"globe"`, `"shield"`) and the web app renders it automatically. If your service needs a custom SVG icon, add a component to `apps/keytrace.dev/components/icons/` and register it in the `iconMap` in `apps/keytrace.dev/composables/useServiceRegistry.ts`. Set `ui.iconDisplay: "raw"` for standalone SVGs (like npm/tangled) that shouldn't be wrapped in a circular badge. 128 129### Using Claude Code to Add a Provider 130 131From the repo root, try a prompt like: 132 133> Add a new service provider for [ServiceName]. Users will prove their identity by [describe the proof location, e.g. "creating a public snippet on GitLab containing their DID", or "adding their DID to their Codeberg profile bio"]. The proof URL format is [e.g. "https://gitlab.com/-/snippets/:id"]. Look at the existing providers in `packages/runner/src/serviceProviders/` for the pattern — especially `github.ts` for an HTTP+JSON example or `dns.ts` for a simpler one. Register the new provider in the index file and add URI match tests. 134 135That should give Claude Code enough to: 136 137- Create a new file in `packages/runner/src/serviceProviders/` 138- Implement the `ServiceProvider` interface (URI regex, `processURI`, `ui` config, `getProofText`, test cases) 139- Register it in `packages/runner/src/serviceProviders/index.ts` 140 141### What Goes in the PR 142 143When you open your PR, please include: 144 145- **How to create a proof**: Step-by-step instructions for how a user creates the public proof on the service (e.g., "go to gitlab.com/-/snippets/new, paste this, make it public") 146- **Example proof URL**: A real or realistic example URL so I can test the flow 147- **Any API quirks**: Rate limits, auth requirements, non-standard response formats, CORS issues, etc. 148- **Fetcher needs**: The existing fetchers are `http`, `dns`, and `activitypub`. If your service needs something different, note that 149 150## License 151 152MIT