Files
gitea-dynamic-runner/internal/runnerfacade/capability.go
T

37 lines
971 B
Go

package runnerfacade
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"errors"
)
// Capabilities are deterministic per assignment so controller restarts do not
// require a per-task token database.
type Capabilities struct{ key []byte }
func NewCapabilities(key []byte) (Capabilities, error) {
if len(key) < 32 {
return Capabilities{}, errors.New("runner facade capability key must be at least 32 bytes")
}
return Capabilities{key: append([]byte(nil), key...)}, nil
}
func (c Capabilities) Issue(assignmentID string) string {
if len(c.key) < 32 || assignmentID == "" {
return ""
}
mac := hmac.New(sha256.New, c.key)
_, _ = mac.Write([]byte("gitea-runner-assignment\x00" + assignmentID))
return base64.RawURLEncoding.EncodeToString(mac.Sum(nil))
}
func (c Capabilities) Verify(assignmentID, token string) bool {
want := c.Issue(assignmentID)
if want == "" || token == "" {
return false
}
return hmac.Equal([]byte(want), []byte(token))
}