Skip to content

feat(source-salesforce): persist rotated refresh token (RTR support)#80892

Open
James Truty (jtruty) wants to merge 3 commits into
airbytehq:masterfrom
jtruty:jtruty/source-salesforce-refresh-token-rotation
Open

feat(source-salesforce): persist rotated refresh token (RTR support)#80892
James Truty (jtruty) wants to merge 3 commits into
airbytehq:masterfrom
jtruty:jtruty/source-salesforce-refresh-token-rotation

Conversation

@jtruty

@jtruty James Truty (jtruty) commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

What

Adds support for Salesforce OAuth Refresh Token Rotation (RTR) to source-salesforce.

Closes #80783

Why

Salesforce is mandating RTR as a security control. With RTR enabled on the connected app, each grant_type=refresh_token exchange returns a new, single-use refresh token and invalidates the previous one. The connector discarded the refresh token in the login response, so once RTR is enabled the next sync authenticates with an invalidated token and Salesforce revokes the grant, breaking the connection until manual re-auth.

How

  • Salesforce.login() now captures the refresh token from the token response when one is present.
  • A new SourceSalesforce._persist_rotated_refresh_token writes the rotated token back into the connector config and emits a CONNECTOR_CONFIG control message. It runs from the single _get_sf_object chokepoint, so it covers check, discover, and read.
  • The connector-sidecar persists CONNECTOR_CONFIG control messages for all three operations, double-gated on the config actually changing, so the rotated token survives across syncs.

This is non-breaking: Salesforce returns a new refresh_token only when rotation is enabled, so for connections without RTR the new path is a strict no-op and behavior is unchanged. No spec change and no new config option.

Testing

poetry run pytest unit_tests/ passes (111 tests). New unit tests cover:

  • A rotated refresh token is written to config and emitted as one control message.
  • A response without a refresh token (RTR off) is a no-op (regression guard).
  • An unchanged refresh token emits no control message (idempotency).

Known limitations

RTR's single-use semantics mean a refresh token can still be lost in two edge cases that are not addressed in connector code:

  • Concurrent check and sync on the same source can race two rotations.
  • The pre-save "Test connection" cannot persist (no actor id yet).

Both are mitigated by configuring a refresh token rotation grace window on the Salesforce connected app.

Salesforce is mandating OAuth Refresh Token Rotation. With RTR enabled on
the connected app, each refresh_token exchange returns a new single-use
refresh token and invalidates the previous one. The connector discarded
the returned token, so the next sync used an invalidated token and the
grant was revoked.

Capture the rotated refresh token in Salesforce.login() and persist it
via a CONNECTOR_CONFIG control message emitted from the _get_sf_object
chokepoint, covering check, discover, and read. The path is a strict
no-op when RTR is off, since Salesforce returns a new refresh token only
when rotation is enabled, so the change is non-breaking.

Closes airbytehq#80783

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fx2eMxCQoDZfL6NUdS4cc5
@octavia-bot octavia-bot Bot marked this pull request as draft June 25, 2026 21:32
@octavia-bot

octavia-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Note

📝 PR Converted to Draft

More info...

Thank you for creating this PR. As a policy to protect our engineers' time, Airbyte requires all PRs to be created first in draft status. Your PR has been automatically converted to draft status in respect for this policy.

As soon as your PR is ready for formal review, you can proceed to convert the PR to "ready for review" status by clicking the "Ready for review" button at the bottom of the PR page.

To skip draft status in future PRs, please include [ready] in your PR title or add the skip-draft-status label when creating your PR.

@github-actions

Copy link
Copy Markdown
Contributor

👋 Welcome to Airbyte!

Thank you for your contribution from jtruty/airbyte! We're excited to have you in the Airbyte community.

If you have any questions, feel free to ask in the PR comments or join our Slack community.

💡 Show Tips and Tricks

PR Slash Commands

As needed or by request, Airbyte Maintainers can execute the following slash commands on your PR:

  • /format-fix - Fixes most formatting issues.
  • /bump-version - Bumps connector versions.
  • /run-connector-tests - Runs connector tests.
  • /run-cat-tests - Runs CAT tests.
  • /run-regression-tests - Runs regression tests for the modified connector(s).
  • /build-connector-images - Builds and publishes a pre-release docker image for the modified connector(s).
  • /publish-connectors-prerelease - Publishes pre-release connector builds (tagged as {version}-preview.{git-sha}) for all modified connectors in the PR.
  • /ai-review - AI-powered PR review for connector safety and quality gates.
  • /ai-docs-review - AI-powered documentation review for PRs with connector changes.
  • /ai-create-docs-pr - Creates a documentation PR for connector changes.
  • /force-merge reason="<A_GOOD_REASON>" - Force merges the PR using admin privileges, bypassing CI checks. Requires a reason.

Tips for Working with CI

  1. Pre-Release Checks. Please pay attention to these, as they contain standard checks on the metadata.yaml file, docs requirements, etc. If you need help resolving a pre-release check, please ask a maintainer.
    • Note: If you are creating a new connector, please be sure to replace the default logo.svg file with a suitable icon.
  2. Connector CI Tests. Some failures here may be expected if your tests require credentials. Please review these results to ensure (1) unit tests are passing, if applicable, and (2) integration tests pass to the degree possible and expected.
  3. (Optional.) BYO Connector Credentials for tests in your fork. You can optionally set up your fork with BYO credentials for your connector. This can significantly speed up your review, ensuring your changes are fully tested before the maintainers begin their review.
📚 Show Repo Guidance

Helpful Resources

📝 Edit this welcome message.

James Truty (jtruty) and others added 2 commits June 25, 2026 16:34
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fx2eMxCQoDZfL6NUdS4cc5
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fx2eMxCQoDZfL6NUdS4cc5
@jtruty James Truty (jtruty) marked this pull request as ready for review June 25, 2026 21:36
@jtruty James Truty (jtruty) changed the title Source Salesforce: persist rotated refresh token (RTR support) feat(source-salesforce): persist rotated refresh token (RTR support) Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

[source-salesforce] Support OAuth Refresh Token Rotation (RTR) ahead of Salesforce 2026 enforcement

2 participants