From 366cc94d8605d783b88417cb08fcdb7fc5e981be Mon Sep 17 00:00:00 2001 From: omigamedev Date: Sun, 18 Jan 2026 18:53:15 +0100 Subject: [PATCH] update M04 auth with Go implementation details --- DEV_PORTAL_M04_AUTH.md | 120 +++++++++++++++++++++++++++++++---------- 1 file changed, 92 insertions(+), 28 deletions(-) diff --git a/DEV_PORTAL_M04_AUTH.md b/DEV_PORTAL_M04_AUTH.md index c99973c..16ee273 100644 --- a/DEV_PORTAL_M04_AUTH.md +++ b/DEV_PORTAL_M04_AUTH.md @@ -1,8 +1,27 @@ # Milestone 4: Authentication System -**Status**: Planning +**Status**: Decided **Goal**: Secure developer authentication and app signing infrastructure. +## Decision + +**Custom JWT + OAuth2** with Go standard library crypto: + +``` +OAuth2: golang.org/x/oauth2 (GitHub, Google) +JWT: github.com/golang-jwt/jwt/v5 +Signing: crypto/ed25519 (stdlib) +Password Hash: golang.org/x/crypto/argon2 +API Key Hash: golang.org/x/crypto/bcrypt +``` + +### Rationale + +1. **Go stdlib crypto** - Ed25519 built into Go, no external deps +2. **Simple JWT** - golang-jwt is battle-tested, minimal +3. **Stateless tokens** - No token store needed (SQLite handles refresh token revocation) +4. **OAuth-first** - GitHub OAuth for most developers, minimal password handling + --- ## Overview @@ -348,49 +367,94 @@ GET /signing-keys/:id/verify # Verify a signature --- -## Implementation Libraries +## Implementation (Go) -### Node.js - -```json -{ - "passport": "OAuth strategies", - "jose": "JWT handling", - "@noble/ed25519": "Ed25519 signing", - "argon2": "Password hashing" -} -``` - -### Go +### Dependencies ```go import ( + // OAuth2 "golang.org/x/oauth2" + "golang.org/x/oauth2/github" + "golang.org/x/oauth2/google" + + // JWT "github.com/golang-jwt/jwt/v5" + + // Cryptography (all stdlib) "crypto/ed25519" + "crypto/rand" + "crypto/sha256" + + // Password/Key hashing "golang.org/x/crypto/argon2" + "golang.org/x/crypto/bcrypt" ) ``` -### Rust +### OAuth2 Config -```toml -[dependencies] -oauth2 = "4.4" -jsonwebtoken = "9" -ed25519-dalek = "2" -argon2 = "0.5" +```go +var githubOAuth = &oauth2.Config{ + ClientID: os.Getenv("GITHUB_CLIENT_ID"), + ClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"), + Endpoint: github.Endpoint, + Scopes: []string{"read:user", "user:email"}, + RedirectURL: "https://portal.mosis.dev/auth/github/callback", +} +``` + +### JWT Generation + +```go +func generateAccessToken(developerID string) (string, error) { + claims := jwt.MapClaims{ + "sub": developerID, + "type": "access", + "iat": time.Now().Unix(), + "exp": time.Now().Add(time.Hour).Unix(), + } + token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + return token.SignedString([]byte(os.Getenv("JWT_SECRET"))) +} +``` + +### Ed25519 Signing + +```go +func signManifest(manifest []byte, privateKey ed25519.PrivateKey) []byte { + return ed25519.Sign(privateKey, manifest) +} + +func verifySignature(manifest, signature []byte, publicKey ed25519.PublicKey) bool { + return ed25519.Verify(publicKey, manifest, signature) +} +``` + +### API Key Hashing + +```go +func hashAPIKey(key string) (string, error) { + hash, err := bcrypt.GenerateFromPassword([]byte(key), bcrypt.DefaultCost) + return string(hash), err +} + +func verifyAPIKey(key, hash string) bool { + return bcrypt.CompareHashAndPassword([]byte(hash), []byte(key)) == nil +} ``` --- ## Deliverables -- [ ] OAuth2 integration (GitHub) -- [ ] OAuth2 integration (Google) +- [x] Auth approach decided (OAuth2 + JWT + API Keys) +- [x] Crypto libraries selected (Go stdlib + golang-jwt) +- [ ] OAuth2 integration (GitHub) - P0 +- [ ] OAuth2 integration (Google) - P1 - [ ] JWT token management - [ ] API key generation and validation -- [ ] Ed25519 key generation tool +- [ ] Ed25519 key generation (CLI tool) - [ ] Signature creation and verification - [ ] Key registration API - [ ] Audit logging @@ -414,10 +478,10 @@ argon2 = "0.5" ## Open Questions -1. Support for hardware security keys (YubiKey)? -2. Multi-factor authentication for portal? -3. Team accounts with role-based access? -4. Key escrow for enterprise customers? +1. ~~Support for hardware security keys (YubiKey)?~~ → Defer to post-MVP +2. ~~Multi-factor authentication for portal?~~ → Defer to post-MVP +3. Team accounts with role-based access? → Consider for v1.1 +4. ~~Key escrow for enterprise customers?~~ → Not needed for self-hosted ---