generated from coulomb/repo-seed
- T22: docker-compose.dev.yml dev stack, Dockerfile, root Makefile - T18: Profile test suite (Scenario A) — 8 integration tests with real handlers - T23: Server binary wiring all components, config validation, /healthz - Config: ValidateConfig with startup validation 14 test packages pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
2.0 KiB
Go
64 lines
2.0 KiB
Go
// Package config handles loading and validating the KeyCape server configuration
|
|
// from a YAML file. The config path is resolved from the --config flag or the
|
|
// KEYCAPE_CONFIG environment variable.
|
|
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
"keycape/internal/adapters/authelia"
|
|
"keycape/internal/adapters/lldap"
|
|
"keycape/internal/adapters/privacyidea"
|
|
)
|
|
|
|
// Config is the top-level server configuration.
|
|
type Config struct {
|
|
Issuer string `yaml:"issuer"`
|
|
Port int `yaml:"port"`
|
|
TokenLifetime string `yaml:"tokenLifetime"`
|
|
PrivateKeyPEM string `yaml:"privateKeyPem"`
|
|
LLDAP lldap.Config `yaml:"lldap"`
|
|
Authelia authelia.Config `yaml:"authelia"`
|
|
PrivacyIDEA privacyidea.Config `yaml:"privacyidea"`
|
|
Clients []ClientConfig `yaml:"clients"`
|
|
Environment string `yaml:"environment"`
|
|
}
|
|
|
|
// ClientConfig is a static OIDC client registration.
|
|
type ClientConfig struct {
|
|
ClientID string `yaml:"clientId"`
|
|
DisplayName string `yaml:"displayName"`
|
|
RedirectURIs []string `yaml:"redirectUris"`
|
|
AllowedScopes []string `yaml:"allowedScopes"`
|
|
GrantTypes []string `yaml:"grantTypes"`
|
|
ClientType string `yaml:"clientType"` // "confidential" | "public"
|
|
SecretRef string `yaml:"secretRef,omitempty"`
|
|
}
|
|
|
|
// Load reads and parses the YAML config file at path.
|
|
// If path is empty, it falls back to the KEYCAPE_CONFIG environment variable.
|
|
// Returns an error if the file cannot be read or parsed.
|
|
func Load(path string) (*Config, error) {
|
|
if path == "" {
|
|
path = os.Getenv("KEYCAPE_CONFIG")
|
|
}
|
|
if path == "" {
|
|
return nil, fmt.Errorf("config: no config path specified (use --config or KEYCAPE_CONFIG)")
|
|
}
|
|
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("config: read %q: %w", path, err)
|
|
}
|
|
|
|
var cfg Config
|
|
if err := yaml.Unmarshal(data, &cfg); err != nil {
|
|
return nil, fmt.Errorf("config: parse %q: %w", path, err)
|
|
}
|
|
|
|
return &cfg, nil
|
|
}
|