Skip to content

feat(source-amazon-seller-partner): Add Restricted Data Token (RDT) support for Orders stream PII fields - #74296

Merged
Serhii Lazebnyi (lazebnyi) merged 10 commits into
masterfrom
devin/1772667651-add-rdt-support-amazon-seller-partner
Mar 10, 2026
Merged

Serhii Lazebnyi (lazebnyi) merged 10 commits into
masterfrom
devin/1772667651-add-rdt-support-amazon-seller-partner

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Mar 4, 2026 •

Copy link
Copy Markdown
Contributor

What

Resolves https://github.com/airbytehq/oncall/issues/11345:

Adds Restricted Data Token (RDT) support for the Orders and OrderItems streams, enabling access to PII fields (BuyerInfo, ShippingAddress) that Amazon SP-API gates behind the Tokens API.

How

  1. New AmazonSPRdtAuthenticator class (components.py): Extends AmazonSPOauthAuthenticator to fetch, cache, and proactively refresh RDTs via POST /tokens/2021-03-01/restrictedDataToken.

    • 403 fallback: If the RDT request returns 403 (missing Restricted Role), the authenticator permanently falls back to the standard LWA token for the remainder of the sync — BuyerInfo/ShippingAddress remain empty (same as today).
    • Other errors: Non-retryable errors raise AirbyteTracedException with FailureType.config_error; retryable errors (429, 5xx) raise DefaultBackoffException and are retried via a @backoff.on_exception decorator.
    • Caching: RDT is cached with its fetch timestamp; get_auth_header() checks time.monotonic() and refreshes if older than 50 minutes (RDTs are valid for 1 hour).
    • Path-based scoping: One RDT covers /orders/v0/orders and /orders/v0/orders/*/orderItems (wildcard), avoiding per-order token requests.
    • Thread safety: _get_rdt_token() uses double-checked locking (threading.Lock) to prevent concurrent threads from refreshing the RDT simultaneously, following the pattern from airbyte-python-cdk#883.
  2. Manifest wiring (manifest.yaml):

    • New orders_authenticator / orders_requester definitions — only Orders and OrderItems streams use the RDT-aware authenticator; all other streams continue using the standard base_requester.
    • New include_pii boolean config option (default: false).
    • Expanded ShippingAddress schema with PII fields (Name, AddressLine1–3, Phone) and additionalProperties: true.
  3. Token invalidation refactor (components.py): _authenticator_instance (single) → _authenticator_instances (list) so that the backoff strategy invalidates all authenticator instances on a "token expired" 403, which is necessary now that two authenticator instances exist.

  4. Version bump: 5.5.1 → 5.6.0 (MINOR — new backward-compatible functionality, not breaking).

Review guide

  1. components.py — AmazonSPRdtAuthenticator class (lines 90–216) is the core addition. Key areas: thread-safe _get_rdt_token() with double-checked locking, @backoff.on_exception on _fetch_rdt_token(), and the _authenticator_instances list change used in _check_and_invalidate_expired_token.
  2. manifest.yaml — orders_authenticator / orders_requester definitions (~line 516), include_pii spec option (~line 285), ShippingAddress schema expansion (~line 9416), and the requester $ref changes for orders/order_items streams.
  3. unit_tests/test_rdt_authenticator.py — 305 lines of unit tests covering RDT fetch, caching, 403 fallback, error handling, and thread-safe concurrent refresh.
  4. unit_tests/test_token_invalidation.py — Updated existing tests to work with _authenticator_instances list.

Key items for human review:

  • The RDT API request payload (dataElements: ["buyerInfo", "shippingAddress"], path: "/orders/v0/orders", "/orders/v0/orders/*/orderItems") matches Amazon SP-API Tokens API docs.
  • CRITICAL: The ShippingAddress PII field names (Name, AddressLine1, AddressLine2, AddressLine3, Phone) match the actual Amazon Orders API response structure. If these are incorrect, PII data will be silently dropped.
  • The permanent _rdt_fallback_to_lwa flag (once a 403 is received, the connector never retries RDT for the rest of the sync) is the desired behavior per the requirements.
  • The _authenticator_instances list approach (invalidate all instances on "token expired" 403) doesn't cause unintended side effects with the backoff strategy.
  • The _rdt_lock is a class-level lock (shared across all instances). This matches the pattern from CDK PR Consolidation of roadmap #883 and is intentional because multiple stream instances share the same refresh token from connector config. Verify this doesn't cause issues if there are truly independent OAuth flows (unlikely in Airbyte's single-process-per-connector architecture).
  • RDT token fetch uses requests.post directly + @backoff.on_exception decorator for retries. This bypasses CDK HTTP client but includes backoff/retry for transient errors.

