{"record":{"id":"4557af88c2286f20","repo":"gastownhall/beads","slug":"dolt-credential-from-s-contains-a-character","errorCode":null,"errorMessage":"dolt: credential from %s contains a character (:, @, or /) that cannot be placed in the connection username","messagePattern":"dolt: credential from (.+?) contains a character \\(:, @, or /\\) that cannot be placed in the connection username","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/gateway_credential.go","lineNumber":54,"sourceCode":"\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":36,"sourceCodeEnd":63,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/gateway_credential.go#L36-L63","documentation":"Fail-closed validation in ApplyGatewayCredential: the credential value becomes the DSN username, and the go-sql-driver DSN grammar has no escaping for the user field, so any ':', '@', or '/' would silently split the token into wrong user/password parts. JWTs (base64url + '.') are safe; anything containing those three characters is rejected.","triggerScenarios":"The resolved gateway credential's Value contains ':', '@', or '/' — e.g. a basic-auth style 'user:pass' string, a URL containing '/', or a token with embedded '@' — and is about to be set as cfg.ServerUser.","commonSituations":"Operator storing a full DSN or basic-auth string as the gateway credential instead of the raw bearer token; copy-paste including scheme 'https://' in the token; legacy credential values predating the JWT-only format.","solutions":["Replace the credential value with the raw token (JWTs are safe: base64url + '.') without scheme or user:pass decoration","Check the credential source (cred.Source) for where the malformed value is stored and correct it","Sanitize/validate tokens at the point of credential creation to reject ':@/' early","Re-run ApplyGatewayCredential after fixing the stored value"],"exampleFix":"// before\ncred.Value = \"https://user:token@example.com\" // contains ':', '@', '/' -> rejected\n// after\ncred.Value = \"eyJhbGciOi...\" // raw JWT, safe for the DSN username slot","handlingStrategy":"validation","validationCode":"func tokenSafeForDSN(v string) error {\n\tif v == \"\" { return errors.New(\"empty credential value\") }\n\tif strings.ContainsAny(v, \":@/\") { return fmt.Errorf(\"token %q unusable as DSN username\", v) }\n\treturn nil\n}\nif err := tokenSafeForDSN(cred.Value); err != nil { return err }","typeGuard":"func isDSNSafeToken(v string) bool {\n\treturn v != \"\" && !strings.ContainsAny(v, \":@/\")\n}","tryCatchPattern":"ok, err := ApplyGatewayCredential(cfg, cred)\nif err != nil && strings.Contains(err.Error(), \"cannot be placed in the connection username\") {\n\t// rotate/re-store the credential as a raw JWT\n}","preventionTips":["Store raw JWTs only — no URLs or user:pass strings","Validate tokens at credential-creation time","Audit legacy credential values for ':@/'"],"tags":["dolt","gateway","credentials","dsn","validation"],"backgroundTag":"invalid-dsn-username-character","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}