{"record":{"id":"9bfac4b6a18676d0","repo":"JuliusBrussee/caveman","slug":"bedrock-unsupported-credential-auth-kind","errorCode":null,"errorMessage":"bedrock: unsupported credential auth kind","messagePattern":"bedrock: unsupported credential auth kind","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/providers/bedrock/signing.go","lineNumber":161,"sourceCode":"\t\treturn kind, nil\n\tcase \"\":\n\t\tkey := strings.TrimSpace(credential.Key)\n\t\tif key == \"\" {\n\t\t\treturn \"\", fmt.Errorf(\"bedrock: missing credential\")\n\t\t}\n\t\t// Backward compatibility for existing x-cave-upstream-key and stored\n\t\t// connection values. A complete colon-form credential remains IAM. An\n\t\t// AKIA/ASIA-looking partial value fails as IAM instead of being sent as a\n\t\t// bearer. Every other opaque value is a Bedrock API key.\n\t\tif _, err := parseAWSCredentials(key); err == nil {\n\t\t\treturn \"aws_access_keys\", nil\n\t\t}\n\t\tif strings.HasPrefix(key, \"AKIA\") || strings.HasPrefix(key, \"ASIA\") {\n\t\t\treturn \"aws_access_keys\", nil\n\t\t}\n\t\treturn \"bedrock_api_key\", nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"bedrock: unsupported credential auth kind\")\n\t}\n}\n\n// parseAWSCredentials decodes the \"accessKeyId:secretAccessKey[:sessionToken]\"\n// form carried in x-cave-upstream-key into awssig.Credentials. It fails closed:\n// a missing access key or secret is an error, never an unsigned passthrough.\nfunc parseAWSCredentials(raw string) (awssig.Credentials, error) {\n\tif raw == \"\" {\n\t\treturn awssig.Credentials{}, fmt.Errorf(\"bedrock: missing AWS credentials in x-cave-upstream-key\")\n\t}\n\tparts := strings.SplitN(raw, \":\", 3)\n\tif len(parts) < 2 || parts[0] == \"\" || parts[1] == \"\" {\n\t\treturn awssig.Credentials{}, fmt.Errorf(\"bedrock: malformed AWS credentials (want accessKeyId:secretAccessKey[:sessionToken])\")\n\t}\n\tcreds := awssig.Credentials{AccessKeyID: parts[0], SecretAccessKey: parts[1]}\n\tif len(parts) == 3 {\n\t\tcreds.SessionToken = parts[2]\n\t}","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/proxy/providers/bedrock/signing.go#L143-L179","documentation":"Thrown by credentialAuthKind in the Bedrock provider when a credential's AuthKind field is set to any string other than 'bedrock_api_key', 'aws_access_keys', or empty. The switch fails closed: an unknown auth kind never falls through to guessing, so a typo like 'aws-key' or 'API_KEY' aborts credential resolution instead of sending the request unsigned or with the wrong scheme.","triggerScenarios":"Passing a providers.Credential with AuthKind set to a value not in {bedrock_api_key, aws_access_keys, \"\"} (after TrimSpace + ToLower) to the Bedrock adapter's signing path — e.g. AuthKind: \"apikey\", \"aws_iam\", \"Bearer\", or \"aws-access-keys\" (hyphens instead of underscores).","commonSituations":"Hand-building a Credential in code or YAML config and inventing an auth kind label; upgrading from an older version that accepted different kind strings; copy-pasting a kind from another provider's adapter (e.g. Anthropic's \"api_key\") into a Bedrock connection.","solutions":["Set AuthKind to exactly \"bedrock_api_key\" for a Bedrock API key bearer credential, or \"aws_access_keys\" for IAM access-key credentials.","Leave AuthKind empty and let the adapter infer: a full \"accessKeyId:secretAccessKey[:sessionToken]\" colon form or an AKIA/ASIA-prefixed value is treated as aws_access_keys; anything else opaque becomes bedrock_api_key.","If migrating config from an older schema, check the stored connection values for the stale auth kind string and update them."],"exampleFix":"// before\ncred := providers.Credential{AuthKind: \"aws-key\", Key: key}\n\n// after\ncred := providers.Credential{AuthKind: \"aws_access_keys\", Key: key}\n// or omit AuthKind entirely:\ncred := providers.Credential{Key: key}","handlingStrategy":"validation","validationCode":"var bedrockAuthKinds = map[string]bool{\"bedrock_api_key\": true, \"aws_access_keys\": true, \"\": true}\n\nfunc validBedrockAuthKind(kind string) bool {\n    return bedrockAuthKinds[strings.ToLower(strings.TrimSpace(kind))]\n}\n\n// before resolving credentials:\nif !validBedrockAuthKind(cred.AuthKind) {\n    return fmt.Errorf(\"rejecting credential with auth kind %q before Bedrock signing\", cred.AuthKind)\n}","typeGuard":null,"tryCatchPattern":"In Go, check the returned error at the credential-resolution call site and surface it as a configuration error (HTTP 502/500 for the proxied request) with the credential's ID (never its secret) in logs — do not retry, this is deterministic config failure.","preventionTips":["Use only the two documented AuthKind literals (bedrock_api_key, aws_access_keys) or leave it empty for inference.","Validate auth kinds in config-load tests so a typo fails CI, not production traffic.","Centralize credential construction in one helper instead of hand-building providers.Credential at multiple call sites."],"tags":["bedrock","authentication","configuration","credentials"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}