{"record":{"id":"c4c5ad12de5b864e","repo":"gastownhall/beads","slug":"dolt-credential-from-s-is-not-an-identity-refus","errorCode":null,"errorMessage":"dolt: credential from %s is not an identity; refusing to present it as the connection username","messagePattern":"dolt: credential from (.+?) is not an identity; refusing to present it as the connection username","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/gateway_credential.go","lineNumber":48,"sourceCode":"func ApplyGatewayCredential(ctx context.Context, fileCfg *configfile.Config, cfg *Config) (bool, error) {\n\tif cfg.ServerUser != \"\" {\n\t\treturn false, nil\n\t}\n\tcred, ok, err := creds.ResolveLadder(ctx, creds.CommandSource{\n\t\tCommand: fileCfg.GetDoltCredentialCommand(),\n\t\tKind:    creds.KindIdentity,\n\t\tLabel:   \"BEADS_DOLT_CREDENTIAL_COMMAND\",\n\t})\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tif !ok {\n\t\treturn false, nil\n\t}\n\t// Defense in depth: the token is presented AS the username, so a non-identity\n\t// credential must never reach this slot.\n\tif cred.Kind != creds.KindIdentity {\n\t\treturn false, fmt.Errorf(\"dolt: credential from %s is not an identity; refusing to present it as the connection username\", cred.Source)\n\t}\n\t// The token becomes the DSN username; the go-sql-driver grammar has no escaping for\n\t// the user field, so a ':' '@' or '/' would silently mis-split it into user/password.\n\t// Reject rather than connect with a mangled identity. (JWTs are base64url + '.', safe.)\n\tif strings.ContainsAny(cred.Value, \":@/\") {\n\t\treturn false, fmt.Errorf(\"dolt: credential from %s contains a character (:, @, or /) that cannot be placed in the connection username\", cred.Source)\n\t}\n\t// cred.Username (a dynamic user/password pair) is meaningless here: the token IS the\n\t// username. Ignored deliberately.\n\tcfg.ServerUser = cred.Value\n\tcfg.Gateway = true\n\tcfg.DisableAutoStart = true\n\treturn true, nil\n}\n","sourceCodeStart":30,"sourceCodeEnd":63,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/gateway_credential.go#L30-L63","documentation":"A deliberate fail-closed guard in ApplyGatewayCredential: gateway credentials are presented AS the DSN username, so a credential whose Kind is not creds.KindIdentity must never be placed in the connection username slot. The error names cred.Source so the operator knows which credential source produced the rejected token.","triggerScenarios":"ApplyGatewayCredential loads a credential (from command, JSON envelope, preset, etc.) whose Kind is not KindIdentity — e.g. a raw API token or password-type credential — and tries to apply it to the Dolt gateway connection config.","commonSituations":"Misconfigured credential store returning the wrong credential kind for the gateway; operator pointing the gateway at a password/token credential instead of an identity credential; version change altering credential Kind classification.","solutions":["Configure the credential source to produce an identity-kind credential for the gateway","Check which source (cred.Source) is misconfigured and fix its credential type","Verify with the creds package that the resolved credential has Kind == KindIdentity before applying","If this comes from a preset, correct the preset definition to reference the identity credential"],"exampleFix":"// before\ncred := loadCredential(\"gateway-token\") // Kind: password\nok, err := ApplyGatewayCredential(cfg, cred)\n// after\ncred := loadCredential(\"gateway-identity\") // Kind: identity\nif cred.Kind != creds.KindIdentity {\n\treturn fmt.Errorf(\"gateway requires an identity credential, got %s\", cred.Kind)\n}\nok, err := ApplyGatewayCredential(cfg, cred)","handlingStrategy":"type-guard","validationCode":"func isIdentityCred(c creds.Credential) bool { return c.Kind == creds.KindIdentity }\nif !isIdentityCred(cred) {\n\treturn fmt.Errorf(\"gateway needs identity credential, got kind %q from %s\", cred.Kind, cred.Source)\n}","typeGuard":"func isIdentityCredential(c creds.Credential) bool {\n\treturn c.Kind == creds.KindIdentity\n}","tryCatchPattern":"ok, err := ApplyGatewayCredential(cfg, cred)\nif err != nil && strings.Contains(err.Error(), \"is not an identity\") {\n\t// fix the credential source, don't retry with same cred\n}","preventionTips":["Only register KindIdentity credentials for gateway use","Label credential sources clearly in config","Fail at config-load, not connect-time"],"tags":["dolt","gateway","credentials","fail-closed","security"],"backgroundTag":"invalid-credential-kind","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}