iflytek/astron-agent · critical
published legacy tenant credentials cannot be used
Error message
published legacy tenant credentials cannot be used
What it means
Validate() rejects the hardcoded legacy tenant credentials (LegacyTenantKey / LegacyTenantSecret) that were once published publicly. Using them would be a security hole, so bootstrap fails fast if either TENANT_KEY or TENANT_SECRET equals a known legacy value.
Solutions
- Rotate to newly generated, secret values for TENANT_KEY and TENANT_SECRET
- Search deployment manifests/secrets for the legacy values and replace them everywhere
- Restart the tenant service and confirm bootstrap succeeds with the new credentials
Example fix
# before TENANT_KEY=<published-legacy-key> # after TENANT_KEY=$(openssl rand -hex 24)
Defensive patterns
Strategy: validation
Validate before calling
legacy := []string{config.LegacyTenantKey, config.LegacyTenantSecret}
for i, v := range []string{os.Getenv("TENANT_KEY"), os.Getenv("TENANT_SECRET")} {
for _, l := range legacy {
if v == l {
return fmt.Errorf("credential %d uses a published legacy value; rotate it", i)
}
}
} Try / catch
if _, err := config.LoadTenantBootstrapCredentials(ctx); err != nil {
if strings.Contains(err.Error(), "legacy") {
logger.Fatal("rotate legacy tenant credentials before deploying")
}
return err
} Prevention
- Rotate credentials on a schedule; never reuse example/doc values
- Scan IaC repos for published legacy secrets
- Treat any appearance of legacy values as a security incident
When it happens
Trigger: Validate is invoked by LoadTenantBootstrapCredentials / reconcileTenantBootstrap / parseMysqlConfig and finds credentials.APIKey == LegacyTenantKey or credentials.Secret == LegacyTenantSecret.
Common situations: Deployments that were never rotated after the legacy credentials were published, infrastructure-as-code still referencing the old well-known values, or copied example configs from old docs/READMEs.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Remote resource URL must not include user information
- Outbound URL must not include user information
- 21600
- TENANT_KEY and TENANT_SECRET must be distinct values
- credential file must be a regular non-symbolic-link file
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/fe2c8c3e5f23b34e.
Report an issue: GitHub.
Appendix: source
Thrown at core/tenant/config/bootstrap_credentials.go:79
// bootstrap credential consumer.
func (credentials TenantBootstrapCredentials) Validate() error {
if credentials.TenantID != BootstrapTenantID {
return fmt.Errorf(
"TENANT_ID must remain %s because persisted bootstrap data refers to it",
BootstrapTenantID,
)
}
if err := validateCredential("TENANT_KEY", credentials.APIKey); err != nil {
return err
}
if err := validateCredential("TENANT_SECRET", credentials.Secret); err != nil {
return err
}
if credentials.APIKey == credentials.Secret {
return errors.New("TENANT_KEY and TENANT_SECRET must be distinct values")
}
if credentials.APIKey == LegacyTenantKey || credentials.Secret == LegacyTenantSecret {
return errors.New("published legacy tenant credentials cannot be used")
}
return nil
}
func credentialFromEnvironmentOrFile(valueEnvironment, fileEnvironment string) (string, error) {
if value := strings.TrimSpace(os.Getenv(valueEnvironment)); value != "" {
if err := validateCredential(valueEnvironment, value); err != nil {
return "", err
}
return value, nil
}
fileName := strings.TrimSpace(os.Getenv(fileEnvironment))
if fileName == "" {
return "", fmt.Errorf("%s or %s is required", valueEnvironment, fileEnvironment)
}
value, err := readCredentialFile(fileName)
if err != nil {View on GitHub (pinned to 5e758547a8)