{"record":{"id":"d55ed79c004220f6","repo":"iflytek/astron-agent","slug":"tenant-key-and-tenant-secret-must-be-distinct-values","errorCode":null,"errorMessage":"TENANT_KEY and TENANT_SECRET must be distinct values","messagePattern":"TENANT_KEY and TENANT_SECRET must be distinct values","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tenant/config/bootstrap_credentials.go","lineNumber":76,"sourceCode":"}\n\n// Validate enforces the storage and HTTP-header constraints shared by every\n// bootstrap credential consumer.\nfunc (credentials TenantBootstrapCredentials) Validate() error {\n\tif credentials.TenantID != BootstrapTenantID {\n\t\treturn fmt.Errorf(\n\t\t\t\"TENANT_ID must remain %s because persisted bootstrap data refers to it\",\n\t\t\tBootstrapTenantID,\n\t\t)\n\t}\n\tif err := validateCredential(\"TENANT_KEY\", credentials.APIKey); err != nil {\n\t\treturn err\n\t}\n\tif err := validateCredential(\"TENANT_SECRET\", credentials.Secret); err != nil {\n\t\treturn err\n\t}\n\tif credentials.APIKey == credentials.Secret {\n\t\treturn errors.New(\"TENANT_KEY and TENANT_SECRET must be distinct values\")\n\t}\n\tif credentials.APIKey == LegacyTenantKey || credentials.Secret == LegacyTenantSecret {\n\t\treturn errors.New(\"published legacy tenant credentials cannot be used\")\n\t}\n\treturn nil\n}\n\nfunc credentialFromEnvironmentOrFile(valueEnvironment, fileEnvironment string) (string, error) {\n\tif value := strings.TrimSpace(os.Getenv(valueEnvironment)); value != \"\" {\n\t\tif err := validateCredential(valueEnvironment, value); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn value, nil\n\t}\n\n\tfileName := strings.TrimSpace(os.Getenv(fileEnvironment))\n\tif fileName == \"\" {\n\t\treturn \"\", fmt.Errorf(\"%s or %s is required\", valueEnvironment, fileEnvironment)","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/tenant/config/bootstrap_credentials.go#L58-L94","documentation":"Validate() in the tenant bootstrap credential loader rejects configurations where TENANT_KEY and TENANT_SECRET hold the identical string. These must be two distinct values (an identifier and a secret); reusing one value for both defeats the credential scheme and indicates a misconfiguration.","triggerScenarios":"LoadTenantBootstrapCredentials / reconcileTenantBootstrap / parseMysqlConfig call Validate, and credentials.APIKey == credentials.Secret after loading from env vars (TENANT_KEY, TENANT_SECRET) or credential files.","commonSituations":"Operator set both env vars to the same generated password, a secrets template rendered the same value into both files, or a copy-paste during manual secret creation in a deployment manifest.","solutions":["Generate and assign two distinct values for TENANT_KEY and TENANT_SECRET","Check the Kubernetes Secret / env template that rendered both fields and fix the duplicate value","Redeploy/restart the tenant service so the corrected credentials are reloaded and validated"],"exampleFix":"# before\nTENANT_KEY=s3cr3tvalue\nTENANT_SECRET=s3cr3tvalue\n# after\nTENANT_KEY=tenant-admin-key-9f2a\nTENANT_SECRET=s3cr3tvalue-7d41","handlingStrategy":"validation","validationCode":"key := os.Getenv(\"TENANT_KEY\")\nsecret := os.Getenv(\"TENANT_SECRET\")\nif key == \"\" || secret == \"\" {\n    return errors.New(\"TENANT_KEY and TENANT_SECRET must both be set\")\n}\nif key == secret {\n    return errors.New(\"TENANT_KEY and TENANT_SECRET must be distinct\")\n}","typeGuard":null,"tryCatchPattern":"creds, err := config.LoadTenantBootstrapCredentials(ctx)\nif err != nil {\n    if strings.Contains(err.Error(), \"must be distinct\") {\n        logger.Fatal(\"fix deployment secret: TENANT_KEY equals TENANT_SECRET\")\n    }\n    return err\n}","preventionTips":["Generate TENANT_KEY and TENANT_SECRET independently with separate random calls","Review rendered manifests/secrets before applying","Add pre-deploy lint that compares the two values"],"tags":["config","credentials","validation","tenant"],"backgroundTag":"invalid-config-value","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}