User Impact

  • Opt-in PII access: Users can now set include_pii: true to retrieve buyer PII fields (BuyerInfo, ShippingAddress) in the Orders and OrderItems streams, enabling cohort analyses by buyer email.
  • Zero impact for existing users: Default include_pii: false — existing syncs are unaffected.
  • Graceful degradation: If the user's Amazon developer profile lacks the required Restricted Role, the connector logs a warning and falls back to standard LWA authentication (BuyerInfo/ShippingAddress remain empty, same as today).
  • Prerequisites: User must have an approved Restricted Role (Direct-to-Consumer Shipping or Tax Invoicing/Tax Remittance) from Amazon.

Can this PR be safely reverted and rolled back?

  • YES 💚

Revert-safe because:

  • New include_pii config defaults to false — no change for existing connections.
  • The orders_authenticator is only used for Orders/OrderItems streams; other streams continue using the standard base_requester.
  • Schema changes are additive-only (additionalProperties: true, new optional PII fields).

Updates since last revision

  • Thread safety: Added threading.Lock with double-checked locking to _get_rdt_token() to prevent concurrent threads from refreshing the RDT simultaneously (airbyte-python-cdk#883 pattern)
  • Added unit test TestRdtTokenThreadSafety.test_concurrent_refresh_only_fetches_once verifying 5 concurrent threads result in exactly 1 fetch call
  • Fixed test assertions in test_500_error_raises_backoff_exception and test_502_error_raises_backoff_exception to expect DefaultBackoffException (retryable) instead of AirbyteTracedException, matching reviewer's refactored error handling
  • Applied ruff-format fixes: corrected import order in test_rdt_authenticator.py and indentation in test_token_invalidation.py

🔗 Session: https://app.devin.ai/sessions/d0af16adf39d477f91e8af506c372614
👤 Requested by: bot_apk (apk@cognition.ai)

…upport for Orders stream PII fields

- Add AmazonSPRdtAuthenticator class that extends AmazonSPOauthAuthenticator
  with RDT support for accessing PII fields (BuyerInfo, ShippingAddress)
- Add include_pii config option (default: false) for opt-in PII access
- Implement 403 fallback: gracefully falls back to standard LWA token when
  Restricted Role is not available
- Implement RDT caching with 50-minute proactive refresh threshold
- Use path-based scoping: /orders/v0/orders and /orders/v0/orders/*/orderItems
- Add orders_authenticator and orders_requester to manifest for Orders/OrderItems
- Expand ShippingAddress schema with PII fields (Name, AddressLine1-3, Phone)
- Add comprehensive unit tests for RDT authenticator
- Update _authenticator_instance to _authenticator_instances list for multi-instance support
- Bump version to 5.6.0 (MINOR - new backward-compatible functionality)

Co-Authored-By: bot_apk <apk@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 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

@github-actions

github-actions Bot commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

💡 Show Tips and Tricks

PR Slash Commands

Airbyte Maintainers (that's you!) can execute the following slash commands on your PR:

  • 🛠️ Quick Fixes
    • /format-fix - Fixes most formatting issues.
    • /bump-version - Bumps connector versions, scraping changelog description from the PR title.
  • ❇️ AI Testing and Review (internal link: AI-SDLC Docs):
    • /ai-prove-fix - Runs prerelease readiness checks, including testing against customer connections.
    • /ai-canary-prerelease - Rolls out prerelease to 5-10 connections for canary testing.
    • /ai-review - AI-powered PR review for connector safety and quality gates.
  • 🚀 Connector Releases:
    • /publish-connectors-prerelease - Publishes pre-release connector builds (tagged as {version}-preview.{git-sha}) for all modified connectors in the PR.
    • /bump-progressive-rollout-version - Bumps connector version with an RC suffix (2.16.10-rc.1) for progressive rollouts (enableProgressiveRollout: true).
      • Example: /bump-progressive-rollout-version changelog="Add new feature for progressive rollout"
  • ☕️ JVM connectors:
    • /update-connector-cdk-version connector=<CONNECTOR_NAME> - Updates the specified connector to the latest CDK version.
      Example: /update-connector-cdk-version connector=destination-bigquery
  • 🐍 Python connectors:
    • /poe connector source-example lock - Run the Poe lock task on the source-example connector, committing the results back to the branch.
    • /poe source example lock - Alias for /poe connector source-example lock.
    • /poe source example use-cdk-branch my/branch - Pin the source-example CDK reference to the branch name specified.
    • /poe source example use-cdk-latest - Update the source-example CDK dependency to the latest available version.
  • ⚙️ Admin commands:
    • /force-merge reason="<REASON>" - Force merges the PR using admin privileges, bypassing CI checks. Requires a reason.
      Example: /force-merge reason="CI is flaky, tests pass locally"
📚 Show Repo Guidance

Helpful Resources

📝 Edit this welcome message.

Co-Authored-By: bot_apk <apk@cognition.ai>
@github-actions

github-actions Bot commented Mar 4, 2026 •

Copy link
Copy Markdown
Contributor

Deploy preview for airbyte-docs ready!

✅ Preview
https://airbyte-docs-km3y70jqi-airbyte-growth.vercel.app

Built with commit 065f13f.
This pull request is being automatically deployed with vercel-action

…oken fetch

Replace manual retry loop with @backoff.on_exception decorator matching
the CDK's OAuth authenticator pattern for consistent retry/backoff on
transient errors (429, 5xx).
@github-actions

github-actions Bot commented Mar 6, 2026 •

Copy link
Copy Markdown
Contributor

source-amazon-seller-partner Connector Test Results

503 tests   500 ✅  18m 48s ⏱️
  2 suites    3 💤
  2 files      0 ❌

Results for commit 065f13f.

♻️ This comment has been updated with latest results.

… of github.com:airbytehq/airbyte into devin/1772667651-add-rdt-support-amazon-seller-partner
@lazebnyi

Serhii Lazebnyi (lazebnyi) commented Mar 6, 2026 •

Copy link
Copy Markdown
Contributor

/format-fix

Format-fix job started... Check job output.

✅ Changes applied successfully. (2f18a48)

# ------------------------------------------------------------------

def _get_rdt_token(self) -> Optional[str]:
"""Return a cached RDT if still fresh, otherwise fetch a new one."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we add a lock here, similar to the one used in the CDK OAuth flow, to prevent multiple threads from refreshing the tokens at the same time? https://github.com/airbytehq/airbyte-python-cdk/pull/883/changes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch! Added a threading.Lock with double-checked locking to _get_rdt_token(), following the same pattern from airbyte-python-cdk#883:

  1. First check without lock (fast path for cached token)
  2. Acquire lock
  3. Re-check (another thread may have refreshed while waiting)
  4. If still expired, fetch new token

Also added a unit test that verifies 5 concurrent threads result in exactly 1 fetch call.

Commit: 065f13f

… with double-checked locking

- Add threading.Lock to AmazonSPRdtAuthenticator._get_rdt_token() to prevent
  concurrent threads from refreshing the RDT simultaneously (see airbyte-python-cdk#883)
- Add unit test verifying only one fetch occurs with 5 concurrent threads
- Fix test assertions to match reviewer's refactored error handling (backoff for 5xx)

Co-Authored-By: bot_apk <apk@cognition.ai>
@lazebnyi

Serhii Lazebnyi (lazebnyi) commented Mar 6, 2026 •

Copy link
Copy Markdown
Contributor

/ai-prove-fix

AI Prove Fix Started

Running readiness checks and testing against customer connections.
View workflow run
🔍 AI Prove Fix session starting... Running readiness checks and testing against customer connections. View playbook

✅ Devin AI session created successfully!

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Fix Validation Evidence

Outcome: In Progress...

Status

Starting /ai-prove-fix validation for PR #74296 — source-amazon-seller-partner v5.6.0 (Add RDT support for Orders stream PII fields).

Current Step: Reading PR, oncall issue, and performing pre-flight checks.

Session: https://app.devin.ai/sessions/14ea9cbce6c54f0ab0bf3ea7176f4c32


This comment will be updated as the validation progresses.

@github-actions

github-actions Bot commented Mar 6, 2026 •

Copy link
Copy Markdown
Contributor

Pre-release Connector Publish Started

Publishing pre-release build for connector source-amazon-seller-partner.
PR: #74296

Pre-release versions will be tagged as {version}-preview.065f13f
and are available for version pinning via the scoped_configuration API.

View workflow run
Pre-release Publish: SUCCESS ✅

Docker image (pre-release):
airbyte/source-amazon-seller-partner:5.6.0-preview.065f13f

Docker Hub: https://hub.docker.com/layers/airbyte/source-amazon-seller-partner/5.6.0-preview.065f13f

Registry JSON:

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Fix Validation Evidence — In Progress

Status: Gathering evidence...

Evidence Plan

Proving Criteria:

  • Regression tests pass: pre-release 5.6.0-preview.065f13f shows no regression vs baseline 5.5.1
  • Live sync completes successfully on pre-release version with Orders/OrderItems streams enabled (default config, include_pii=false)
  • CI tests pass (503 tests: 500 passed, 3 skipped, 0 failed) — confirms RDT token logic, caching, and fallback behavior

Disproving Criteria:

  • Regression tests show new failures not present in baseline
  • Live sync fails with errors not present in current production version
  • New errors in Orders/OrderItems streams specifically

Test Cases (ranked by preference)

  1. Regression Tests (REQUIRED) — Isolated comparison test between baseline 5.5.1 and pre-release 5.6.0-preview.065f13f

  2. Live Connection Test — Internal Connection A — Internal Airbyte org connection with Orders + OrderItems streams to /dev/null destination

    • Streams: Orders, OrderItems + 37 others
    • Source not pinned (running v5.5.1)
    • Plan: Pin to pre-release, trigger sync, verify completion
  3. Backup — Internal Connection B — Internal Airbyte org connection with Orders + OrderItems + ListFinancialEventGroups to Redshift

    • Source not pinned (running v5.5.1)
    • Fallback if Connection A is blocked

Notes

  • This is a feature PR (MINOR bump), not a bug fix. The new include_pii config defaults to false, so existing connections exercise the default (non-PII) code path.
  • The RDT-specific logic (include_pii=true path) is validated by unit/integration tests in CI.
  • Pre-release image published successfully: 5.6.0-preview.065f13f
Pre-flight Checks
  • Viability: Code changes add RDT authenticator with thread-safe caching and 403 fallback
  • Safety: No malicious code or dangerous patterns
  • Breaking Change: NOT breaking (schema additive-only, include_pii optional with default false)
  • Reversibility: Safe to downgrade (MINOR version bump, no state/config format changes)

Devin session

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

/publish-connectors-prerelease

@github-actions

github-actions Bot commented Mar 9, 2026 •

Copy link
Copy Markdown
Contributor

Pre-release Connector Publish Started

Publishing pre-release build for connector source-amazon-seller-partner.
PR: #74296

Pre-release versions will be tagged as {version}-preview.065f13f
and are available for version pinning via the scoped_configuration API.

View workflow run
Pre-release Publish: SUCCESS ✅

Docker image (pre-release):
airbyte/source-amazon-seller-partner:5.6.0-preview.065f13f

Docker Hub: https://hub.docker.com/layers/airbyte/source-amazon-seller-partner/5.6.0-preview.065f13f

Registry JSON:

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Pre-release Testing: Version Pin Request

Pinning pre-release version 5.6.0-preview.065f13f in the @devin-ai-sandbox workspace (ID: 266ebdfe-0d7b-4540-9817-de7e4505ba61) for testing.

Actions taken:

  1. Published pre-release Docker image: airbyte/source-amazon-seller-partner:5.6.0-preview.065f13f
  2. Deployed source with test credentials in sandbox workspace
  3. Created connection "Amazon SP (RDT Pre-release Test) → Dev Null" (streams: Orders, OrderItems)
  4. Pinning workspace-level version override to 5.6.0-preview.065f13f

Requested by Serhii Lazebnyi (@lazebnyi)


Devin session

@lazebnyi

Copy link
Copy Markdown
Contributor

Approved: pin 5.6.0-preview.065f13f in @devin-ai-sandbox

@aaronsteers

Copy link
Copy Markdown
Member

Devin, please take this comment as approval on Serhii's behalf.

@github-actions

github-actions Bot commented Mar 9, 2026 •

Copy link
Copy Markdown
Contributor

Pre-release Connector Publish Started

Publishing pre-release build for connector source-amazon-seller-partner.
PR: #74296

Pre-release versions will be tagged as {version}-preview.065f13f
and are available for version pinning via the scoped_configuration API.

View workflow run
Pre-release Publish: SUCCESS ✅

Docker image (pre-release):
airbyte/source-amazon-seller-partner:5.6.0-preview.065f13f

Docker Hub: https://hub.docker.com/layers/airbyte/source-amazon-seller-partner/5.6.0-preview.065f13f

Registry JSON:

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Pinning prerelease version 5.6.0-preview.065f13f on sandbox workspace (@devin-ai-sandbox) for testing RDT support. Requested by @gl_serhii.lazebnyi.


Devin session

@lazebnyi

Serhii Lazebnyi (lazebnyi) commented Mar 9, 2026 •

Copy link
Copy Markdown
Contributor

Devin, please take this comment as an approve from my side

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Thank you for the approval, Serhii Lazebnyi (@lazebnyi)! 🙏

@lazebnyi
Serhii Lazebnyi (lazebnyi) merged commit c4b8049 into master Mar 10, 2026
45 checks passed
@lazebnyi
Serhii Lazebnyi (lazebnyi) deleted the devin/1772667651-add-rdt-support-amazon-seller-partner branch March 10, 2026 00:26
Robertas Kudulis (rkudulis) pushed a commit to rkudulis/airbyte that referenced this pull request Mar 16, 2026
…upport for Orders stream PII fields (airbytehq#74296)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
Co-authored-by: Serhii Lazebnyi <53845333+lazebnyi@users.noreply.github.com>
Co-authored-by: Serhii Lazebnyi <gl_serhii.lazebnyi@airbyte.io>
Co-authored-by: Octavia Squidington III <octavia-squidington-iii@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants