chore: checkpoint 第一版
ci / verify (push) Canceled after 0s

This commit is contained in:
Codex Local
2026-09-06 17:04:11 +08:00
parent a8cdec98d1
commit 0c2151ace9
659 changed files with 185855 additions and 554 deletions
+241 -175
View File
@@ -23,101 +23,119 @@ const (
)
type Config struct {
ServiceName string
Environment string
LogLevel string
HTTPAddr string
DatabaseURL string
RedisAddr string
RedisPassword string
RedisDB int
AuthIssuerURL string
AuthJWKSURL string
AuthAudience string
OTLPEndpoint string
RateLimitRPS float64
RateLimitBurst int
RateLimitUserRPS float64
RateLimitUserBurst int
RateLimitTenantRPS float64
RateLimitTenantBurst int
RateLimitDeviceRPS float64
RateLimitDeviceBurst int
ProviderStartRPS float64
ProviderStartBurst int
ProviderMaxActiveTasks int
DeviceLocalSecret string
DeviceCredentialMasterKey string
ContentModelMasterKey string
DeviceClockSkew time.Duration
RTCAppID string
RTCAppKey string
RTCTokenIssuer string
RTCTokenSecret string
CursorSigningSecret string
ShareTokenSecret string
RTCTokenTTL time.Duration
AllocationTTL time.Duration
HeartbeatInterval int
ProviderCallbackSecret string
ProviderCallbackSkew time.Duration
PlatformHealthSecret string
PlatformHealthSkew time.Duration
MockProviderBaseURL string
MockProviderAPIKey string
VoiceProvider string
VolcRTCBaseURL string
VolcAccessKeyID string
VolcSecretAccessKey string
VolcSessionToken string
VolcRTCRegion string
VolcRTCAPIVersion string
VolcVoiceChatTemplate string
ProviderRequestTimeout time.Duration
ProviderFailureThreshold int
ProviderCircuitCooldown time.Duration
DependencyTimeout time.Duration
ExternalProbeInterval time.Duration
ShutdownTimeout time.Duration
WorkerPollInterval time.Duration
RecoveryScanInterval time.Duration
RecoveryStartingAfter time.Duration
RecoveryStoppingAfter time.Duration
ObjectStoreEndpoint string
ObjectStorePublic string
ObjectStoreAccessKey string
ObjectStoreSecretKey string
ObjectStoreBucket string
ObjectStoreRegion string
ObjectStoreSecure bool
ObjectStorePublicSecure bool
ExportDownloadTTL time.Duration
ExportObjectTTL time.Duration
MediaLocalDeleteGrace time.Duration
AlertWebhookURL string
AlertWebhookSecret string
AlertWebhookTimeout time.Duration
ContentGenerator string
ArkBaseURL string
ArkAPIKey string
ArkContentModel string
ArkRequestTimeout time.Duration
ContentSafetyProvider string
ContentSafetyEndpoint string
ContentSafetyAPIKey string
ContentSafetyPolicyRef string
ContentSafetyTimeout time.Duration
EmbeddingProvider string
ArkEmbeddingModel string
MemoryToolBaseURL string
MemoryToolSigningSecret string
MemoryToolTokenTTL time.Duration
MemoryToolRateRPS float64
MemoryToolRateBurst int
ProviderMemoryMode string
ProviderMemoryBaseURL string
ProviderMemoryAPIKey string
ProviderMemoryTimeout time.Duration
VikingResourceID string
VikingAPIKey string
VikingEventType string
VikingProfileType string
ServiceName string
Environment string
LogLevel string
HTTPAddr string
DatabaseURL string
RedisAddr string
RedisPassword string
RedisDB int
AuthIssuerURL string
AuthJWKSURL string
AuthAudience string
OTLPEndpoint string
RateLimitRPS float64
RateLimitBurst int
RateLimitUserRPS float64
RateLimitUserBurst int
RateLimitTenantRPS float64
RateLimitTenantBurst int
RateLimitDeviceRPS float64
RateLimitDeviceBurst int
ProviderStartRPS float64
ProviderStartBurst int
ProviderMaxActiveTasks int
DeviceLocalSecret string
DeviceCredentialMasterKey string
ContentModelMasterKey string
DeviceClockSkew time.Duration
RTCAppID string
RTCAppKey string
RTCTokenIssuer string
RTCTokenSecret string
CursorSigningSecret string
ShareTokenSecret string
RTCTokenTTL time.Duration
AllocationTTL time.Duration
HeartbeatInterval int
ProviderCallbackSecret string
SubtitleCallbackURL string
SubtitleCallbackSecret string
SubtitlePrimary bool
ProviderCallbackSkew time.Duration
PlatformHealthSecret string
PlatformHealthSkew time.Duration
MockProviderBaseURL string
MockProviderAPIKey string
VoiceProvider string
VolcRTCBaseURL string
VolcAccessKeyID string
VolcSecretAccessKey string
VolcSessionToken string
VolcRTCRegion string
VolcRTCAPIVersion string
VolcVoiceChatTemplate string
VolcHardwareAgentBotID string
VolcHardwareTransport string
VolcHardwareMinimumSDKVersion string
VolcHardwareProvisioningEnabled bool
VolcHardwareInstanceID string
VolcHardwareProductKey string
VolcHardwareProductSecret string
VolcHardwareDeviceCredentialMasterKey string
VolcHardwareRegisterURL string
VolcHardwareRegisterTimeout time.Duration
VolcHardwareDeviceNamePrefix string
ProviderRequestTimeout time.Duration
ProviderFailureThreshold int
ProviderCircuitCooldown time.Duration
DependencyTimeout time.Duration
ExternalProbeInterval time.Duration
ShutdownTimeout time.Duration
WorkerPollInterval time.Duration
RecoveryScanInterval time.Duration
RecoveryStartingAfter time.Duration
RecoveryStoppingAfter time.Duration
ObjectStoreEndpoint string
ObjectStorePublic string
ObjectStoreAccessKey string
ObjectStoreSecretKey string
ObjectStoreBucket string
ObjectStoreRegion string
ObjectStoreSecure bool
ObjectStorePublicSecure bool
ExportDownloadTTL time.Duration
ExportObjectTTL time.Duration
MediaLocalDeleteGrace time.Duration
AlertWebhookURL string
AlertWebhookSecret string
AlertWebhookTimeout time.Duration
ContentGenerator string
ArkBaseURL string
ArkAPIKey string
ArkContentModel string
ArkRequestTimeout time.Duration
ContentSafetyProvider string
ContentSafetyEndpoint string
ContentSafetyAPIKey string
ContentSafetyPolicyRef string
ContentSafetyTimeout time.Duration
EmbeddingProvider string
ArkEmbeddingModel string
MemoryToolBaseURL string
MemoryToolSigningSecret string
MemoryToolTokenTTL time.Duration
MemoryToolRateRPS float64
MemoryToolRateBurst int
ProviderMemoryMode string
ProviderMemoryBaseURL string
ProviderMemoryAPIKey string
ProviderMemoryTimeout time.Duration
}
func Load(serviceName string) (Config, error) {
@@ -217,6 +235,14 @@ func Load(serviceName string) (Config, error) {
if err != nil {
return Config{}, err
}
volcHardwareProvisioningEnabled, err := boolEnv("VOLC_HARDWARE_PROVISIONING_ENABLED", false)
if err != nil {
return Config{}, err
}
volcHardwareRegisterTimeout, err := durationEnv("VOLC_HARDWARE_REGISTER_TIMEOUT", 10*time.Second)
if err != nil {
return Config{}, err
}
objectStoreSecure, err := boolEnv("OBJECT_STORE_SECURE", false)
if err != nil {
return Config{}, err
@@ -229,7 +255,9 @@ func Load(serviceName string) (Config, error) {
secretValues, err := loadSecretValues(
"DATABASE_URL", "REDIS_PASSWORD", "DEVICE_LOCAL_SECRET", "DEVICE_CREDENTIAL_MASTER_KEY", "MODEL_CREDENTIAL_MASTER_KEY", "RTC_APP_KEY", "RTC_TOKEN_SIGNING_SECRET",
"CURSOR_SIGNING_SECRET", "SHARE_TOKEN_SIGNING_SECRET", "PROVIDER_CALLBACK_SECRET", "PLATFORM_HEALTH_CALLBACK_SECRET",
"VOLC_SUBTITLE_CALLBACK_SECRET", "VIKING_MEMORY_API_KEY",
"MOCK_PROVIDER_API_KEY", "VOLC_ACCESS_KEY_ID", "VOLC_SECRET_ACCESS_KEY", "VOLC_SESSION_TOKEN",
"VOLC_HARDWARE_PRODUCT_SECRET", "VOLC_HARDWARE_DEVICE_CREDENTIAL_MASTER_KEY",
"OBJECT_STORE_ACCESS_KEY", "OBJECT_STORE_SECRET_KEY", "ALERT_WEBHOOK_SECRET", "ARK_API_KEY", "CONTENT_SAFETY_API_KEY", "MEMORY_TOOL_SIGNING_SECRET", "PROVIDER_MEMORY_API_KEY",
)
if err != nil {
@@ -295,86 +323,104 @@ func Load(serviceName string) (Config, error) {
}
cfg := Config{
ServiceName: serviceName,
Environment: environment,
LogLevel: stringEnv("LOG_LEVEL", "info"),
HTTPAddr: stringEnv("HTTP_ADDR", defaultHTTPAddr(serviceName)),
DatabaseURL: secretDefault(secretValues["DATABASE_URL"], "postgres://voice:voice_dev_only@localhost:55432/voice_platform?sslmode=disable"),
RedisAddr: stringEnv("REDIS_ADDR", "localhost:56379"),
RedisPassword: secretValues["REDIS_PASSWORD"],
RedisDB: redisDB,
AuthIssuerURL: stringEnv("AUTH_ISSUER_URL", "http://localhost:58180/realms/voice-local"),
AuthJWKSURL: stringEnv("AUTH_JWKS_URL", "http://localhost:58180/realms/voice-local/protocol/openid-connect/certs"),
AuthAudience: stringEnv("AUTH_AUDIENCE", "voice-platform-web"),
OTLPEndpoint: stringEnvAllowEmpty("OTEL_EXPORTER_OTLP_ENDPOINT", "localhost:54317"),
DependencyTimeout: dependencyTimeout,
ExternalProbeInterval: externalProbeInterval,
ShutdownTimeout: shutdownTimeout,
WorkerPollInterval: pollInterval,
RecoveryScanInterval: recoveryScanInterval,
RecoveryStartingAfter: recoveryStartingAfter,
RecoveryStoppingAfter: recoveryStoppingAfter,
DeviceLocalSecret: deviceLocalSecret,
DeviceCredentialMasterKey: deviceCredentialMasterKey,
ContentModelMasterKey: contentModelMasterKey,
DeviceClockSkew: deviceClockSkew,
RTCAppID: stringEnv("RTC_APP_ID", "local-public-rtc-app"),
RTCAppKey: secretValues["RTC_APP_KEY"],
RTCTokenIssuer: stringEnv("RTC_TOKEN_ISSUER", "local"),
RTCTokenSecret: rtcTokenSecret,
CursorSigningSecret: cursorSigningSecret,
ShareTokenSecret: shareTokenSecret,
RTCTokenTTL: rtcTokenTTL,
AllocationTTL: allocationTTL,
ProviderCallbackSecret: providerCallbackSecret,
ProviderCallbackSkew: providerCallbackSkew,
PlatformHealthSecret: secretValues["PLATFORM_HEALTH_CALLBACK_SECRET"],
PlatformHealthSkew: platformHealthSkew,
MockProviderBaseURL: stringEnv("MOCK_PROVIDER_BASE_URL", "http://localhost:59200"),
MockProviderAPIKey: secretDefault(secretValues["MOCK_PROVIDER_API_KEY"], "local-mock-provider-key"),
VoiceProvider: stringEnv("VOICE_PROVIDER", "mock"),
VolcRTCBaseURL: stringEnv("VOLC_RTC_BASE_URL", "https://rtc.volcengineapi.com"),
VolcAccessKeyID: secretValues["VOLC_ACCESS_KEY_ID"],
VolcSecretAccessKey: secretValues["VOLC_SECRET_ACCESS_KEY"],
VolcSessionToken: secretValues["VOLC_SESSION_TOKEN"],
VolcRTCRegion: stringEnv("VOLC_RTC_REGION", "cn-north-1"),
VolcRTCAPIVersion: stringEnv("VOLC_RTC_API_VERSION", "2024-12-01"),
VolcVoiceChatTemplate: strings.TrimSpace(os.Getenv("VOLC_VOICE_CHAT_TEMPLATE_FILE")),
ProviderRequestTimeout: providerRequestTimeout,
ProviderCircuitCooldown: providerCircuitCooldown,
ObjectStoreEndpoint: objectStoreEndpoint,
ObjectStorePublic: objectStorePublic,
ObjectStoreAccessKey: objectStoreAccessKey,
ObjectStoreSecretKey: objectStoreSecretKey,
ObjectStoreBucket: objectStoreBucket,
ObjectStoreRegion: objectStoreRegion,
ObjectStoreSecure: objectStoreSecure,
ObjectStorePublicSecure: objectStorePublicSecure,
ExportDownloadTTL: exportDownloadTTL,
ExportObjectTTL: exportObjectTTL,
MediaLocalDeleteGrace: mediaLocalDeleteGrace,
AlertWebhookURL: strings.TrimSpace(os.Getenv("ALERT_WEBHOOK_URL")),
AlertWebhookSecret: secretValues["ALERT_WEBHOOK_SECRET"],
AlertWebhookTimeout: alertWebhookTimeout,
ContentGenerator: stringEnv("CONTENT_GENERATOR", "local"),
ArkBaseURL: stringEnv("ARK_BASE_URL", "https://ark.cn-beijing.volces.com/api/v3"),
ArkAPIKey: secretValues["ARK_API_KEY"],
ArkContentModel: strings.TrimSpace(os.Getenv("ARK_CONTENT_MODEL")),
ArkRequestTimeout: arkRequestTimeout,
ContentSafetyProvider: stringEnv("CONTENT_SAFETY_PROVIDER", "local"),
ContentSafetyEndpoint: strings.TrimSpace(os.Getenv("CONTENT_SAFETY_ENDPOINT")),
ContentSafetyAPIKey: secretValues["CONTENT_SAFETY_API_KEY"],
ContentSafetyPolicyRef: strings.TrimSpace(os.Getenv("CONTENT_SAFETY_POLICY_REF")),
ContentSafetyTimeout: contentSafetyTimeout,
EmbeddingProvider: stringEnv("EMBEDDING_PROVIDER", "local"),
ArkEmbeddingModel: strings.TrimSpace(os.Getenv("ARK_EMBEDDING_MODEL")),
MemoryToolBaseURL: strings.TrimSpace(os.Getenv("MEMORY_TOOL_BASE_URL")),
MemoryToolSigningSecret: memoryToolSigningSecret,
MemoryToolTokenTTL: memoryToolTokenTTL,
ProviderMemoryMode: stringEnv("PROVIDER_MEMORY_MODE", "disabled"),
ProviderMemoryBaseURL: strings.TrimSpace(os.Getenv("PROVIDER_MEMORY_BASE_URL")),
ProviderMemoryAPIKey: secretValues["PROVIDER_MEMORY_API_KEY"],
ProviderMemoryTimeout: providerMemoryTimeout,
ServiceName: serviceName,
Environment: environment,
LogLevel: stringEnv("LOG_LEVEL", "info"),
HTTPAddr: stringEnv("HTTP_ADDR", defaultHTTPAddr(serviceName)),
DatabaseURL: secretDefault(secretValues["DATABASE_URL"], "postgres://voice:voice_dev_only@localhost:55432/voice_platform?sslmode=disable"),
RedisAddr: stringEnv("REDIS_ADDR", "localhost:56379"),
RedisPassword: secretValues["REDIS_PASSWORD"],
RedisDB: redisDB,
AuthIssuerURL: stringEnv("AUTH_ISSUER_URL", "http://localhost:58180/realms/voice-local"),
AuthJWKSURL: stringEnv("AUTH_JWKS_URL", "http://localhost:58180/realms/voice-local/protocol/openid-connect/certs"),
AuthAudience: stringEnv("AUTH_AUDIENCE", "voice-platform-web"),
OTLPEndpoint: stringEnvAllowEmpty("OTEL_EXPORTER_OTLP_ENDPOINT", "localhost:54317"),
DependencyTimeout: dependencyTimeout,
ExternalProbeInterval: externalProbeInterval,
ShutdownTimeout: shutdownTimeout,
WorkerPollInterval: pollInterval,
RecoveryScanInterval: recoveryScanInterval,
RecoveryStartingAfter: recoveryStartingAfter,
RecoveryStoppingAfter: recoveryStoppingAfter,
DeviceLocalSecret: deviceLocalSecret,
DeviceCredentialMasterKey: deviceCredentialMasterKey,
ContentModelMasterKey: contentModelMasterKey,
DeviceClockSkew: deviceClockSkew,
RTCAppID: stringEnv("RTC_APP_ID", "local-public-rtc-app"),
RTCAppKey: secretValues["RTC_APP_KEY"],
RTCTokenIssuer: stringEnv("RTC_TOKEN_ISSUER", "local"),
RTCTokenSecret: rtcTokenSecret,
CursorSigningSecret: cursorSigningSecret,
ShareTokenSecret: shareTokenSecret,
RTCTokenTTL: rtcTokenTTL,
AllocationTTL: allocationTTL,
ProviderCallbackSecret: providerCallbackSecret,
SubtitleCallbackURL: strings.TrimSpace(os.Getenv("VOLC_SUBTITLE_CALLBACK_URL")),
SubtitleCallbackSecret: secretValues["VOLC_SUBTITLE_CALLBACK_SECRET"],
SubtitlePrimary: os.Getenv("VOLC_SUBTITLE_PRIMARY") == "true",
ProviderCallbackSkew: providerCallbackSkew,
PlatformHealthSecret: secretValues["PLATFORM_HEALTH_CALLBACK_SECRET"],
PlatformHealthSkew: platformHealthSkew,
MockProviderBaseURL: stringEnv("MOCK_PROVIDER_BASE_URL", "http://localhost:59200"),
MockProviderAPIKey: secretDefault(secretValues["MOCK_PROVIDER_API_KEY"], "local-mock-provider-key"),
VoiceProvider: stringEnv("VOICE_PROVIDER", "mock"),
VolcRTCBaseURL: stringEnv("VOLC_RTC_BASE_URL", "https://rtc.volcengineapi.com"),
VolcAccessKeyID: secretValues["VOLC_ACCESS_KEY_ID"],
VolcSecretAccessKey: secretValues["VOLC_SECRET_ACCESS_KEY"],
VolcSessionToken: secretValues["VOLC_SESSION_TOKEN"],
VolcRTCRegion: stringEnv("VOLC_RTC_REGION", "cn-north-1"),
VolcRTCAPIVersion: stringEnv("VOLC_RTC_API_VERSION", "2024-12-01"),
VolcVoiceChatTemplate: strings.TrimSpace(os.Getenv("VOLC_VOICE_CHAT_TEMPLATE_FILE")),
VolcHardwareAgentBotID: strings.TrimSpace(os.Getenv("VOLC_HARDWARE_AGENT_BOT_ID")),
VolcHardwareTransport: stringEnv("VOLC_HARDWARE_AGENT_TRANSPORT", "high_quality"),
VolcHardwareMinimumSDKVersion: stringEnv("VOLC_HARDWARE_AGENT_MINIMUM_SDK_VERSION", "1.0.0"),
VolcHardwareProvisioningEnabled: volcHardwareProvisioningEnabled,
VolcHardwareInstanceID: strings.TrimSpace(os.Getenv("VOLC_HARDWARE_INSTANCE_ID")),
VolcHardwareProductKey: strings.TrimSpace(os.Getenv("VOLC_HARDWARE_PRODUCT_KEY")),
VolcHardwareProductSecret: secretValues["VOLC_HARDWARE_PRODUCT_SECRET"],
VolcHardwareDeviceCredentialMasterKey: secretValues["VOLC_HARDWARE_DEVICE_CREDENTIAL_MASTER_KEY"],
VolcHardwareRegisterURL: stringEnv("VOLC_HARDWARE_REGISTER_URL", "https://iot-cn-shanghai.iot.volces.com/2021-12-14/DynamicRegister?Action=DynamicRegister&Version=2021-12-14"),
VolcHardwareRegisterTimeout: volcHardwareRegisterTimeout,
VolcHardwareDeviceNamePrefix: stringEnv("VOLC_HARDWARE_DEVICE_NAME_PREFIX", "dt-"),
ProviderRequestTimeout: providerRequestTimeout,
ProviderCircuitCooldown: providerCircuitCooldown,
ObjectStoreEndpoint: objectStoreEndpoint,
ObjectStorePublic: objectStorePublic,
ObjectStoreAccessKey: objectStoreAccessKey,
ObjectStoreSecretKey: objectStoreSecretKey,
ObjectStoreBucket: objectStoreBucket,
ObjectStoreRegion: objectStoreRegion,
ObjectStoreSecure: objectStoreSecure,
ObjectStorePublicSecure: objectStorePublicSecure,
ExportDownloadTTL: exportDownloadTTL,
ExportObjectTTL: exportObjectTTL,
MediaLocalDeleteGrace: mediaLocalDeleteGrace,
AlertWebhookURL: strings.TrimSpace(os.Getenv("ALERT_WEBHOOK_URL")),
AlertWebhookSecret: secretValues["ALERT_WEBHOOK_SECRET"],
AlertWebhookTimeout: alertWebhookTimeout,
ContentGenerator: stringEnv("CONTENT_GENERATOR", "local"),
ArkBaseURL: stringEnv("ARK_BASE_URL", "https://ark.cn-beijing.volces.com/api/v3"),
ArkAPIKey: secretValues["ARK_API_KEY"],
ArkContentModel: strings.TrimSpace(os.Getenv("ARK_CONTENT_MODEL")),
ArkRequestTimeout: arkRequestTimeout,
ContentSafetyProvider: stringEnv("CONTENT_SAFETY_PROVIDER", "local"),
ContentSafetyEndpoint: strings.TrimSpace(os.Getenv("CONTENT_SAFETY_ENDPOINT")),
ContentSafetyAPIKey: secretValues["CONTENT_SAFETY_API_KEY"],
ContentSafetyPolicyRef: strings.TrimSpace(os.Getenv("CONTENT_SAFETY_POLICY_REF")),
ContentSafetyTimeout: contentSafetyTimeout,
EmbeddingProvider: stringEnv("EMBEDDING_PROVIDER", "local"),
ArkEmbeddingModel: strings.TrimSpace(os.Getenv("ARK_EMBEDDING_MODEL")),
MemoryToolBaseURL: strings.TrimSpace(os.Getenv("MEMORY_TOOL_BASE_URL")),
MemoryToolSigningSecret: memoryToolSigningSecret,
MemoryToolTokenTTL: memoryToolTokenTTL,
VikingResourceID: strings.TrimSpace(os.Getenv("VIKING_MEMORY_RESOURCE_ID")),
VikingAPIKey: secretValues["VIKING_MEMORY_API_KEY"],
VikingEventType: stringEnv("VIKING_MEMORY_EVENT_TYPE", "event_v1"),
VikingProfileType: stringEnv("VIKING_MEMORY_PROFILE_TYPE", "profile_v1"),
ProviderMemoryMode: stringEnv("PROVIDER_MEMORY_MODE", "disabled"),
ProviderMemoryBaseURL: strings.TrimSpace(os.Getenv("PROVIDER_MEMORY_BASE_URL")),
ProviderMemoryAPIKey: secretValues["PROVIDER_MEMORY_API_KEY"],
ProviderMemoryTimeout: providerMemoryTimeout,
}
cfg.RateLimitRPS, err = floatEnv("RATE_LIMIT_RPS", 50)
if err != nil {
@@ -444,6 +490,12 @@ func Load(serviceName string) (Config, error) {
}
func (c Config) Validate() error {
if c.SubtitleCallbackURL != "" || c.SubtitleCallbackSecret != "" || c.SubtitlePrimary {
u, err := url.Parse(c.SubtitleCallbackURL)
if err != nil || u.Scheme != "https" || u.Host == "" || u.RawQuery != "" || u.Fragment != "" || u.User != nil || len(c.SubtitleCallbackSecret) < 32 {
return errors.New("native subtitle callback requires an HTTPS URL without query and a dedicated secret of at least 32 bytes")
}
}
validEnvironment := map[string]bool{
EnvironmentLocal: true,
EnvironmentTest: true,
@@ -550,6 +602,20 @@ func (c Config) Validate() error {
if c.ProviderCallbackSkew <= 0 || c.PlatformHealthSkew <= 0 || c.ProviderRequestTimeout <= 0 || c.ProviderFailureThreshold < 1 || c.ProviderCircuitCooldown <= 0 {
return errors.New("provider callback skew and request timeout must be positive")
}
if c.VolcHardwareTransport != "high_quality" && c.VolcHardwareTransport != "low_load" {
return errors.New("VOLC_HARDWARE_AGENT_TRANSPORT must be high_quality or low_load")
}
if c.ServiceName == "api" && c.VolcHardwareProvisioningEnabled {
providerKey, err := hex.DecodeString(c.VolcHardwareDeviceCredentialMasterKey)
if err != nil || len(providerKey) != 32 {
return errors.New("VOLC_HARDWARE_DEVICE_CREDENTIAL_MASTER_KEY must be 32 bytes encoded as 64 hexadecimal characters")
}
if c.VolcHardwareInstanceID == "" || c.VolcHardwareProductKey == "" || c.VolcHardwareAgentBotID == "" ||
c.VolcHardwareMinimumSDKVersion == "" || len(c.VolcHardwareMinimumSDKVersion) > 80 ||
len(c.VolcHardwareProductSecret) < 16 || c.VolcHardwareRegisterTimeout <= 0 {
return errors.New("enabled hardware provisioning requires instance ID, product key, default Bot ID, minimum SDK, product secret and positive registration timeout")
}
}
if c.AlertWebhookTimeout <= 0 {
return errors.New("ALERT_WEBHOOK_TIMEOUT must be positive")
}
+39
View File
@@ -260,3 +260,42 @@ func TestWorkerManagedContentSafetyConfiguration(t *testing.T) {
t.Fatalf("Validate() rejected complete non-production managed content safety config: %v", err)
}
}
func TestHardwareProvisioningLoadsProductSecretFromFile(t *testing.T) {
t.Setenv("APP_ENV", "test")
t.Setenv("VOLC_HARDWARE_PROVISIONING_ENABLED", "true")
t.Setenv("VOLC_HARDWARE_INSTANCE_ID", "instance-1")
t.Setenv("VOLC_HARDWARE_PRODUCT_KEY", "product-1")
t.Setenv("VOLC_HARDWARE_AGENT_BOT_ID", "bot-test")
t.Setenv("VOLC_HARDWARE_PRODUCT_SECRET", "")
secretPath := filepath.Join(t.TempDir(), "product-secret")
if err := os.WriteFile(secretPath, []byte("product-secret-at-least-16-bytes\n"), 0o600); err != nil {
t.Fatal(err)
}
t.Setenv("VOLC_HARDWARE_PRODUCT_SECRET_FILE", secretPath)
t.Setenv("VOLC_HARDWARE_DEVICE_CREDENTIAL_MASTER_KEY", strings.Repeat("ab", 32))
cfg, err := Load("api")
if err != nil {
t.Fatalf("Load() error = %v", err)
}
if cfg.VolcHardwareProductSecret != "product-secret-at-least-16-bytes" || !cfg.VolcHardwareProvisioningEnabled {
t.Fatalf("hardware provisioning secret/config was not loaded")
}
}
func TestHardwareProvisioningRejectsMissingProductSecret(t *testing.T) {
cfg, err := Load("api")
if err != nil {
t.Fatal(err)
}
cfg.VolcHardwareProvisioningEnabled = true
cfg.VolcHardwareInstanceID = "instance-1"
cfg.VolcHardwareProductKey = "product-1"
cfg.VolcHardwareAgentBotID = "bot-test"
cfg.VolcHardwareProductSecret = ""
cfg.VolcHardwareDeviceCredentialMasterKey = strings.Repeat("ab", 32)
if err = cfg.Validate(); err == nil || !strings.Contains(err.Error(), "hardware provisioning") {
t.Fatalf("Validate() error = %v, want missing product secret rejection", err)
}
}