feat: establish v0.70 platform milestone
ci / verify (push) Canceled after 0s

This commit is contained in:
Codex Local
2026-08-29 21:56:51 +08:00
parent d97bbf7cf5
commit e652516147
133 changed files with 12907 additions and 801 deletions
+233 -167
View File
@@ -2,6 +2,7 @@ package config
import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"io"
@@ -22,91 +23,100 @@ 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
DeviceSecretDirectory 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
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
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
}
func Load(serviceName string) (Config, error) {
@@ -198,6 +208,14 @@ func Load(serviceName string) (Config, error) {
if err != nil {
return Config{}, err
}
providerMemoryTimeout, err := durationEnv("PROVIDER_MEMORY_TIMEOUT", 5*time.Second)
if err != nil {
return Config{}, err
}
memoryToolTokenTTL, err := durationEnv("MEMORY_TOOL_TOKEN_TTL", 4*time.Hour)
if err != nil {
return Config{}, err
}
objectStoreSecure, err := boolEnv("OBJECT_STORE_SECURE", false)
if err != nil {
return Config{}, err
@@ -208,15 +226,16 @@ func Load(serviceName string) (Config, error) {
}
environment := stringEnv("APP_ENV", EnvironmentLocal)
secretValues, err := loadSecretValues(
"DATABASE_URL", "REDIS_PASSWORD", "DEVICE_LOCAL_SECRET", "RTC_APP_KEY", "RTC_TOKEN_SIGNING_SECRET",
"DATABASE_URL", "REDIS_PASSWORD", "DEVICE_LOCAL_SECRET", "DEVICE_CREDENTIAL_MASTER_KEY", "RTC_APP_KEY", "RTC_TOKEN_SIGNING_SECRET",
"CURSOR_SIGNING_SECRET", "SHARE_TOKEN_SIGNING_SECRET", "PROVIDER_CALLBACK_SECRET", "PLATFORM_HEALTH_CALLBACK_SECRET",
"MOCK_PROVIDER_API_KEY", "VOLC_ACCESS_KEY_ID", "VOLC_SECRET_ACCESS_KEY", "VOLC_SESSION_TOKEN",
"OBJECT_STORE_ACCESS_KEY", "OBJECT_STORE_SECRET_KEY", "ALERT_WEBHOOK_SECRET", "ARK_API_KEY", "CONTENT_SAFETY_API_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 {
return Config{}, err
}
deviceLocalSecret := secretValues["DEVICE_LOCAL_SECRET"]
deviceCredentialMasterKey := secretValues["DEVICE_CREDENTIAL_MASTER_KEY"]
rtcTokenSecret := secretValues["RTC_TOKEN_SIGNING_SECRET"]
cursorSigningSecret := secretValues["CURSOR_SIGNING_SECRET"]
shareTokenSecret := secretValues["SHARE_TOKEN_SIGNING_SECRET"]
@@ -230,6 +249,9 @@ func Load(serviceName string) (Config, error) {
if deviceLocalSecret == "" && serviceName == "api" && (environment == EnvironmentLocal || environment == EnvironmentTest) {
deviceLocalSecret = "local-simulated-device-secret-32-bytes-minimum"
}
if deviceCredentialMasterKey == "" && serviceName == "api" && (environment == EnvironmentLocal || environment == EnvironmentTest) {
deviceCredentialMasterKey = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}
if rtcTokenSecret == "" && serviceName == "api" && (environment == EnvironmentLocal || environment == EnvironmentTest) {
rtcTokenSecret = "local-simulated-rtc-token-secret-32-bytes-minimum"
}
@@ -239,6 +261,10 @@ func Load(serviceName string) (Config, error) {
if shareTokenSecret == "" && serviceName == "api" && (environment == EnvironmentLocal || environment == EnvironmentTest) {
shareTokenSecret = "local-share-token-signing-secret-32-bytes-minimum"
}
memoryToolSigningSecret := secretValues["MEMORY_TOOL_SIGNING_SECRET"]
if memoryToolSigningSecret == "" && (serviceName == "api" || serviceName == "worker") && (environment == EnvironmentLocal || environment == EnvironmentTest) {
memoryToolSigningSecret = "local-memory-tool-signing-secret-32-bytes-minimum"
}
if providerCallbackSecret == "" && serviceName == "callbacks" && (environment == EnvironmentLocal || environment == EnvironmentTest) {
providerCallbackSecret = "local-provider-callback-secret-32-bytes-minimum"
}
@@ -264,78 +290,85 @@ 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,
DeviceSecretDirectory: strings.TrimSpace(os.Getenv("DEVICE_SECRET_DIRECTORY")),
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")),
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,
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,
}
cfg.RateLimitRPS, err = floatEnv("RATE_LIMIT_RPS", 50)
if err != nil {
@@ -381,6 +414,14 @@ func Load(serviceName string) (Config, error) {
if err != nil {
return Config{}, err
}
cfg.MemoryToolRateRPS, err = floatEnv("MEMORY_TOOL_RATE_RPS", 2)
if err != nil {
return Config{}, err
}
cfg.MemoryToolRateBurst, err = intEnv("MEMORY_TOOL_RATE_BURST", 5)
if err != nil {
return Config{}, err
}
cfg.HeartbeatInterval, err = intEnv("HEARTBEAT_INTERVAL_SECONDS", 15)
if err != nil {
return Config{}, err
@@ -427,14 +468,15 @@ func (c Config) Validate() error {
c.RateLimitUserRPS <= 0 || c.RateLimitUserBurst <= 0 ||
c.RateLimitTenantRPS <= 0 || c.RateLimitTenantBurst <= 0 ||
c.RateLimitDeviceRPS <= 0 || c.RateLimitDeviceBurst <= 0 ||
c.ProviderStartRPS <= 0 || c.ProviderStartBurst <= 0 || c.ProviderMaxActiveTasks <= 0 {
c.ProviderStartRPS <= 0 || c.ProviderStartBurst <= 0 || c.ProviderMaxActiveTasks <= 0 ||
c.MemoryToolRateRPS <= 0 || c.MemoryToolRateBurst <= 0 {
return errors.New("rate limits, bursts and provider task capacity must be positive")
}
if c.ServiceName == "api" && c.DeviceSecretDirectory == "" && len(c.DeviceLocalSecret) < 32 {
return errors.New("DEVICE_LOCAL_SECRET must contain at least 32 characters when DEVICE_SECRET_DIRECTORY is not configured")
}
if c.ServiceName == "api" && c.DeviceSecretDirectory != "" && !filepath.IsAbs(c.DeviceSecretDirectory) {
return errors.New("DEVICE_SECRET_DIRECTORY must be an absolute path")
if c.ServiceName == "api" {
decodedMasterKey, err := hex.DecodeString(c.DeviceCredentialMasterKey)
if err != nil || len(decodedMasterKey) != 32 {
return errors.New("DEVICE_CREDENTIAL_MASTER_KEY must be 32 bytes encoded as 64 hexadecimal characters")
}
}
if c.DeviceClockSkew <= 0 {
return errors.New("DEVICE_CLOCK_SKEW must be positive")
@@ -459,6 +501,18 @@ func (c Config) Validate() error {
if c.ServiceName == "api" && len(c.ShareTokenSecret) < 32 {
return errors.New("SHARE_TOKEN_SIGNING_SECRET must contain at least 32 characters")
}
if (c.ServiceName == "api" || c.ServiceName == "worker") && (len(c.MemoryToolSigningSecret) < 32 || c.MemoryToolTokenTTL <= 0) {
return errors.New("MEMORY_TOOL_SIGNING_SECRET must contain at least 32 characters and token TTL must be positive")
}
if c.MemoryToolBaseURL != "" && !isAbsoluteHTTPURL(c.MemoryToolBaseURL) {
return errors.New("MEMORY_TOOL_BASE_URL must be an absolute HTTP(S) URL")
}
if c.ProviderMemoryMode != "disabled" && c.ProviderMemoryMode != "managed_http" {
return errors.New("PROVIDER_MEMORY_MODE must be disabled or managed_http")
}
if (c.ServiceName == "api" || c.ServiceName == "worker") && c.ProviderMemoryMode == "managed_http" && (!isAbsoluteHTTPURL(c.ProviderMemoryBaseURL) || c.ProviderMemoryAPIKey == "" || c.ProviderMemoryTimeout <= 0) {
return errors.New("managed provider memory requires an HTTP(S) base URL, API key and positive timeout")
}
if c.RTCAppID == "" || c.RTCTokenTTL <= 0 || c.AllocationTTL <= 0 || c.HeartbeatInterval <= 0 {
return errors.New("RTC app, token TTL, allocation TTL and heartbeat interval must be valid")
}
@@ -570,8 +624,8 @@ func (c Config) validateProduction() error {
}
if c.ServiceName == "api" {
if c.DeviceSecretDirectory == "" {
return errors.New("production API must use DEVICE_SECRET_DIRECTORY for per-device credentials")
if c.DeviceCredentialMasterKey == "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" {
return errors.New("production API must use a non-default DEVICE_CREDENTIAL_MASTER_KEY")
}
if isPlaceholderSecret(c.CursorSigningSecret) || isPlaceholderSecret(c.ShareTokenSecret) {
return errors.New("production API signing secrets must not use local or example values")
@@ -579,6 +633,12 @@ func (c Config) validateProduction() error {
if c.CursorSigningSecret == c.ShareTokenSecret {
return errors.New("production API signing secrets must be distinct")
}
if isPlaceholderSecret(c.MemoryToolSigningSecret) || c.MemoryToolSigningSecret == c.CursorSigningSecret || c.MemoryToolSigningSecret == c.ShareTokenSecret {
return errors.New("production memory tool signing secret must be non-placeholder and distinct")
}
if c.MemoryToolBaseURL != "" && !isHTTPSURL(c.MemoryToolBaseURL) {
return errors.New("production memory tool URL must use HTTPS")
}
if isLocalValue(c.RTCAppID) || c.RTCTokenIssuer != "volcengine" || isPlaceholderSecret(c.RTCAppKey) {
return errors.New("production RTC credentials must use a real app ID, Volcengine token issuer and non-placeholder app key")
}
@@ -610,6 +670,12 @@ func (c Config) validateProduction() error {
}
}
if c.ServiceName == "api" || c.ServiceName == "worker" {
if isPlaceholderSecret(c.MemoryToolSigningSecret) {
return errors.New("production memory tool signing secret must be non-placeholder")
}
if c.ProviderMemoryMode == "managed_http" && (!isHTTPSURL(c.ProviderMemoryBaseURL) || isLocalValue(c.ProviderMemoryBaseURL) || isPlaceholderSecret(c.ProviderMemoryAPIKey)) {
return errors.New("production provider memory must use managed HTTPS and a non-placeholder API key")
}
if !c.ObjectStoreSecure || !c.ObjectStorePublicSecure {
return errors.New("production object storage must use TLS")
}
+31 -2
View File
@@ -46,6 +46,32 @@ func TestLoadRejectsInvalidDuration(t *testing.T) {
}
}
func TestLoadValidatesProviderMemoryConfiguration(t *testing.T) {
t.Setenv("PROVIDER_MEMORY_MODE", "managed_http")
t.Setenv("PROVIDER_MEMORY_BASE_URL", "https://memory.example.com")
t.Setenv("PROVIDER_MEMORY_API_KEY", strings.Repeat("p", 40))
cfg, err := Load("worker")
if err != nil {
t.Fatal(err)
}
if cfg.ProviderMemoryMode != "managed_http" || cfg.ProviderMemoryTimeout <= 0 {
t.Fatalf("provider memory config=%+v", cfg)
}
t.Setenv("PROVIDER_MEMORY_BASE_URL", "")
if _, err := Load("worker"); err == nil {
t.Fatal("managed provider memory should require an endpoint")
}
// The mode is distributed through the shared ConfigMap. Services that never
// create a provider-memory client must not require the API/Worker-only key.
t.Setenv("PROVIDER_MEMORY_API_KEY", "")
t.Setenv("PROVIDER_CALLBACK_SECRET", strings.Repeat("c", 32))
t.Setenv("PLATFORM_HEALTH_CALLBACK_SECRET", strings.Repeat("h", 32))
if _, err := Load("callbacks"); err != nil {
t.Fatalf("callbacks should ignore provider-memory credentials: %v", err)
}
}
func TestLoadReadsSecretsFromAbsoluteFiles(t *testing.T) {
secret := strings.Repeat("k", 40)
path := filepath.Join(t.TempDir(), "ark-api-key")
@@ -118,12 +144,14 @@ func TestProductionAPIAcceptsHardenedConfiguration(t *testing.T) {
cfg.AuthIssuerURL = "https://identity.example.com/realms/voice"
cfg.AuthJWKSURL = "https://identity.example.com/realms/voice/certs"
cfg.DeviceLocalSecret = strings.Repeat("d", 40)
cfg.DeviceSecretDirectory = t.TempDir()
cfg.DeviceCredentialMasterKey = strings.Repeat("ab", 32)
cfg.RTCTokenSecret = strings.Repeat("t", 40)
cfg.RTCTokenIssuer = "volcengine"
cfg.RTCAppKey = strings.Repeat("v", 40)
cfg.CursorSigningSecret = strings.Repeat("c", 40)
cfg.ShareTokenSecret = strings.Repeat("h", 40)
cfg.MemoryToolSigningSecret = strings.Repeat("m", 40)
cfg.MemoryToolBaseURL = "https://api.example.com/internal/v1/tools/memory-search"
cfg.RTCAppID = "661e7ae5543cf00000000000"
cfg.ObjectStoreEndpoint = "objects.internal.example.com:9000"
cfg.ObjectStorePublic = "objects.example.com"
@@ -151,7 +179,7 @@ func TestProductionRejectsReusedSigningSecrets(t *testing.T) {
cfg.AuthIssuerURL = "https://identity.example.com/realms/voice"
cfg.AuthJWKSURL = "https://identity.example.com/realms/voice/certs"
cfg.DeviceLocalSecret = strings.Repeat("x", 40)
cfg.DeviceSecretDirectory = t.TempDir()
cfg.DeviceCredentialMasterKey = strings.Repeat("cd", 32)
cfg.RTCTokenSecret = strings.Repeat("x", 40)
cfg.RTCTokenIssuer = "volcengine"
cfg.RTCAppKey = strings.Repeat("v", 40)
@@ -197,6 +225,7 @@ func TestProductionWorkerRequiresRealArkContentGenerator(t *testing.T) {
cfg.ObjectStoreSecretKey = strings.Repeat("s", 40)
cfg.ObjectStoreSecure = true
cfg.ObjectStorePublicSecure = true
cfg.MemoryToolSigningSecret = strings.Repeat("m", 40)
if err = cfg.Validate(); err == nil || !strings.Contains(err.Error(), "content generation") {
t.Fatalf("Validate() error=%v, want local content generator production gate", err)
}