update M04 auth with Go implementation details

This commit is contained in:
2026-01-18 18:53:15 +01:00
parent 416c447ad8
commit 366cc94d86

View File

@@ -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
---