Skip to content

fix(auth): Harden Cloud OAuth credential recovery#184

Merged
avivsinai merged 1 commit intomasterfrom
avivsinai/fix/cloud-auth-oauth-recovery
Apr 25, 2026
Merged

fix(auth): Harden Cloud OAuth credential recovery#184
avivsinai merged 1 commit intomasterfrom
avivsinai/fix/cloud-auth-oauth-recovery

Conversation

@avivsinai
Copy link
Copy Markdown
Owner

Harden Bitbucket Cloud credential handling around the OAuth/API-token split that caused expired OAuth credentials to look like API-token state.

Cloud API-token logins now persist auth_method: basic, and explicit configured auth methods are authoritative when loading keychain credentials. OAuth blob inference is limited to legacy missing-auth-method configs and now validates that stored JSON includes access_token, refresh_token, and expires_at before treating it as OAuth.

The Cloud client now carries runtime-only OAuth expiry metadata from the loaded token, fails fast when OAuth is already expired and consumer env vars are missing, and uses a per-host file lock around refresh and keychain write-back to avoid races with rotating refresh tokens. bkt auth status now surfaces inferred OAuth, expired OAuth, unavailable refresh state, and treats BKT_TOKEN as effective basic auth by default.

Recovery guidance now tells users to rerun bkt auth login https://bitbucket.org --kind cloud --web-token to replace stored OAuth credentials with a scoped API token, without recommending auth logout and deleting contexts. The login help also stops presenting OAuth as the recommended default for ordinary Cloud auth.

Comment thread pkg/cmdutil/context_test.go Outdated
func TestLoadHostTokenExplicitBasicTreatsJSONAsPlainToken(t *testing.T) {
store := setupFileKeyring(t)

token := `{"access_token":"literal-api-token","refresh_token":"not-oauth","expires_at":"2099-01-01T00:00:00Z"}`
@avivsinai avivsinai force-pushed the avivsinai/fix/cloud-auth-oauth-recovery branch 2 times, most recently from 3919514 to b17936a Compare April 25, 2026 08:01
Make explicit auth methods authoritative when loading stored Cloud credentials. This prevents legacy OAuth blob sniffing from overriding API-token logins and validates OAuth blobs before treating them as refreshable credentials.

Surface expired OAuth state earlier through auth status and Cloud client construction, and avoid recovery guidance that would delete contexts. Add a per-host refresh lock so concurrent invocations do not race on rotating OAuth refresh tokens.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
@avivsinai avivsinai force-pushed the avivsinai/fix/cloud-auth-oauth-recovery branch from b17936a to 2deadbe Compare April 25, 2026 08:05
@sentry
Copy link
Copy Markdown

sentry Bot commented Apr 25, 2026

Codecov Report

❌ Patch coverage is 64.74820% with 49 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/cmd/auth/auth.go 63.63% 11 Missing and 5 partials ⚠️
pkg/cmdutil/client.go 70.90% 13 Missing and 3 partials ⚠️
internal/filelock/filelock.go 0.00% 11 Missing ⚠️
internal/filelock/filelock_unix.go 0.00% 4 Missing ⚠️
pkg/cmdutil/context.go 88.23% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@avivsinai avivsinai marked this pull request as ready for review April 25, 2026 08:10
@avivsinai avivsinai merged commit 59144b6 into master Apr 25, 2026
10 checks passed
@avivsinai avivsinai deleted the avivsinai/fix/cloud-auth-oauth-recovery branch April 25, 2026 08:10
avivsinai added a commit that referenced this pull request Apr 26, 2026
Add release notes for the Cloud auth hardening work merged in PR #184 so the release script can prepare v0.26.3 from a populated Unreleased section.

Refs #184
Co-Authored-By: OpenAI Codex <noreply@openai.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants