All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 25s
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02e3f-7301-7622-9be1-12e5f352881c
70 lines
2.4 KiB
Go
70 lines
2.4 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"`
|
|
ServiceSubject string `yaml:"serviceSubject,omitempty"`
|
|
Tenant string `yaml:"tenant,omitempty"`
|
|
Roles []string `yaml:"roles,omitempty"`
|
|
TokenLifetime string `yaml:"tokenLifetime,omitempty"`
|
|
MFARequired *bool `yaml:"mfaRequired,omitempty"`
|
|
RegistrationURL string `yaml:"registrationUrl,omitempty"`
|
|
EnrollmentURL string `yaml:"enrollmentUrl,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
|
|
}
|