// ABOUTME: HMAC-SHA256 token generation and validation for scoped push authentication. // ABOUTME: Tokens are derived from a key + scope, enabling stateless validation without DB storage. package receiver import ( "crypto/hmac" "crypto/sha256" "crypto/subtle" "encoding/hex" ) // GenerateScopedToken computes an HMAC-SHA256 token scoped to a specific org/repo/workflow/job. // The canonical input is "v1\x00\x00\x00\x00". func GenerateScopedToken(key, org, repo, workflow, job string) string { mac := hmac.New(sha256.New, []byte(key)) mac.Write([]byte("v1\x00" + org + "\x00" + repo + "\x00" + workflow + "\x00" + job)) return hex.EncodeToString(mac.Sum(nil)) } // ValidateScopedToken checks whether a token matches the expected HMAC for the given scope. // Uses constant-time comparison to prevent timing attacks. func ValidateScopedToken(key, token, org, repo, workflow, job string) bool { expected := GenerateScopedToken(key, org, repo, workflow, job) return subtle.ConstantTimeCompare([]byte(token), []byte(expected)) == 1 }