Files
nexarch/cmd/account-api/sessionkeys.go

71 lines
2.6 KiB
Go

package main
import (
"context"
"fmt"
"time"
"github.com/jackc/pgx/v5/pgxpool"
"gitea.perlbach24.de/scripte/nexarch/internal/kek"
"gitea.perlbach24.de/scripte/nexarch/internal/moduletrust"
)
// QA-15 F-10: eigener Schluesselsatz fuer Sitzungstokens (Tabelle
// session_signing_keys), unabhaengig vom Modul-Signaturschluessel aus
// API-16 (module_signing_keys) — getrennte Sicherheitsdomaenen, siehe
// Migration 0010. Envs bewusst analog zu modulekeys.go benannt.
const (
envSessionKeyEncryptionKey = "NEXARCH_ACCOUNT_SESSION_KEY_ENCRYPTION_KEY"
envSessionKeysEphemeral = "NEXARCH_ACCOUNT_SESSION_KEYS_EPHEMERAL"
envSessionKeyRotationDays = "NEXARCH_ACCOUNT_SESSION_KEY_ROTATION_DAYS"
envSessionKeyActivationSecs = "NEXARCH_ACCOUNT_SESSION_KEY_ACTIVATION_DELAY_SECONDS"
envSessionKeyRefreshSecs = "NEXARCH_ACCOUNT_SESSION_KEY_REFRESH_SECONDS"
defaultSessionRotationDays = 30
defaultSessionActivationSecs = 120
defaultSessionRefreshSecs = 30
)
func newSessionKeyManager(ctx context.Context, pool *pgxpool.Pool, getenv func(string) string, tokenTTL time.Duration) (*moduletrust.KeyManager, error) {
ephemeral := false
switch getenv(envSessionKeysEphemeral) {
case "", "false":
case "true":
ephemeral = true
default:
return nil, fmt.Errorf("%s: erlaubt sind true oder false", envSessionKeysEphemeral)
}
days, err := intEnv(getenv, envSessionKeyRotationDays, defaultSessionRotationDays, 0, 3650)
if err != nil {
return nil, err
}
act, err := intEnv(getenv, envSessionKeyActivationSecs, defaultSessionActivationSecs, 60, 3600)
if err != nil {
return nil, err
}
refresh, err := intEnv(getenv, envSessionKeyRefreshSecs, defaultSessionRefreshSecs, 1, 300)
if err != nil {
return nil, err
}
if act < refresh {
return nil, fmt.Errorf("%s (%ds) darf nicht kuerzer sein als %s (%ds)", envSessionKeyActivationSecs, act, envSessionKeyRefreshSecs, refresh)
}
if ephemeral {
return moduletrust.NewKeyManager()
}
key, err := kek.LoadMasterKeyFromEnv(envSessionKeyEncryptionKey)
if err != nil {
return nil, fmt.Errorf("%s: %w (ohne persistente schluessel nur mit %s=true, dann ungueltig nach jedem neustart)", envSessionKeyEncryptionKey, err, envSessionKeysEphemeral)
}
return moduletrust.NewPersistentKeyManager(ctx, moduletrust.PersistentConfig{
Store: moduletrust.NewSessionPGKeyStore(pool),
Cipher: kekCipher{key: key},
TokenTTL: tokenTTL,
ActivationDelay: time.Duration(act) * time.Second,
RotationInterval: time.Duration(days) * 24 * time.Hour,
RefreshInterval: time.Duration(refresh) * time.Second,
})
}