Files
goclaw/internal/crypto/apikey.go
T
Goon 75c570e951 feat(security): credentialed exec + HTTP RBAC + API key cache (#197)
- Secure CLI credential injection via AES-256-GCM encrypted env vars
- API key management with fine-grained RBAC scopes
- resolveAuth/requireAuth middleware across all 25+ HTTP handlers
- In-memory API key cache with TTL, negative caching, pubsub invalidation
- Sandbox-first execution (fails if unavailable, no silent fallback)
- Credential scrubbing, constant-time token comparison, Admin-only CLI creds
- SQL migration 000020: secure_cli_binaries + api_keys tables
- 14 unit tests for cache and RBAC with race detector

Closes #197
2026-03-15 20:13:18 +07:00

31 lines
855 B
Go

package crypto
import (
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"fmt"
)
const apiKeyPrefix = "goclaw_"
// GenerateAPIKey creates a new API key with format "goclaw_<32hex>".
// Returns the raw key (show once), its SHA-256 hash, and 8-char display prefix.
func GenerateAPIKey() (raw, hash, displayPrefix string, err error) {
b := make([]byte, 16) // 16 bytes = 32 hex chars
if _, err = rand.Read(b); err != nil {
return "", "", "", fmt.Errorf("generate random bytes: %w", err)
}
raw = apiKeyPrefix + hex.EncodeToString(b)
hash = HashAPIKey(raw)
displayPrefix = hex.EncodeToString(b[:4]) // first 8 hex chars of the random part
return raw, hash, displayPrefix, nil
}
// HashAPIKey returns the SHA-256 hex digest of a raw API key.
func HashAPIKey(raw string) string {
h := sha256.Sum256([]byte(raw))
return hex.EncodeToString(h[:])
}