Extract config structs into pkg/probodconfig

probod-bootstrap only needs the config struct definitions for
YAML marshaling but transitively pulled in ~40 heavy runtime
dependencies via pkg/probod. Move all config types and their
methods to a new pkg/probodconfig package and re-export them
from pkg/probod via type aliases for backward compatibility.

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-04-28 12:49:10 +04:00
parent 983331e4dd
commit c043a7f1f5
20 changed files with 237 additions and 169 deletions

53
pkg/probod/aliases.go Normal file
View File

@@ -0,0 +1,53 @@
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
import "go.probo.inc/probo/pkg/probodconfig"
type (
FullConfig = probodconfig.FullConfig
Config = probodconfig.Config
UnitConfig = probodconfig.UnitConfig
MetricsConfig = probodconfig.MetricsConfig
TracingConfig = probodconfig.TracingConfig
ESignConfig = probodconfig.ESignConfig
TrustCenterConfig = probodconfig.TrustCenterConfig
APIConfig = probodconfig.APIConfig
CorsConfig = probodconfig.CorsConfig
ProxyProtocolConfig = probodconfig.ProxyProtocolConfig
AuthConfig = probodconfig.AuthConfig
OAuth2ServerConfig = probodconfig.OAuth2ServerConfig
OAuth2SigningKeyConfig = probodconfig.OAuth2SigningKeyConfig
CookieConfig = probodconfig.CookieConfig
PasswordConfig = probodconfig.PasswordConfig
AWSConfig = probodconfig.AWSConfig
ConnectorConfig = probodconfig.ConnectorConfig
ConnectorConfigOAuth2 = probodconfig.ConnectorConfigOAuth2
CustomDomainsConfig = probodconfig.CustomDomainsConfig
ACMEConfig = probodconfig.ACMEConfig
LLMProviderConfig = probodconfig.LLMProviderConfig
LLMAgentConfig = probodconfig.LLMAgentConfig
EvidenceDescriberConfig = probodconfig.EvidenceDescriberConfig
AgentsConfig = probodconfig.AgentsConfig
MailerConfig = probodconfig.MailerConfig
SMTPConfig = probodconfig.SMTPConfig
NotificationsConfig = probodconfig.NotificationsConfig
WebhookConfig = probodconfig.WebhookConfig
OIDCProviderConfig = probodconfig.OIDCProviderConfig
PgConfig = probodconfig.PgConfig
SAMLConfig = probodconfig.SAMLConfig
SCIMBridgeConfig = probodconfig.SCIMBridgeConfig
SlackConfig = probodconfig.SlackConfig
)

View File

@@ -1,30 +0,0 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
type CorsConfig struct {
AllowedOrigins []string `json:"allowed-origins"`
}
type ProxyProtocolConfig struct {
TrustedProxies []string `json:"trusted-proxies"`
}
type APIConfig struct {
Addr string `json:"addr"`
ProxyProtocol ProxyProtocolConfig `json:"proxy-protocol"`
Cors CorsConfig `json:"cors"`
ExtraHeaderFields map[string]string `json:"extra-header-fields"`
}

View File

@@ -1,98 +0,0 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
import (
"encoding/base64"
"fmt"
)
type AuthConfig struct {
Cookie CookieConfig `json:"cookie"`
Password PasswordConfig `json:"password"`
DisableSignup bool `json:"disable-signup"`
InvitationConfirmationTokenValidity int `json:"invitation-confirmation-token-validity"`
PasswordResetTokenValidity int `json:"password-reset-token-validity"`
MagicLinkTokenValidity int `json:"magic-link-token-validity"`
SAML SAMLConfig `json:"saml"`
Google OIDCProviderConfig `json:"google"`
Microsoft OIDCProviderConfig `json:"microsoft"`
OAuth2Server OAuth2ServerConfig `json:"oauth2-server"`
}
type OAuth2ServerConfig struct {
SigningKeys []OAuth2SigningKeyConfig `json:"signing-keys"`
AccessTokenDuration int `json:"access-token-duration"`
RefreshTokenDuration int `json:"refresh-token-duration"`
AuthorizationCodeDuration int `json:"authorization-code-duration"`
DeviceCodeDuration int `json:"device-code-duration"`
}
type OAuth2SigningKeyConfig struct {
PrivateKey string `json:"private-key"`
KID string `json:"kid"`
Active bool `json:"active"`
}
type CookieConfig struct {
Domain string `json:"domain"`
Secret string `json:"secret"`
Duration int `json:"duration"`
Name string `json:"name"`
Secure bool `json:"secure"`
}
type PasswordConfig struct {
Iterations int `json:"iterations"`
Pepper string `json:"pepper"`
}
func (c AuthConfig) GetPepperBytes() ([]byte, error) {
if c.Password.Pepper == "" {
return nil, fmt.Errorf("pepper cannot be empty")
}
if decoded, err := base64.StdEncoding.DecodeString(c.Password.Pepper); err == nil {
if len(decoded) < 32 {
return nil, fmt.Errorf("decoded pepper must be at least 32 bytes long")
}
return decoded, nil
}
if len(c.Password.Pepper) < 32 {
return nil, fmt.Errorf("pepper must be at least 32 bytes long")
}
return []byte(c.Password.Pepper), nil
}
func (c AuthConfig) GetCookieSecretBytes() ([]byte, error) {
if c.Cookie.Secret == "" {
return nil, fmt.Errorf("cookie secret cannot be empty")
}
if decoded, err := base64.StdEncoding.DecodeString(c.Cookie.Secret); err == nil {
if len(decoded) < 32 {
return nil, fmt.Errorf("decoded cookie secret must be at least 32 bytes long")
}
return decoded, nil
}
if len(c.Cookie.Secret) < 32 {
return nil, fmt.Errorf("cookie secret must be at least 32 bytes long")
}
return []byte(c.Cookie.Secret), nil
}

View File

@@ -1,24 +0,0 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
type AWSConfig struct {
Region string `json:"region"`
Bucket string `json:"bucket"`
AccessKeyID string `json:"access-key-id"`
SecretAccessKey string `json:"secret-access-key"`
Endpoint string `json:"endpoint"`
UsePathStyle bool `json:"use-path-style"`
}

View File

@@ -1,98 +0,0 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
import (
"bytes"
"encoding/json"
"fmt"
"strings"
"go.probo.inc/probo/pkg/connector"
)
type ConnectorConfig struct {
Provider string `json:"provider"`
Protocol connector.ProtocolType `json:"protocol"`
Config connector.Connector `json:"-"`
RawConfig any `json:"config,omitempty"`
Settings any `json:"-"`
RawSettings any `json:"settings,omitempty"`
}
type ConnectorConfigOAuth2 struct {
ClientID string `json:"client-id"`
ClientSecret string `json:"client-secret"`
}
func (c *Config) GetSlackSigningSecret() string {
if c.Notifications.Slack.SigningSecret != "" {
return c.Notifications.Slack.SigningSecret
}
for _, conn := range c.Connectors {
if conn.Provider == "SLACK" {
if settings, ok := conn.Settings.(map[string]any); ok {
if signingSecret, ok := settings["signing-secret"].(string); ok {
return signingSecret
}
}
}
}
return ""
}
func (c *ConnectorConfig) UnmarshalJSON(data []byte) error {
var tmp struct {
Provider string `json:"provider"`
Protocol string `json:"protocol"`
RawConfig json.RawMessage `json:"config"`
Settings json.RawMessage `json:"settings"`
}
if err := json.NewDecoder(bytes.NewReader(data)).Decode(&tmp); err != nil {
return fmt.Errorf("cannot unmarshal connector config: %w", err)
}
c.Provider = strings.ToUpper(tmp.Provider)
c.Protocol = connector.ProtocolType(strings.ToUpper(tmp.Protocol))
if len(tmp.Settings) > 0 {
var settings map[string]any
if err := json.NewDecoder(bytes.NewReader(tmp.Settings)).Decode(&settings); err != nil {
return fmt.Errorf("cannot unmarshal settings: %w", err)
}
c.Settings = settings
}
switch c.Protocol {
case connector.ProtocolOAuth2:
var config ConnectorConfigOAuth2
if err := json.NewDecoder(bytes.NewReader(tmp.RawConfig)).Decode(&config); err != nil {
return fmt.Errorf("cannot unmarshal oauth2 connector config: %w", err)
}
oauth2Connector := connector.OAuth2Connector{
ClientID: config.ClientID,
ClientSecret: config.ClientSecret,
}
c.Config = &oauth2Connector
default:
return fmt.Errorf("unknown connector protocol: %q", c.Protocol)
}
return nil
}

View File

@@ -1,32 +0,0 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
type CustomDomainsConfig struct {
RenewalInterval int `json:"renewal-interval"`
ProvisionInterval int `json:"provision-interval"`
ResolverAddr string `json:"resolver-addr"`
CnameTarget string `json:"cname-target"`
CAAIssuerDomain string `json:"caa-issuer-domain"`
ACME ACMEConfig `json:"acme"`
}
type ACMEConfig struct {
Directory string `json:"directory"`
Email string `json:"email"`
KeyType string `json:"key-type"`
AccountKey string `json:"account-key"`
RootCA string `json:"root-ca"`
}

