Files
DoGaMa-serv/internal/internalsecrets/secrets.go
T
tony 46bc90a0e8
CI / validate (pull_request) Failing after 2m30s
feat(release): harden production packaging
2026-08-09 22:11:21 +02:00

108 lines
3.1 KiB
Go

// Package internalsecrets initializes persistent deployment secrets without
// exposing their values through environment variables or logs.
package internalsecrets
import (
"crypto/rand"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"runtime"
)
const secretSize = 32
// Ensure creates path atomically with cryptographically random bytes. Existing
// destination files are validated and never replaced.
func Ensure(path string, uid, gid int, mode os.FileMode) (bool, error) {
if mode.Perm()&0o007 != 0 || mode.Perm()&0o700 == 0 {
return false, errors.New("secret permissions are invalid")
}
if err := validateExisting(path, mode); err == nil {
return false, nil
} else if !errors.Is(err, os.ErrNotExist) {
return false, err
}
value := make([]byte, secretSize)
if _, err := io.ReadFull(rand.Reader, value); err != nil {
return false, fmt.Errorf("generate secret: %w", err)
}
directory := filepath.Dir(path)
directoryMode := os.FileMode(0o700)
if mode.Perm()&0o040 != 0 {
directoryMode = 0o750
}
if err := os.MkdirAll(directory, directoryMode); err != nil {
return false, fmt.Errorf("create secret directory: %w", err)
}
if err := os.Chmod(directory, directoryMode); err != nil {
return false, fmt.Errorf("restrict secret directory: %w", err)
}
temporary, err := os.CreateTemp(directory, ".secret-*")
if err != nil {
return false, fmt.Errorf("create temporary secret: %w", err)
}
temporaryPath := temporary.Name()
defer os.Remove(temporaryPath)
if err := temporary.Chmod(mode); err != nil {
temporary.Close()
return false, fmt.Errorf("restrict temporary secret: %w", err)
}
if _, err := temporary.Write(value); err != nil {
temporary.Close()
return false, fmt.Errorf("write temporary secret: %w", err)
}
if err := temporary.Sync(); err != nil {
temporary.Close()
return false, fmt.Errorf("sync temporary secret: %w", err)
}
if err := temporary.Close(); err != nil {
return false, fmt.Errorf("close temporary secret: %w", err)
}
if err := os.Link(temporaryPath, path); err != nil {
if errors.Is(err, os.ErrExist) {
return false, validateExisting(path, mode)
}
return false, fmt.Errorf("install secret: %w", err)
}
if runtime.GOOS != "windows" && os.Geteuid() == 0 {
if err := os.Chown(path, uid, gid); err != nil {
return false, fmt.Errorf("set secret owner: %w", err)
}
if err := os.Chown(directory, uid, gid); err != nil {
return false, fmt.Errorf("set secret directory owner: %w", err)
}
}
return true, nil
}
func validateExisting(path string, mode os.FileMode) error {
info, err := os.Lstat(path)
if err != nil {
return err
}
if !info.Mode().IsRegular() || info.Mode()&os.ModeSymlink != 0 {
return errors.New("secret must be a regular file")
}
if runtime.GOOS != "windows" && info.Mode().Perm() != mode.Perm() {
return errors.New("secret permissions do not match the required mode")
}
_, err = readSecret(path)
return err
}
func readSecret(path string) ([]byte, error) {
value, err := os.ReadFile(path)
if err != nil {
return nil, err
}
if len(value) != secretSize {
return nil, fmt.Errorf("secret must contain exactly %d bytes", secretSize)
}
return value, nil
}