Skip to content

fix(go): Basic Auth header not sent when username is empty#13563

Merged
iamnamananand996 merged 4 commits intomainfrom
devin/1773669098-fix-go-basic-auth-empty-username
Mar 16, 2026
Merged

fix(go): Basic Auth header not sent when username is empty#13563
iamnamananand996 merged 4 commits intomainfrom
devin/1773669098-fix-go-basic-auth-empty-username

Conversation

@iamnamananand996
Copy link
Contributor

@iamnamananand996 iamnamananand996 commented Mar 16, 2026

Description

Fixes a bug where WithBasicAuth("", "my-api-key") silently dropped the Authorization header because the generated ToHeader() required both username and password to be non-empty (&&). Per RFC 7617, an empty user-id is a valid Basic Auth credential (e.g., :password).

Changes Made

  • Changed the Basic Auth guard in the Go SDK generator (sdk.go) from && to ||, so the Authorization header is set when either field is non-empty
  • Updated the corresponding test fixture (testdata/sdk/basic) and seed outputs (any-auth, basic-auth, endpoint-security-auth)
  • Fixed pre-existing ": "":" (extra space after colon) in the test fixture testdata/sdk/basic/fixtures/core/request_option.go, aligning it with the generator output and all seed files per RFC 7617
  • Added version 1.30.2 changelog entry in generators/go/sdk/versions.yml

Testing

  • Existing Go generator tests pass (go test ./internal/...)
  • Seed tests pass (CI green on prior push)
  • No new unit test added specifically for the empty-username scenario

Human Review Checklist

  • Verify the || semantics cover the desired cases: WithBasicAuth("", "pass") ✅ sends header; WithBasicAuth("user", "") ✅ sends header; WithBasicAuth("", "") ❌ does not send header (both fields empty). The reporter noted that supporting fully-empty credentials (":") would require more significant changes.

Link to Devin session: https://app.devin.ai/sessions/860e57bb8f7a47978117231dfb6cf3a0
Requested by: @iamnamananand996


Open with Devin

…ader

Per RFC 7617, an empty user-id is valid in Basic Auth. The previous
condition required both username and password to be non-empty, which
silently dropped the Authorization header when username was empty
(e.g., WithBasicAuth("", "my-api-key")).
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — straightforward one-line logic fix (&&||) consistent with RFC 7617, with matching seed and changelog updates.

Extended reasoning...

Overview

This PR changes a single conditional operator in the Go SDK generator (sdk.go:429) from && to || for the Basic Auth header guard, so the Authorization header is emitted whenever either the username or password is non-empty. The same change is propagated to the test fixture (testdata/sdk/basic/fixtures/core/request_option.go) and three seed output files (any-auth, basic-auth, endpoint-security-auth). A versions.yml entry for v1.30.2 with type: fix is included.

Security risks

The behavioral change means WithBasicAuth("user", "") or WithBasicAuth("", "password") will now send an Authorization header where previously it would silently drop it. This is the correct behavior per RFC 7617 and aligns with how other HTTP clients handle Basic Auth. No new security surface is introduced.

Level of scrutiny

This is a low-risk, mechanical one-line operator change in a code generator. The intent is clear, the RFC justification is sound, and the seed outputs confirm the generator produces the expected output. Minimal scrutiny is needed.

Other factors

The inline bug comment about the pre-existing ": " vs ":" discrepancy in the test fixture is valid but was not introduced by this PR — the PR author explicitly documents this in the Reviewer Checklist. The versions.yml entry follows the repository conventions with the correct type: fix and irVersion: 61.

header := r.cloneHeader()
if r.Username != "" && r.Password != "" {
if r.Username != "" || r.Password != "" {
header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(r.Username+": "+r.Password)))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟣 Pre-existing bug: The test fixture uses r.Username+": "+r.Password (space after colon) but the generator at sdk.go:430 produces r.Username+":"+r.Password (no space). This was supposed to be fixed in v1.16.5 ("Fix Basic auth header formatting to remove erroneous whitespace") but this fixture was missed. Since this PR already modifies this line, it should also fix ": " to ":" to match the generator output and all seed files.

Extended reasoning...

What the bug is

The test fixture at generators/go/internal/testdata/sdk/basic/fixtures/core/request_option.go line 52 constructs the Basic Auth credential string with a space after the colon separator:

header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(r.Username+": "+r.Password)))

while the generator at generators/go/internal/generator/sdk.go line 430 produces:

r.Username + ":" + r.Password

(no space after the colon). All three seed outputs modified in this PR (any-auth, basic-auth, endpoint-security-auth) also use ":" without a space, consistent with the generator.

Step-by-step proof

  1. The generator template at sdk.go:430 emits: r.Username + ":" + r.Password
  2. The seed outputs (e.g., seed/go-sdk/basic-auth/core/request_option.go line 53) all contain: r.Username+":"+r.Password
  3. The fixture at testdata/sdk/basic/fixtures/core/request_option.go line 52 contains: r.Username+": "+r.Password (note the space after colon)
  4. For credentials user / pass, the fixture would produce base64("user: pass") = dXNlcjogcGFzcw== instead of the correct base64("user:pass") = dXNlcjpwYXNz
  5. RFC 7617 specifies the format as user-id ":" password with no whitespace around the colon

Why this was missed

Version 1.16.5 in versions.yml explicitly states: "Fix Basic auth header formatting to remove erroneous whitespace between username and password." This fix was applied to the generator and seed outputs but the test fixture in testdata/sdk/basic/ was overlooked.

Impact

The fixture produces incorrect Basic Auth headers with an extra space in the credentials, violating RFC 7617. If the cmdtest.TestFixtures framework ever runs a byte-for-byte comparison of generated output against this fixture, it would either fail (because the generator produces ":" but the fixture has ": ") or, if the fixture is used as compilable Go code directly, it would produce malformed auth headers at runtime.

Addressing the duplicate concern

One verifier noted this may be a duplicate of bug_002. This report covers bug_001 as assigned; if bug_002 describes the same issue, only one comment needs to be posted. The underlying issue remains valid regardless.

Fix

On line 52 of generators/go/internal/testdata/sdk/basic/fixtures/core/request_option.go, change r.Username+": "+r.Password to r.Username+":"+r.Password to match the generator output.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in 5a9f505. Changed ": " to ":" in the test fixture to match the generator output, seed files, and RFC 7617.

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

Per user feedback, remove the conditional check entirely instead of
changing && to ||. The Authorization header is now always set when
Basic Auth is configured, matching RFC 7617 which considers even
empty username:password as valid credentials.
… auth

Removing the if guard entirely would overwrite Bearer/API key auth in
multi-auth SDKs. The || approach correctly sets the Basic Auth header
when either username or password is non-empty while preserving other
auth mechanisms when Basic Auth is not configured.
The test fixture used ': ' (space after colon) instead of ':' in the
Basic Auth credential string, inconsistent with the generator output
and all seed files. This was missed when v1.16.5 fixed the same issue
in the generator. Per RFC 7617 the format is user-id:password with no
whitespace around the colon.
@iamnamananand996 iamnamananand996 merged commit 05cdce4 into main Mar 16, 2026
89 checks passed
@iamnamananand996 iamnamananand996 deleted the devin/1773669098-fix-go-basic-auth-empty-username branch March 16, 2026 20:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants