access-engine/cmd/access-engine/envelope_signing.go
tegwick ec21518e25
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Failing after 1m27s
fix(auth): sign served decisions before recording and returning them
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
2026-10-16 07:51:43 +02:00

42 lines
1.3 KiB
Go

package main
import (
"crypto/ed25519"
"encoding/base64"
"fmt"
"io"
"os"
"strings"
"github.com/netkingdom/access-engine/internal/decision"
)
// configureEnvelopeSigning reads a mounted seed once at startup. Never accept
// the secret in argv, an environment value, an HTTP request or a log message.
func configureEnvelopeSigning(engine *decision.Engine, path, kid string) error {
if path == "" && kid == "" {
return nil
}
if path == "" || strings.TrimSpace(kid) == "" {
return fmt.Errorf("envelope signing requires key file and kid")
}
file, err := os.Open(path)
if err != nil {
return fmt.Errorf("envelope signing key file unavailable")
}
defer file.Close()
info, err := file.Stat()
if err != nil || !info.Mode().IsRegular() || info.Mode().Perm()&0027 != 0 {
return fmt.Errorf("envelope signing key must be a regular file without group-write or world permissions")
}
raw, err := io.ReadAll(io.LimitReader(file, 129))
if err != nil || len(raw) > 128 {
return fmt.Errorf("invalid envelope signing key file")
}
encoded := strings.TrimSpace(string(raw))
seed, err := base64.RawURLEncoding.Strict().DecodeString(encoded)
if err != nil || len(seed) != ed25519.SeedSize {
return fmt.Errorf("invalid envelope signing seed")
}
return engine.SetEnvelopeSigningKey(ed25519.NewKeyFromSeed(seed), kid)
}