github-claims.md
1 # GitHub Claims 2 3 Link your GitHub account to your Auths cryptographic identity. This creates a publicly verifiable proof that a specific GitHub username is controlled by the same person who holds the corresponding `did:keri` identity. 4 5 ## Prerequisites 6 7 - An initialized Auths identity (`auths init`) 8 - Your identity registered with the Auths registry (`auths id register`) 9 10 ## How it works 11 12 The claim flow uses the [OAuth Device Flow (RFC 8628)](https://datatracker.ietf.org/doc/html/rfc8628) so the CLI never handles your GitHub password. The process: 13 14 1. **Authenticate via device flow** -- Auths requests a device code from GitHub using the `gist read:user` scopes. You authorize in your browser. 15 2. **Create a signed claim** -- Auths builds a JSON document containing your GitHub username, your controller DID, and a timestamp, then signs it with your identity key using Ed25519. The claim is canonicalized with [RFC 8785 (JCS)](https://datatracker.ietf.org/doc/html/rfc8785) before signing to ensure deterministic verification. 16 3. **Publish proof Gist** -- The signed claim is uploaded as a public GitHub Gist (`auths-proof.json`). This Gist persists as a permanent, publicly verifiable anchor even after the OAuth token expires. 17 4. **Submit to registry** -- The proof URL is submitted to the Auths registry, which indexes the claim linking your platform identity to your DID. 18 19 ## Claiming your GitHub account 20 21 ```bash 22 auths id claim github 23 ``` 24 25 The CLI will: 26 27 1. Open your browser to `https://github.com/login/device` and display a one-time code. 28 2. Wait for you to enter the code and authorize the Auths GitHub App. 29 3. Fetch your GitHub username from the API. 30 4. Sign a platform claim linking `github:@<username>` to your `did:keri:E...`. 31 5. Publish the signed claim as a public Gist. 32 6. Submit the Gist URL to the registry for indexing. 33 34 On success you will see: 35 36 ``` 37 Platform claim indexed: github @<username> -> did:keri:E... 38 ``` 39 40 ### Custom registry URL 41 42 By default, claims are submitted to `https://auths-registry.fly.dev`. To use a different registry: 43 44 ```bash 45 auths id claim github --registry https://your-registry.example.com 46 ``` 47 48 ## What the attestation proves 49 50 The published Gist contains a JSON document like this: 51 52 ```json 53 { 54 "type": "platform_claim", 55 "platform": "github", 56 "namespace": "octocat", 57 "did": "did:keri:EaBcDeFgHiJkLmNoPqRsTuVwXyZ...", 58 "timestamp": "2026-03-01T12:00:00+00:00", 59 "signature": "<base64url-encoded Ed25519 signature>" 60 } 61 ``` 62 63 This proves: 64 65 - **Account ownership** -- At the time of signing, the person holding the private key for `did:keri:E...` also controlled the GitHub account `@octocat` (they had a valid OAuth token with `gist` and `read:user` scopes). 66 - **Cryptographic binding** -- The signature covers the canonicalized claim (excluding the `signature` field itself). Anyone with the DID's public key can verify the signature independently. 67 - **Permanent anchor** -- The Gist URL is publicly accessible. Even if the OAuth token is revoked, the signed claim remains verifiable using only the DID's public key. 68 69 The claim does **not** prove continuous ownership. If the GitHub account changes hands, the claim remains valid because it is bound to a point-in-time assertion. Future revocation would require a new signed statement. 70 71 ## Verifying a claim 72 73 Anyone can verify a claim by: 74 75 1. Fetching the Gist at the proof URL. 76 2. Removing the `signature` field from the JSON. 77 3. Canonicalizing the remaining JSON with JCS (RFC 8785). 78 4. Verifying the Ed25519 signature against the public key derived from the `did` field. 79 80 ## JSON output 81 82 For scripting and automation, use `--json` to get machine-readable output: 83 84 ```bash 85 auths id claim github --json 86 ``` 87 88 ```json 89 { 90 "status": "success", 91 "command": "id claim", 92 "data": { 93 "platform": "github", 94 "namespace": "octocat", 95 "did": "did:keri:EaBcDeFgHiJkLmNoPqRsTuVwXyZ..." 96 } 97 } 98 ```