JuliusBrussee/caveman · error

bedrock: unsupported credential auth kind

Error message

bedrock: unsupported credential auth kind

What it means

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.

Source

Thrown at proxy/providers/bedrock/signing.go:161

		return kind, nil
	case "":
		key := strings.TrimSpace(credential.Key)
		if key == "" {
			return "", fmt.Errorf("bedrock: missing credential")
		}
		// Backward compatibility for existing x-cave-upstream-key and stored
		// connection values. A complete colon-form credential remains IAM. An
		// AKIA/ASIA-looking partial value fails as IAM instead of being sent as a
		// bearer. Every other opaque value is a Bedrock API key.
		if _, err := parseAWSCredentials(key); err == nil {
			return "aws_access_keys", nil
		}
		if strings.HasPrefix(key, "AKIA") || strings.HasPrefix(key, "ASIA") {
			return "aws_access_keys", nil
		}
		return "bedrock_api_key", nil
	default:
		return "", fmt.Errorf("bedrock: unsupported credential auth kind")
	}
}

// parseAWSCredentials decodes the "accessKeyId:secretAccessKey[:sessionToken]"
// form carried in x-cave-upstream-key into awssig.Credentials. It fails closed:
// a missing access key or secret is an error, never an unsigned passthrough.
func parseAWSCredentials(raw string) (awssig.Credentials, error) {
	if raw == "" {
		return awssig.Credentials{}, fmt.Errorf("bedrock: missing AWS credentials in x-cave-upstream-key")
	}
	parts := strings.SplitN(raw, ":", 3)
	if len(parts) < 2 || parts[0] == "" || parts[1] == "" {
		return awssig.Credentials{}, fmt.Errorf("bedrock: malformed AWS credentials (want accessKeyId:secretAccessKey[:sessionToken])")
	}
	creds := awssig.Credentials{AccessKeyID: parts[0], SecretAccessKey: parts[1]}
	if len(parts) == 3 {
		creds.SessionToken = parts[2]
	}

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Set AuthKind to exactly "bedrock_api_key" for a Bedrock API key bearer credential, or "aws_access_keys" for IAM access-key credentials.
  2. 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.
  3. If migrating config from an older schema, check the stored connection values for the stale auth kind string and update them.

Example fix

// before
cred := providers.Credential{AuthKind: "aws-key", Key: key}

// after
cred := providers.Credential{AuthKind: "aws_access_keys", Key: key}
// or omit AuthKind entirely:
cred := providers.Credential{Key: key}
Defensive patterns

Strategy: validation

Validate before calling

var bedrockAuthKinds = map[string]bool{"bedrock_api_key": true, "aws_access_keys": true, "": true}

func validBedrockAuthKind(kind string) bool {
    return bedrockAuthKinds[strings.ToLower(strings.TrimSpace(kind))]
}

// before resolving credentials:
if !validBedrockAuthKind(cred.AuthKind) {
    return fmt.Errorf("rejecting credential with auth kind %q before Bedrock signing", cred.AuthKind)
}

Try / catch

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.

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/9bfac4b6a18676d0. Report an issue: GitHub.