Skip to content

fix(drivers): bind rotated OAuth credentials to a stable owner #1109

Description

@frahlg

Resolved on the native 0.x line (2026-10-06)

PR #1508 gives rotated credentials a durable owner and preserves the name-keyed copy for binary rollback. PR #1507 makes Test connection use that owner and restart the matched live driver after a shared token changes. Both fixes passed CI and shipped in v0.139.5-beta.1, source b4badd04db6eae2a046e1334853af206c27f6794.

Regressions cover first upgrade with a previously rotated token, rename, name reuse, reauthorization, restart, late callbacks and rollback. The combined source passed make verify, targeted race tests and full stack tests.

The home box passed upgrade from v0.139.4-beta.1, a real myUplink Test connection with token rotation, rollback to v0.139.4-beta.1 with working myUplink reads and another rotation, then return to v0.139.5-beta.1. Stored settings, goals and identity stayed intact; all three drivers were healthy, history commits advanced without write failures, and only one Core ran. This resolves the credential defect; it does not complete the separate stable qualification.

Original report

A driver rename can discard a saved OAuth rotation, and reusing a name can apply that old credential to another configuration. This blocks promotion of the 3.0 beta line to stable until credentials have a durable owner that does not depend on the driver display name.

Found while reviewing v3.0.3-beta.1 (61839f00e1a16189acc1f491577e0ee6ea00fe13, PR #1108). The same isolated Go/Lua/SQLite reproduction passes on the preceding v3.0.2-beta.1 source (2549645c5da1be4e0b039f9ee02f3fa5738d1409), so #1108 did not introduce the name-keyed storage or override layer. It moved their setup before the first driver initialization, fixing ordinary process restarts.

Reproduction with synthetic credentials:

  1. Keep token A in the driver config and save rotated B under driver_secret:old-name:refresh_token.
  2. Initialize the same driver as renamed. It receives A because the lookup uses the new name.
  3. Initialize another config with token C under old-name. It receives the old override B.

config.SaveStored also matches previous driver credentials by name. On rename it can treat A as a newly supplied token and write A under the new name, so a migration must handle this write path as well as registry startup. The runtime hardware identity is learned after init and may be absent before OAuth authentication; it cannot select the boot credential by itself.

A fix needs tests for rename, name reuse with a different account, explicit reauthorization, restart, and migration of existing name-keyed rows. Reject ambiguous ownership instead of attaching a saved credential to another account. Keep the config document and credential override changes atomic.

The published v3.0.3-beta.1 ARM64 image separately passed an unchanged-driver restart test: config A stays intact, init can save B, and a second Core process receives B. No real accounts or credentials were used in these reproductions.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingrelease-blockerThis line must not promote to stable until fixed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions