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

View File

@@ -20,7 +20,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"go.probo.inc/probo/pkg/probod" "go.probo.inc/probo/pkg/probodconfig"
) )
type EnvGetter func(key string) string type EnvGetter func(key string) string
@@ -39,7 +39,7 @@ func NewBuilder(getEnv EnvGetter) *Builder {
return &Builder{getEnv: getEnv} return &Builder{getEnv: getEnv}
} }
func (b *Builder) Build() (*probod.FullConfig, error) { func (b *Builder) Build() (*probodconfig.FullConfig, error) {
if err := b.validateRequired(); err != nil { if err := b.validateRequired(); err != nil {
return nil, err return nil, err
} }
@@ -53,12 +53,12 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
pgCACertBundle := b.getPgCACertBundle() pgCACertBundle := b.getPgCACertBundle()
cfg := &probod.FullConfig{ cfg := &probodconfig.FullConfig{
Unit: probod.UnitConfig{ Unit: probodconfig.UnitConfig{
Metrics: probod.MetricsConfig{ Metrics: probodconfig.MetricsConfig{
Addr: b.getEnvOrDefault("METRICS_ADDR", "localhost:8081"), Addr: b.getEnvOrDefault("METRICS_ADDR", "localhost:8081"),
}, },
Tracing: probod.TracingConfig{ Tracing: probodconfig.TracingConfig{
Addr: b.getEnvOrDefault("TRACING_ADDR", "localhost:4317"), Addr: b.getEnvOrDefault("TRACING_ADDR", "localhost:4317"),
MaxBatchSize: b.getEnvIntOrDefault("TRACING_MAX_BATCH_SIZE", 512), MaxBatchSize: b.getEnvIntOrDefault("TRACING_MAX_BATCH_SIZE", 512),
BatchTimeout: b.getEnvIntOrDefault("TRACING_BATCH_TIMEOUT", 5), BatchTimeout: b.getEnvIntOrDefault("TRACING_BATCH_TIMEOUT", 5),
@@ -66,21 +66,21 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
MaxQueueSize: b.getEnvIntOrDefault("TRACING_MAX_QUEUE_SIZE", 2048), MaxQueueSize: b.getEnvIntOrDefault("TRACING_MAX_QUEUE_SIZE", 2048),
}, },
}, },
Probod: probod.Config{ Probod: probodconfig.Config{
BaseURL: b.getEnvOrDefault("PROBOD_BASE_URL", "http://localhost:8080"), BaseURL: b.getEnvOrDefault("PROBOD_BASE_URL", "http://localhost:8080"),
EncryptionKey: b.getEnv("PROBOD_ENCRYPTION_KEY"), EncryptionKey: b.getEnv("PROBOD_ENCRYPTION_KEY"),
ChromeDPAddr: b.getEnvOrDefault("CHROME_DP_ADDR", "localhost:9222"), ChromeDPAddr: b.getEnvOrDefault("CHROME_DP_ADDR", "localhost:9222"),
Api: probod.APIConfig{ Api: probodconfig.APIConfig{
Addr: b.getEnvOrDefault("API_ADDR", ":8080"), Addr: b.getEnvOrDefault("API_ADDR", ":8080"),
ProxyProtocol: probod.ProxyProtocolConfig{ ProxyProtocol: probodconfig.ProxyProtocolConfig{
TrustedProxies: b.parseOriginsList(b.getEnv("API_PROXY_PROTOCOL_TRUSTED_PROXIES")), TrustedProxies: b.parseOriginsList(b.getEnv("API_PROXY_PROTOCOL_TRUSTED_PROXIES")),
}, },
Cors: probod.CorsConfig{ Cors: probodconfig.CorsConfig{
AllowedOrigins: b.parseOriginsList(b.getEnvOrDefault("API_CORS_ALLOWED_ORIGINS", "http://localhost:8080")), AllowedOrigins: b.parseOriginsList(b.getEnvOrDefault("API_CORS_ALLOWED_ORIGINS", "http://localhost:8080")),
}, },
ExtraHeaderFields: make(map[string]string), ExtraHeaderFields: make(map[string]string),
}, },
Pg: probod.PgConfig{ Pg: probodconfig.PgConfig{
Addr: b.getEnvOrDefault("PG_ADDR", "localhost:5432"), Addr: b.getEnvOrDefault("PG_ADDR", "localhost:5432"),
Username: b.getEnvOrDefault("PG_USERNAME", "postgres"), Username: b.getEnvOrDefault("PG_USERNAME", "postgres"),
Password: b.getEnvOrDefault("PG_PASSWORD", "postgres"), Password: b.getEnvOrDefault("PG_PASSWORD", "postgres"),
@@ -92,23 +92,23 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
CACertBundle: pgCACertBundle, CACertBundle: pgCACertBundle,
Debug: b.getEnvBoolOrDefault("PG_DEBUG", false), Debug: b.getEnvBoolOrDefault("PG_DEBUG", false),
}, },
Auth: probod.AuthConfig{ Auth: probodconfig.AuthConfig{
DisableSignup: b.getEnvBoolOrDefault("AUTH_DISABLE_SIGNUP", false), DisableSignup: b.getEnvBoolOrDefault("AUTH_DISABLE_SIGNUP", false),
InvitationConfirmationTokenValidity: b.getEnvIntOrDefault("AUTH_INVITATION_TOKEN_VALIDITY", 3600), InvitationConfirmationTokenValidity: b.getEnvIntOrDefault("AUTH_INVITATION_TOKEN_VALIDITY", 3600),
PasswordResetTokenValidity: b.getEnvIntOrDefault("AUTH_PASSWORD_RESET_TOKEN_VALIDITY", 3600), PasswordResetTokenValidity: b.getEnvIntOrDefault("AUTH_PASSWORD_RESET_TOKEN_VALIDITY", 3600),
MagicLinkTokenValidity: b.getEnvIntOrDefault("AUTH_MAGIC_LINK_TOKEN_VALIDITY", 900), MagicLinkTokenValidity: b.getEnvIntOrDefault("AUTH_MAGIC_LINK_TOKEN_VALIDITY", 900),
Cookie: probod.CookieConfig{ Cookie: probodconfig.CookieConfig{
Name: b.getEnvOrDefault("AUTH_COOKIE_NAME", "SSID"), Name: b.getEnvOrDefault("AUTH_COOKIE_NAME", "SSID"),
Domain: b.getEnvOrDefault("AUTH_COOKIE_DOMAIN", "localhost"), Domain: b.getEnvOrDefault("AUTH_COOKIE_DOMAIN", "localhost"),
Secret: b.getEnv("AUTH_COOKIE_SECRET"), Secret: b.getEnv("AUTH_COOKIE_SECRET"),
Duration: b.getEnvIntOrDefault("AUTH_COOKIE_DURATION", 24), Duration: b.getEnvIntOrDefault("AUTH_COOKIE_DURATION", 24),
Secure: b.getEnvBoolOrDefault("AUTH_COOKIE_SECURE", true), Secure: b.getEnvBoolOrDefault("AUTH_COOKIE_SECURE", true),
}, },
Password: probod.PasswordConfig{ Password: probodconfig.PasswordConfig{
Pepper: b.getEnv("AUTH_PASSWORD_PEPPER"), Pepper: b.getEnv("AUTH_PASSWORD_PEPPER"),
Iterations: b.getEnvIntOrDefault("AUTH_PASSWORD_ITERATIONS", 1000000), Iterations: b.getEnvIntOrDefault("AUTH_PASSWORD_ITERATIONS", 1000000),
}, },
SAML: probod.SAMLConfig{ SAML: probodconfig.SAMLConfig{
SessionDuration: b.getEnvIntOrDefault("SAML_SESSION_DURATION", 604800), SessionDuration: b.getEnvIntOrDefault("SAML_SESSION_DURATION", 604800),
CleanupIntervalSeconds: b.getEnvIntOrDefault("SAML_CLEANUP_INTERVAL_SECONDS", 0), CleanupIntervalSeconds: b.getEnvIntOrDefault("SAML_CLEANUP_INTERVAL_SECONDS", 0),
Certificate: samlCert, Certificate: samlCert,
@@ -116,18 +116,18 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
DomainVerificationIntervalSeconds: b.getEnvIntOrDefault("SAML_DOMAIN_VERIFICATION_INTERVAL_SECONDS", 60), DomainVerificationIntervalSeconds: b.getEnvIntOrDefault("SAML_DOMAIN_VERIFICATION_INTERVAL_SECONDS", 60),
DomainVerificationResolverAddr: b.getEnvOrDefault("SAML_DOMAIN_VERIFICATION_RESOLVER_ADDR", "8.8.8.8:53"), DomainVerificationResolverAddr: b.getEnvOrDefault("SAML_DOMAIN_VERIFICATION_RESOLVER_ADDR", "8.8.8.8:53"),
}, },
Google: probod.OIDCProviderConfig{ Google: probodconfig.OIDCProviderConfig{
ClientID: b.getEnv("AUTH_GOOGLE_CLIENT_ID"), ClientID: b.getEnv("AUTH_GOOGLE_CLIENT_ID"),
ClientSecret: b.getEnv("AUTH_GOOGLE_CLIENT_SECRET"), ClientSecret: b.getEnv("AUTH_GOOGLE_CLIENT_SECRET"),
Enabled: b.getEnv("AUTH_GOOGLE_CLIENT_ID") != "" && b.getEnv("AUTH_GOOGLE_CLIENT_SECRET") != "", Enabled: b.getEnv("AUTH_GOOGLE_CLIENT_ID") != "" && b.getEnv("AUTH_GOOGLE_CLIENT_SECRET") != "",
}, },
Microsoft: probod.OIDCProviderConfig{ Microsoft: probodconfig.OIDCProviderConfig{
ClientID: b.getEnv("AUTH_MICROSOFT_CLIENT_ID"), ClientID: b.getEnv("AUTH_MICROSOFT_CLIENT_ID"),
ClientSecret: b.getEnv("AUTH_MICROSOFT_CLIENT_SECRET"), ClientSecret: b.getEnv("AUTH_MICROSOFT_CLIENT_SECRET"),
Enabled: b.getEnv("AUTH_MICROSOFT_CLIENT_ID") != "" && b.getEnv("AUTH_MICROSOFT_CLIENT_SECRET") != "", Enabled: b.getEnv("AUTH_MICROSOFT_CLIENT_ID") != "" && b.getEnv("AUTH_MICROSOFT_CLIENT_SECRET") != "",
}, },
OAuth2Server: probod.OAuth2ServerConfig{ OAuth2Server: probodconfig.OAuth2ServerConfig{
SigningKeys: []probod.OAuth2SigningKeyConfig{{ SigningKeys: []probodconfig.OAuth2SigningKeyConfig{{
PrivateKey: oauth2SigningKey, PrivateKey: oauth2SigningKey,
KID: b.getEnvOrDefault("OAUTH2_SERVER_SIGNING_KEY_KID", "default"), KID: b.getEnvOrDefault("OAUTH2_SERVER_SIGNING_KEY_KID", "default"),
Active: true, Active: true,
@@ -138,14 +138,14 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
DeviceCodeDuration: b.getEnvIntOrDefault("OAUTH2_SERVER_DEVICE_CODE_DURATION", 600), DeviceCodeDuration: b.getEnvIntOrDefault("OAUTH2_SERVER_DEVICE_CODE_DURATION", 600),
}, },
}, },
TrustCenter: probod.TrustCenterConfig{ TrustCenter: probodconfig.TrustCenterConfig{
HTTPAddr: b.getEnvOrDefault("TRUST_CENTER_HTTP_ADDR", ":80"), HTTPAddr: b.getEnvOrDefault("TRUST_CENTER_HTTP_ADDR", ":80"),
HTTPSAddr: b.getEnvOrDefault("TRUST_CENTER_HTTPS_ADDR", ":443"), HTTPSAddr: b.getEnvOrDefault("TRUST_CENTER_HTTPS_ADDR", ":443"),
ProxyProtocol: probod.ProxyProtocolConfig{ ProxyProtocol: probodconfig.ProxyProtocolConfig{
TrustedProxies: b.parseOriginsList(b.getEnv("TRUST_CENTER_PROXY_PROTOCOL_TRUSTED_PROXIES")), TrustedProxies: b.parseOriginsList(b.getEnv("TRUST_CENTER_PROXY_PROTOCOL_TRUSTED_PROXIES")),
}, },
}, },
AWS: probod.AWSConfig{ AWS: probodconfig.AWSConfig{
Region: b.getEnvOrDefault("AWS_REGION", "us-east-1"), Region: b.getEnvOrDefault("AWS_REGION", "us-east-1"),
Bucket: b.getEnvOrDefault("AWS_BUCKET", "probod"), Bucket: b.getEnvOrDefault("AWS_BUCKET", "probod"),
AccessKeyID: b.getEnv("AWS_ACCESS_KEY_ID"), AccessKeyID: b.getEnv("AWS_ACCESS_KEY_ID"),
@@ -153,29 +153,29 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
Endpoint: b.getEnv("AWS_ENDPOINT"), Endpoint: b.getEnv("AWS_ENDPOINT"),
UsePathStyle: b.getEnvBoolOrDefault("AWS_USE_PATH_STYLE", false), UsePathStyle: b.getEnvBoolOrDefault("AWS_USE_PATH_STYLE", false),
}, },
Notifications: probod.NotificationsConfig{ Notifications: probodconfig.NotificationsConfig{
Mailer: probod.MailerConfig{ Mailer: probodconfig.MailerConfig{
SenderName: b.getEnvOrDefault("MAILER_SENDER_NAME", "Probo"), SenderName: b.getEnvOrDefault("MAILER_SENDER_NAME", "Probo"),
SenderEmail: b.getEnvOrDefault("MAILER_SENDER_EMAIL", "no-reply@notification.getprobo.com"), SenderEmail: b.getEnvOrDefault("MAILER_SENDER_EMAIL", "no-reply@notification.getprobo.com"),
MailerInterval: b.getEnvIntOrDefault("MAILER_INTERVAL", 60), MailerInterval: b.getEnvIntOrDefault("MAILER_INTERVAL", 60),
SMTP: probod.SMTPConfig{ SMTP: probodconfig.SMTPConfig{
Addr: b.getEnvOrDefault("SMTP_ADDR", "localhost:1025"), Addr: b.getEnvOrDefault("SMTP_ADDR", "localhost:1025"),
User: b.getEnv("SMTP_USER"), User: b.getEnv("SMTP_USER"),
Password: b.getEnv("SMTP_PASSWORD"), Password: b.getEnv("SMTP_PASSWORD"),
TLSRequired: b.getEnvBoolOrDefault("SMTP_TLS_REQUIRED", false), TLSRequired: b.getEnvBoolOrDefault("SMTP_TLS_REQUIRED", false),
}, },
}, },
Slack: probod.SlackConfig{ Slack: probodconfig.SlackConfig{
SenderInterval: b.getEnvIntOrDefault("SLACK_SENDER_INTERVAL", 60), SenderInterval: b.getEnvIntOrDefault("SLACK_SENDER_INTERVAL", 60),
SigningSecret: b.getEnv("CONNECTOR_SLACK_SIGNING_SECRET"), SigningSecret: b.getEnv("CONNECTOR_SLACK_SIGNING_SECRET"),
}, },
Webhook: probod.WebhookConfig{ Webhook: probodconfig.WebhookConfig{
SenderInterval: b.getEnvIntOrDefault("WEBHOOK_SENDER_INTERVAL", 5), SenderInterval: b.getEnvIntOrDefault("WEBHOOK_SENDER_INTERVAL", 5),
CacheTTL: b.getEnvIntOrDefault("WEBHOOK_CACHE_TTL", 86400), CacheTTL: b.getEnvIntOrDefault("WEBHOOK_CACHE_TTL", 86400),
}, },
}, },
Agents: probod.AgentsConfig{ Agents: probodconfig.AgentsConfig{
Providers: map[string]probod.LLMProviderConfig{ Providers: map[string]probodconfig.LLMProviderConfig{
"openai": { "openai": {
Type: "openai", Type: "openai",
APIKey: b.getEnv("OPENAI_API_KEY"), APIKey: b.getEnv("OPENAI_API_KEY"),
@@ -185,32 +185,32 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
APIKey: b.getEnv("ANTHROPIC_API_KEY"), APIKey: b.getEnv("ANTHROPIC_API_KEY"),
}, },
}, },
Default: probod.LLMAgentConfig{ Default: probodconfig.LLMAgentConfig{
Provider: b.getEnvOrDefault("AGENT_DEFAULT_PROVIDER", "openai"), Provider: b.getEnvOrDefault("AGENT_DEFAULT_PROVIDER", "openai"),
ModelName: b.getEnvOrDefault("AGENT_DEFAULT_MODEL_NAME", "gpt-4o"), ModelName: b.getEnvOrDefault("AGENT_DEFAULT_MODEL_NAME", "gpt-4o"),
Temperature: new(b.getEnvFloatOrDefault("AGENT_DEFAULT_TEMPERATURE", 0.1)), Temperature: new(b.getEnvFloatOrDefault("AGENT_DEFAULT_TEMPERATURE", 0.1)),
MaxTokens: new(b.getEnvIntOrDefault("AGENT_DEFAULT_MAX_TOKENS", 4096)), MaxTokens: new(b.getEnvIntOrDefault("AGENT_DEFAULT_MAX_TOKENS", 4096)),
}, },
Probo: probod.LLMAgentConfig{ Probo: probodconfig.LLMAgentConfig{
Provider: b.getEnvOrDefault("AGENT_PROBO_PROVIDER", ""), Provider: b.getEnvOrDefault("AGENT_PROBO_PROVIDER", ""),
ModelName: b.getEnvOrDefault("AGENT_PROBO_MODEL_NAME", ""), ModelName: b.getEnvOrDefault("AGENT_PROBO_MODEL_NAME", ""),
Temperature: b.getEnvFloatPtr("AGENT_PROBO_TEMPERATURE"), Temperature: b.getEnvFloatPtr("AGENT_PROBO_TEMPERATURE"),
MaxTokens: b.getEnvIntPtr("AGENT_PROBO_MAX_TOKENS"), MaxTokens: b.getEnvIntPtr("AGENT_PROBO_MAX_TOKENS"),
}, },
EvidenceDescriber: probod.LLMAgentConfig{ EvidenceDescriber: probodconfig.LLMAgentConfig{
Provider: b.getEnvOrDefault("AGENT_EVIDENCE_DESCRIBER_PROVIDER", ""), Provider: b.getEnvOrDefault("AGENT_EVIDENCE_DESCRIBER_PROVIDER", ""),
ModelName: b.getEnvOrDefault("AGENT_EVIDENCE_DESCRIBER_MODEL_NAME", ""), ModelName: b.getEnvOrDefault("AGENT_EVIDENCE_DESCRIBER_MODEL_NAME", ""),
Temperature: b.getEnvFloatPtr("AGENT_EVIDENCE_DESCRIBER_TEMPERATURE"), Temperature: b.getEnvFloatPtr("AGENT_EVIDENCE_DESCRIBER_TEMPERATURE"),
MaxTokens: b.getEnvIntPtr("AGENT_EVIDENCE_DESCRIBER_MAX_TOKENS"), MaxTokens: b.getEnvIntPtr("AGENT_EVIDENCE_DESCRIBER_MAX_TOKENS"),
}, },
}, },
CustomDomains: probod.CustomDomainsConfig{ CustomDomains: probodconfig.CustomDomainsConfig{
RenewalInterval: b.getEnvIntOrDefault("CUSTOM_DOMAINS_RENEWAL_INTERVAL", 3600), RenewalInterval: b.getEnvIntOrDefault("CUSTOM_DOMAINS_RENEWAL_INTERVAL", 3600),
ProvisionInterval: b.getEnvIntOrDefault("CUSTOM_DOMAINS_PROVISION_INTERVAL", 30), ProvisionInterval: b.getEnvIntOrDefault("CUSTOM_DOMAINS_PROVISION_INTERVAL", 30),
CnameTarget: b.getEnvOrDefault("CUSTOM_DOMAINS_CNAME_TARGET", "custom.getprobo.com"), CnameTarget: b.getEnvOrDefault("CUSTOM_DOMAINS_CNAME_TARGET", "custom.getprobo.com"),
ResolverAddr: b.getEnvOrDefault("CUSTOM_DOMAINS_RESOLVER_ADDR", "8.8.8.8:53"), ResolverAddr: b.getEnvOrDefault("CUSTOM_DOMAINS_RESOLVER_ADDR", "8.8.8.8:53"),
CAAIssuerDomain: b.getEnvOrDefault("CUSTOM_DOMAINS_CAA_ISSUER_DOMAIN", "letsencrypt.org"), CAAIssuerDomain: b.getEnvOrDefault("CUSTOM_DOMAINS_CAA_ISSUER_DOMAIN", "letsencrypt.org"),
ACME: probod.ACMEConfig{ ACME: probodconfig.ACMEConfig{
Directory: b.getEnvOrDefault("ACME_DIRECTORY", "https://acme-v02.api.letsencrypt.org/directory"), Directory: b.getEnvOrDefault("ACME_DIRECTORY", "https://acme-v02.api.letsencrypt.org/directory"),
Email: b.getEnvOrDefault("ACME_EMAIL", "admin@getprobo.com"), Email: b.getEnvOrDefault("ACME_EMAIL", "admin@getprobo.com"),
KeyType: b.getEnvOrDefault("ACME_KEY_TYPE", "EC256"), KeyType: b.getEnvOrDefault("ACME_KEY_TYPE", "EC256"),
@@ -218,14 +218,14 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
AccountKey: b.getEnv("ACME_ACCOUNT_KEY"), AccountKey: b.getEnv("ACME_ACCOUNT_KEY"),
}, },
}, },
SCIMBridge: probod.SCIMBridgeConfig{ SCIMBridge: probodconfig.SCIMBridgeConfig{
SyncInterval: b.getEnvIntOrDefault("SCIM_BRIDGE_SYNC_INTERVAL", 900), SyncInterval: b.getEnvIntOrDefault("SCIM_BRIDGE_SYNC_INTERVAL", 900),
PollInterval: b.getEnvIntOrDefault("SCIM_BRIDGE_POLL_INTERVAL", 30), PollInterval: b.getEnvIntOrDefault("SCIM_BRIDGE_POLL_INTERVAL", 30),
}, },
ESign: probod.ESignConfig{ ESign: probodconfig.ESignConfig{
TSAURL: b.getEnvOrDefault("ESIGN_TSA_URL", "http://timestamp.digicert.com"), TSAURL: b.getEnvOrDefault("ESIGN_TSA_URL", "http://timestamp.digicert.com"),
}, },
EvidenceDescriber: probod.EvidenceDescriberConfig{ EvidenceDescriber: probodconfig.EvidenceDescriberConfig{
Interval: b.getEnvIntOrDefault("EVIDENCE_DESCRIBER_INTERVAL", 10), Interval: b.getEnvIntOrDefault("EVIDENCE_DESCRIBER_INTERVAL", 10),
StaleAfter: b.getEnvIntOrDefault("EVIDENCE_DESCRIBER_STALE_AFTER", 300), StaleAfter: b.getEnvIntOrDefault("EVIDENCE_DESCRIBER_STALE_AFTER", 300),
MaxConcurrency: b.getEnvIntOrDefault("EVIDENCE_DESCRIBER_MAX_CONCURRENCY", 10), MaxConcurrency: b.getEnvIntOrDefault("EVIDENCE_DESCRIBER_MAX_CONCURRENCY", 10),
@@ -235,10 +235,10 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
} }
if slackClientID := b.getEnv("CONNECTOR_SLACK_CLIENT_ID"); slackClientID != "" { if slackClientID := b.getEnv("CONNECTOR_SLACK_CLIENT_ID"); slackClientID != "" {
cfg.Probod.Connectors = append(cfg.Probod.Connectors, probod.ConnectorConfig{ cfg.Probod.Connectors = append(cfg.Probod.Connectors, probodconfig.ConnectorConfig{
Provider: "SLACK", Provider: "SLACK",
Protocol: "oauth2", Protocol: "oauth2",
RawConfig: probod.ConnectorConfigOAuth2{ RawConfig: probodconfig.ConnectorConfigOAuth2{
ClientID: slackClientID, ClientID: slackClientID,
ClientSecret: b.getEnv("CONNECTOR_SLACK_CLIENT_SECRET"), ClientSecret: b.getEnv("CONNECTOR_SLACK_CLIENT_SECRET"),
}, },
@@ -249,10 +249,10 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
} }
if hubspotClientID := b.getEnv("CONNECTOR_HUBSPOT_CLIENT_ID"); hubspotClientID != "" { if hubspotClientID := b.getEnv("CONNECTOR_HUBSPOT_CLIENT_ID"); hubspotClientID != "" {
cfg.Probod.Connectors = append(cfg.Probod.Connectors, probod.ConnectorConfig{ cfg.Probod.Connectors = append(cfg.Probod.Connectors, probodconfig.ConnectorConfig{
Provider: "HUBSPOT", Provider: "HUBSPOT",
Protocol: "oauth2", Protocol: "oauth2",
RawConfig: probod.ConnectorConfigOAuth2{ RawConfig: probodconfig.ConnectorConfigOAuth2{
ClientID: hubspotClientID, ClientID: hubspotClientID,
ClientSecret: b.getEnv("CONNECTOR_HUBSPOT_CLIENT_SECRET"), ClientSecret: b.getEnv("CONNECTOR_HUBSPOT_CLIENT_SECRET"),
}, },
@@ -260,10 +260,10 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
} }
if docusignClientID := b.getEnv("CONNECTOR_DOCUSIGN_CLIENT_ID"); docusignClientID != "" { if docusignClientID := b.getEnv("CONNECTOR_DOCUSIGN_CLIENT_ID"); docusignClientID != "" {
cfg.Probod.Connectors = append(cfg.Probod.Connectors, probod.ConnectorConfig{ cfg.Probod.Connectors = append(cfg.Probod.Connectors, probodconfig.ConnectorConfig{
Provider: "DOCUSIGN", Provider: "DOCUSIGN",
Protocol: "oauth2", Protocol: "oauth2",
RawConfig: probod.ConnectorConfigOAuth2{ RawConfig: probodconfig.ConnectorConfigOAuth2{
ClientID: docusignClientID, ClientID: docusignClientID,
ClientSecret: b.getEnv("CONNECTOR_DOCUSIGN_CLIENT_SECRET"), ClientSecret: b.getEnv("CONNECTOR_DOCUSIGN_CLIENT_SECRET"),
}, },
@@ -271,10 +271,10 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
} }
if notionClientID := b.getEnv("CONNECTOR_NOTION_CLIENT_ID"); notionClientID != "" { if notionClientID := b.getEnv("CONNECTOR_NOTION_CLIENT_ID"); notionClientID != "" {
cfg.Probod.Connectors = append(cfg.Probod.Connectors, probod.ConnectorConfig{ cfg.Probod.Connectors = append(cfg.Probod.Connectors, probodconfig.ConnectorConfig{
Provider: "NOTION", Provider: "NOTION",
Protocol: "oauth2", Protocol: "oauth2",
RawConfig: probod.ConnectorConfigOAuth2{ RawConfig: probodconfig.ConnectorConfigOAuth2{
ClientID: notionClientID, ClientID: notionClientID,
ClientSecret: b.getEnv("CONNECTOR_NOTION_CLIENT_SECRET"), ClientSecret: b.getEnv("CONNECTOR_NOTION_CLIENT_SECRET"),
}, },
@@ -282,10 +282,10 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
} }
if githubClientID := b.getEnv("CONNECTOR_GITHUB_CLIENT_ID"); githubClientID != "" { if githubClientID := b.getEnv("CONNECTOR_GITHUB_CLIENT_ID"); githubClientID != "" {
cfg.Probod.Connectors = append(cfg.Probod.Connectors, probod.ConnectorConfig{ cfg.Probod.Connectors = append(cfg.Probod.Connectors, probodconfig.ConnectorConfig{
Provider: "GITHUB", Provider: "GITHUB",
Protocol: "oauth2", Protocol: "oauth2",
RawConfig: probod.ConnectorConfigOAuth2{ RawConfig: probodconfig.ConnectorConfigOAuth2{
ClientID: githubClientID, ClientID: githubClientID,
ClientSecret: b.getEnv("CONNECTOR_GITHUB_CLIENT_SECRET"), ClientSecret: b.getEnv("CONNECTOR_GITHUB_CLIENT_SECRET"),
}, },
@@ -293,10 +293,10 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
} }
if sentryClientID := b.getEnv("CONNECTOR_SENTRY_CLIENT_ID"); sentryClientID != "" { if sentryClientID := b.getEnv("CONNECTOR_SENTRY_CLIENT_ID"); sentryClientID != "" {
cfg.Probod.Connectors = append(cfg.Probod.Connectors, probod.ConnectorConfig{ cfg.Probod.Connectors = append(cfg.Probod.Connectors, probodconfig.ConnectorConfig{
Provider: "SENTRY", Provider: "SENTRY",
Protocol: "oauth2", Protocol: "oauth2",
RawConfig: probod.ConnectorConfigOAuth2{ RawConfig: probodconfig.ConnectorConfigOAuth2{
ClientID: sentryClientID, ClientID: sentryClientID,
ClientSecret: b.getEnv("CONNECTOR_SENTRY_CLIENT_SECRET"), ClientSecret: b.getEnv("CONNECTOR_SENTRY_CLIENT_SECRET"),
}, },
@@ -304,10 +304,10 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
} }
if intercomClientID := b.getEnv("CONNECTOR_INTERCOM_CLIENT_ID"); intercomClientID != "" { if intercomClientID := b.getEnv("CONNECTOR_INTERCOM_CLIENT_ID"); intercomClientID != "" {
cfg.Probod.Connectors = append(cfg.Probod.Connectors, probod.ConnectorConfig{ cfg.Probod.Connectors = append(cfg.Probod.Connectors, probodconfig.ConnectorConfig{
Provider: "INTERCOM", Provider: "INTERCOM",
Protocol: "oauth2", Protocol: "oauth2",
RawConfig: probod.ConnectorConfigOAuth2{ RawConfig: probodconfig.ConnectorConfigOAuth2{
ClientID: intercomClientID, ClientID: intercomClientID,
ClientSecret: b.getEnv("CONNECTOR_INTERCOM_CLIENT_SECRET"), ClientSecret: b.getEnv("CONNECTOR_INTERCOM_CLIENT_SECRET"),
}, },
@@ -315,10 +315,10 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
} }
if brexClientID := b.getEnv("CONNECTOR_BREX_CLIENT_ID"); brexClientID != "" { if brexClientID := b.getEnv("CONNECTOR_BREX_CLIENT_ID"); brexClientID != "" {
cfg.Probod.Connectors = append(cfg.Probod.Connectors, probod.ConnectorConfig{ cfg.Probod.Connectors = append(cfg.Probod.Connectors, probodconfig.ConnectorConfig{
Provider: "BREX", Provider: "BREX",
Protocol: "oauth2", Protocol: "oauth2",
RawConfig: probod.ConnectorConfigOAuth2{ RawConfig: probodconfig.ConnectorConfigOAuth2{
ClientID: brexClientID, ClientID: brexClientID,
ClientSecret: b.getEnv("CONNECTOR_BREX_CLIENT_SECRET"), ClientSecret: b.getEnv("CONNECTOR_BREX_CLIENT_SECRET"),
}, },
@@ -326,10 +326,10 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
} }
if googleWorkspaceClientID := b.getEnv("CONNECTOR_GOOGLE_WORKSPACE_CLIENT_ID"); googleWorkspaceClientID != "" { if googleWorkspaceClientID := b.getEnv("CONNECTOR_GOOGLE_WORKSPACE_CLIENT_ID"); googleWorkspaceClientID != "" {
cfg.Probod.Connectors = append(cfg.Probod.Connectors, probod.ConnectorConfig{ cfg.Probod.Connectors = append(cfg.Probod.Connectors, probodconfig.ConnectorConfig{
Provider: "GOOGLE_WORKSPACE", Provider: "GOOGLE_WORKSPACE",
Protocol: "oauth2", Protocol: "oauth2",
RawConfig: probod.ConnectorConfigOAuth2{ RawConfig: probodconfig.ConnectorConfigOAuth2{
ClientID: googleWorkspaceClientID, ClientID: googleWorkspaceClientID,
ClientSecret: b.getEnv("CONNECTOR_GOOGLE_WORKSPACE_CLIENT_SECRET"), ClientSecret: b.getEnv("CONNECTOR_GOOGLE_WORKSPACE_CLIENT_SECRET"),
}, },

View File

@@ -21,7 +21,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.probo.inc/probo/pkg/probod" "go.probo.inc/probo/pkg/probodconfig"
) )
func mockEnv(env map[string]string) EnvGetter { func mockEnv(env map[string]string) EnvGetter {
@@ -393,7 +393,7 @@ func TestBuilder_Build_GoogleWorkspaceConnector(t *testing.T) {
connector := cfg.Probod.Connectors[0] connector := cfg.Probod.Connectors[0]
assert.Equal(t, "GOOGLE_WORKSPACE", connector.Provider) assert.Equal(t, "GOOGLE_WORKSPACE", connector.Provider)
assert.Equal(t, "oauth2", string(connector.Protocol)) assert.Equal(t, "oauth2", string(connector.Protocol))
rawConfig := connector.RawConfig.(probod.ConnectorConfigOAuth2) rawConfig := connector.RawConfig.(probodconfig.ConnectorConfigOAuth2)
assert.Equal(t, "gw-client-id", rawConfig.ClientID) assert.Equal(t, "gw-client-id", rawConfig.ClientID)
assert.Equal(t, "gw-client-secret", rawConfig.ClientSecret) assert.Equal(t, "gw-client-secret", rawConfig.ClientSecret)
} }
@@ -415,7 +415,7 @@ func TestBuilder_Build_SlackConnector(t *testing.T) {
connector := cfg.Probod.Connectors[0] connector := cfg.Probod.Connectors[0]
assert.Equal(t, "SLACK", connector.Provider) assert.Equal(t, "SLACK", connector.Provider)
assert.Equal(t, "oauth2", string(connector.Protocol)) assert.Equal(t, "oauth2", string(connector.Protocol))
rawConfig := connector.RawConfig.(probod.ConnectorConfigOAuth2) rawConfig := connector.RawConfig.(probodconfig.ConnectorConfigOAuth2)
assert.Equal(t, "slack-client-id", rawConfig.ClientID) assert.Equal(t, "slack-client-id", rawConfig.ClientID)
assert.Equal(t, "slack-client-secret", rawConfig.ClientSecret) assert.Equal(t, "slack-client-secret", rawConfig.ClientSecret)
rawSettings := connector.RawSettings.(map[string]any) rawSettings := connector.RawSettings.(map[string]any)

View File

@@ -19,11 +19,11 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"go.probo.inc/probo/pkg/probod" "go.probo.inc/probo/pkg/probodconfig"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
func WriteConfig(cfg *probod.FullConfig, path string) error { func WriteConfig(cfg *probodconfig.FullConfig, path string) error {
dir := filepath.Dir(path) dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil { if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("create directory %s: %w", dir, err) return fmt.Errorf("create directory %s: %w", dir, err)

View File

@@ -21,7 +21,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.probo.inc/probo/pkg/probod" "go.probo.inc/probo/pkg/probodconfig"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
@@ -29,11 +29,11 @@ func TestWriteConfig(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
configPath := filepath.Join(tmpDir, "probod.yml") configPath := filepath.Join(tmpDir, "probod.yml")
cfg := &probod.FullConfig{ cfg := &probodconfig.FullConfig{
Unit: probod.UnitConfig{ Unit: probodconfig.UnitConfig{
Metrics: probod.MetricsConfig{Addr: "localhost:9090"}, Metrics: probodconfig.MetricsConfig{Addr: "localhost:9090"},
}, },
Probod: probod.Config{ Probod: probodconfig.Config{
BaseURL: "http://localhost:8080", BaseURL: "http://localhost:8080",
EncryptionKey: "test-key", EncryptionKey: "test-key",
}, },
@@ -45,7 +45,7 @@ func TestWriteConfig(t *testing.T) {
data, err := os.ReadFile(configPath) data, err := os.ReadFile(configPath)
require.NoError(t, err) require.NoError(t, err)
var loaded probod.FullConfig var loaded probodconfig.FullConfig
err = yaml.Unmarshal(data, &loaded) err = yaml.Unmarshal(data, &loaded)
require.NoError(t, err) require.NoError(t, err)
@@ -58,8 +58,8 @@ func TestWriteConfig_CreatesDirectory(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
configPath := filepath.Join(tmpDir, "nested", "dir", "probod.yml") configPath := filepath.Join(tmpDir, "nested", "dir", "probod.yml")
cfg := &probod.FullConfig{ cfg := &probodconfig.FullConfig{
Probod: probod.Config{BaseURL: "http://localhost:8080"}, Probod: probodconfig.Config{BaseURL: "http://localhost:8080"},
} }
err := WriteConfig(cfg, configPath) err := WriteConfig(cfg, configPath)
@@ -73,7 +73,7 @@ func TestWriteConfig_FilePermissions(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
configPath := filepath.Join(tmpDir, "probod.yml") configPath := filepath.Join(tmpDir, "probod.yml")
cfg := &probod.FullConfig{} cfg := &probodconfig.FullConfig{}
err := WriteConfig(cfg, configPath) err := WriteConfig(cfg, configPath)
require.NoError(t, err) require.NoError(t, err)
@@ -88,10 +88,10 @@ func TestWriteConfig_CompleteConfig(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
configPath := filepath.Join(tmpDir, "probod.yml") configPath := filepath.Join(tmpDir, "probod.yml")
cfg := &probod.FullConfig{ cfg := &probodconfig.FullConfig{
Unit: probod.UnitConfig{ Unit: probodconfig.UnitConfig{
Metrics: probod.MetricsConfig{Addr: "localhost:8081"}, Metrics: probodconfig.MetricsConfig{Addr: "localhost:8081"},
Tracing: probod.TracingConfig{ Tracing: probodconfig.TracingConfig{
Addr: "localhost:4317", Addr: "localhost:4317",
MaxBatchSize: 512, MaxBatchSize: 512,
BatchTimeout: 5, BatchTimeout: 5,
@@ -99,18 +99,18 @@ func TestWriteConfig_CompleteConfig(t *testing.T) {
MaxQueueSize: 2048, MaxQueueSize: 2048,
}, },
}, },
Probod: probod.Config{ Probod: probodconfig.Config{
BaseURL: "http://localhost:8080", BaseURL: "http://localhost:8080",
EncryptionKey: "test-key", EncryptionKey: "test-key",
ChromeDPAddr: "localhost:9222", ChromeDPAddr: "localhost:9222",
Api: probod.APIConfig{ Api: probodconfig.APIConfig{
Addr: ":8080", Addr: ":8080",
Cors: probod.CorsConfig{ Cors: probodconfig.CorsConfig{
AllowedOrigins: []string{"http://localhost:8080"}, AllowedOrigins: []string{"http://localhost:8080"},
}, },
ExtraHeaderFields: map[string]string{}, ExtraHeaderFields: map[string]string{},
}, },
Pg: probod.PgConfig{ Pg: probodconfig.PgConfig{
Addr: "localhost:5432", Addr: "localhost:5432",
Username: "postgres", Username: "postgres",
Password: "postgres", Password: "postgres",
@@ -120,11 +120,11 @@ func TestWriteConfig_CompleteConfig(t *testing.T) {
MaxConnIdleTimeSeconds: 1800, MaxConnIdleTimeSeconds: 1800,
MaxConnLifetimeSeconds: 3600, MaxConnLifetimeSeconds: 3600,
}, },
Connectors: []probod.ConnectorConfig{ Connectors: []probodconfig.ConnectorConfig{
{ {
Provider: "slack", Provider: "slack",
Protocol: "oauth2", Protocol: "oauth2",
RawConfig: probod.ConnectorConfigOAuth2{ RawConfig: probodconfig.ConnectorConfigOAuth2{
ClientID: "client-id", ClientID: "client-id",
ClientSecret: "client-secret", ClientSecret: "client-secret",
}, },
@@ -142,7 +142,7 @@ func TestWriteConfig_CompleteConfig(t *testing.T) {
data, err := os.ReadFile(configPath) data, err := os.ReadFile(configPath)
require.NoError(t, err) require.NoError(t, err)
var loaded probod.FullConfig var loaded probodconfig.FullConfig
err = yaml.Unmarshal(data, &loaded) err = yaml.Unmarshal(data, &loaded)
require.NoError(t, err) require.NoError(t, err)

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

@@ -73,71 +73,9 @@ import (
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )
type ( type Implm struct {
Implm struct { cfg Config
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"`
}
)
var ( var (
_ unit.Configurable = (*Implm)(nil) _ unit.Configurable = (*Implm)(nil)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>. // Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
type CorsConfig struct { type CorsConfig struct {
AllowedOrigins []string `json:"allowed-origins"` AllowedOrigins []string `json:"allowed-origins"`

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>. // Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
import ( import (
"encoding/base64" "encoding/base64"

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>. // Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
type AWSConfig struct { type AWSConfig struct {
Region string `json:"region"` Region string `json:"region"`

View File

@@ -0,0 +1,77 @@
// 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 probodconfig
type (
// 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"`
}
)

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>. // Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
import ( import (
"bytes" "bytes"

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>. // Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
type CustomDomainsConfig struct { type CustomDomainsConfig struct {
RenewalInterval int `json:"renewal-interval"` RenewalInterval int `json:"renewal-interval"`

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>. // Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
type ( type (
// LLMProviderConfig holds authentication and connection settings for an // LLMProviderConfig holds authentication and connection settings for an

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>. // Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
type MailerConfig struct { type MailerConfig struct {
MailerInterval int `json:"mailer-interval"` MailerInterval int `json:"mailer-interval"`

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>. // Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
type NotificationsConfig struct { type NotificationsConfig struct {
Mailer MailerConfig `json:"mailer"` Mailer MailerConfig `json:"mailer"`

View File

@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
type OIDCProviderConfig struct { type OIDCProviderConfig struct {
ClientID string `json:"client-id"` ClientID string `json:"client-id"`

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>. // Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
import ( import (
"crypto/x509" "crypto/x509"

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>. // Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
import ( import (
"time" "time"

View File

@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
type SCIMBridgeConfig struct { type SCIMBridgeConfig struct {
SyncInterval int `json:"sync-interval"` SyncInterval int `json:"sync-interval"`

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>. // Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
package probod package probodconfig
type SlackConfig struct { type SlackConfig struct {
SenderInterval int `json:"sender-interval"` SenderInterval int `json:"sender-interval"`