View File

@@ -1,71 +0,0 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
type (
// LLMProviderConfig holds authentication and connection settings for an
// LLM provider (e.g. OpenAI, Anthropic).
LLMProviderConfig struct {
Type string `json:"type"` // "openai", "anthropic", "bedrock"
APIKey string `json:"api-key"` // for OpenAI and Anthropic
}
// LLMAgentConfig holds model parameters for a single agent. Provider
// references one of the keys in AgentsConfig.Providers.
LLMAgentConfig struct {
Provider string `json:"provider"` // key into AgentsConfig.Providers
ModelName string `json:"model-name"`
Temperature *float64 `json:"temperature"`
MaxTokens *int `json:"max-tokens"`
}
// EvidenceDescriberConfig holds worker-side tuning for the evidence
// description background worker. LLM parameters for the same worker
// live under AgentsConfig.EvidenceDescriber.
EvidenceDescriberConfig struct {
Interval int `json:"interval"` // seconds between polls
StaleAfter int `json:"stale-after"` // seconds before a claim is recycled
MaxConcurrency int `json:"max-concurrency"`
}
// AgentsConfig groups LLM provider credentials and per-agent model
// settings. Default is used as a fallback when an agent-specific field
// is zero-valued.
AgentsConfig struct {
Providers map[string]LLMProviderConfig `json:"providers"`
Default LLMAgentConfig `json:"defaults"`
Probo LLMAgentConfig `json:"probo"`
EvidenceDescriber LLMAgentConfig `json:"evidence-describer"`
VendorAssessor LLMAgentConfig `json:"vendor-assessor"`
}
)
// ResolveAgent returns a fully populated LLMAgentConfig by filling in
// zero-valued fields from the default config.
func (c *AgentsConfig) ResolveAgent(agent LLMAgentConfig) LLMAgentConfig {
if agent.Provider == "" {
agent.Provider = c.Default.Provider
}
if agent.ModelName == "" {
agent.ModelName = c.Default.ModelName
}
if agent.Temperature == nil {
agent.Temperature = c.Default.Temperature
}
if agent.MaxTokens == nil {
agent.MaxTokens = c.Default.MaxTokens
}
return agent
}

View File

@@ -1,29 +0,0 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
type MailerConfig struct {
MailerInterval int `json:"mailer-interval"`
SenderName string `json:"sender-name"`
SenderEmail string `json:"sender-email"`
SMTP SMTPConfig `json:"smtp"`
}
type SMTPConfig struct {
Addr string `json:"addr"`
User string `json:"user"`
Password string `json:"password"`
TLSRequired bool `json:"tls-required"`
}

View File

@@ -1,26 +0,0 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
type NotificationsConfig struct {
Mailer MailerConfig `json:"mailer"`
Slack SlackConfig `json:"slack"`
Webhook WebhookConfig `json:"webhook"`
}
type WebhookConfig struct {
SenderInterval int `json:"sender-interval"`
CacheTTL int `json:"cache-ttl"`
}

View File

@@ -1,21 +0,0 @@
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
type OIDCProviderConfig struct {
ClientID string `json:"client-id"`
ClientSecret string `json:"client-secret"`
Enabled bool `json:"enabled"`
}

View File

@@ -1,101 +0,0 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
import (
"crypto/x509"
"encoding/pem"
"time"
"go.gearno.de/kit/pg"
)
type PgConfig struct {
Addr string `json:"addr"`
Username string `json:"username"`
Password string `json:"password"`
Database string `json:"database"`
PoolSize int32 `json:"pool-size"`
MinPoolSize int32 `json:"min-pool-size"`
MaxConnIdleTimeSeconds int `json:"max-conn-idle-time-seconds"`
MaxConnLifetimeSeconds int `json:"max-conn-lifetime-seconds"`
CACertBundle string `json:"ca-cert-bundle"`
Debug bool `json:"debug"`
}
func (cfg PgConfig) Options(options ...pg.Option) []pg.Option {
opts := []pg.Option{
pg.WithAddr(cfg.Addr),
pg.WithUser(cfg.Username),
pg.WithPassword(cfg.Password),
pg.WithDatabase(cfg.Database),
pg.WithPoolSize(cfg.PoolSize),
}
if cfg.MinPoolSize > 0 {
opts = append(opts, pg.WithMinPoolSize(cfg.MinPoolSize))
}
if cfg.MaxConnIdleTimeSeconds > 0 {
opts = append(
opts,
pg.WithMaxConnIdleTime(
time.Duration(cfg.MaxConnIdleTimeSeconds)*time.Second,
),
)
}
if cfg.MaxConnLifetimeSeconds > 0 {
opts = append(
opts,
pg.WithMaxConnLifetime(
time.Duration(cfg.MaxConnLifetimeSeconds)*time.Second,
),
)
}
if cfg.Debug {
opts = append(opts, pg.WithDebug())
}
if cfg.CACertBundle != "" {
var certs []*x509.Certificate
pemData := []byte(cfg.CACertBundle)
for len(pemData) > 0 {
var block *pem.Block
block, pemData = pem.Decode(pemData)
if block == nil {
break
}
if block.Type != "CERTIFICATE" {
continue
}
cert, err := x509.ParseCertificate(block.Bytes)
if err == nil {
certs = append(certs, cert)
}
}
if len(certs) > 0 {
opts = append(opts, pg.WithTLS(certs))
}
}
opts = append(opts, options...)
return opts
}

View File

@@ -73,71 +73,9 @@ import (
"golang.org/x/sync/errgroup"
)
type (
Implm struct {
cfg Config
}
// FullConfig represents the complete configuration file structure.
// This is used by bootstrap to generate the YAML config file.
FullConfig struct {
Unit UnitConfig `json:"unit"`
Probod Config `json:"probod"`
}
// UnitConfig contains unit framework configuration.
UnitConfig struct {
Metrics MetricsConfig `json:"metrics"`
Tracing TracingConfig `json:"tracing"`
}
// MetricsConfig contains metrics server configuration.
MetricsConfig struct {
Addr string `json:"addr"`
}
// TracingConfig contains tracing configuration.
TracingConfig struct {
Addr string `json:"addr"`
MaxBatchSize int `json:"max-batch-size"`
BatchTimeout int `json:"batch-timeout"`
ExportTimeout int `json:"export-timeout"`
MaxQueueSize int `json:"max-queue-size"`
}
// ESignConfig contains electronic signature configuration.
ESignConfig struct {
TSAURL string `json:"tsa-url"`
}
// Config represents the probod application configuration.
Config struct {
BaseURL string `json:"base-url"`
EncryptionKey string `json:"encryption-key"`
Pg PgConfig `json:"pg"`
Api APIConfig `json:"api"`
Auth AuthConfig `json:"auth"`
TrustCenter TrustCenterConfig `json:"trust-center"`
AWS AWSConfig `json:"aws"`
Notifications NotificationsConfig `json:"notifications"`
Connectors []ConnectorConfig `json:"connectors"`
Agents AgentsConfig `json:"llm"`
EvidenceDescriber EvidenceDescriberConfig `json:"evidence-describer"`
ChromeDPAddr string `json:"chrome-dp-addr"`
SearchEndpoint string `json:"search-endpoint"`
CustomDomains CustomDomainsConfig `json:"custom-domains"`
SCIMBridge SCIMBridgeConfig `json:"scim-bridge"`
ESign ESignConfig `json:"esign"`
Branding bool `json:"branding"`
}
// TrustCenterConfig contains trust center server configuration.
TrustCenterConfig struct {
HTTPAddr string `json:"http-addr"`
HTTPSAddr string `json:"https-addr"`
ProxyProtocol ProxyProtocolConfig `json:"proxy-protocol"`
}
)
type Implm struct {
cfg Config
}
var (
_ unit.Configurable = (*Implm)(nil)

View File

@@ -1,47 +0,0 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
import (
"time"
)
type SAMLConfig struct {
SessionDuration int `json:"session-duration"`
CleanupIntervalSeconds int `json:"cleanup-interval-seconds"`
Certificate string `json:"certificate"`
PrivateKey string `json:"private-key"`
DomainVerificationIntervalSeconds int `json:"domain-verification-interval-seconds"`
DomainVerificationResolverAddr string `json:"domain-verification-resolver-addr"`
}
func (c SAMLConfig) SessionDurationTime() time.Duration {
if c.SessionDuration == 0 {
return 7 * 24 * time.Hour
}
return time.Duration(c.SessionDuration) * time.Second
}
func (c SAMLConfig) CleanupInterval() time.Duration {
if c.CleanupIntervalSeconds == 0 {
return 0
}
return time.Duration(c.CleanupIntervalSeconds) * time.Second
}
func (c SAMLConfig) DomainVerificationInterval() time.Duration {
return time.Duration(c.DomainVerificationIntervalSeconds) * time.Second
}

View File

@@ -1,20 +0,0 @@
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
type SCIMBridgeConfig struct {
SyncInterval int `json:"sync-interval"`
PollInterval int `json:"poll-interval"`
}

View File

@@ -1,20 +0,0 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probod
type SlackConfig struct {
SenderInterval int `json:"sender-interval"`
SigningSecret string `json:"signing-secret"`
}