Skip to content

Conversation

tsdk02
Copy link
Contributor

@tsdk02 tsdk02 commented Apr 7, 2025

Type of Change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring
  • Dependency updates
  • Documentation
  • CI/CD

Description

This PR introduces two new authentication mechanisms that enhance the existing AdminApiAuth and AdminApiAuthWithMerchantIdFromRoute by allowing fallback to regular API key-based authentication when the admin key check fails.

1. AdminApiAuthWithApiKeyFallback

  • Used in routes where no merchant context is required.
  • Authenticates using:
    1. admin_api_key
    2. If that fails, falls back to:
      • Validating the provided api-key
      • Ensuring its associated merchant_id matches the configured fallback_merchant_id from the merchant_ids set.

2. AdminApiAuthWithApiKeyFallbackWithMerchant

  • Used in routes that require full merchant context (AuthenticationData)
  • Authenticates using:
    1. admin_api_key — on success, loads AuthenticationData
    2. If that fails:
      • Validates the provided api-key
      • Ensures:
        • The merchant_id from api-key also matches the configured fallback_merchant_id from the merchant_ids set.
      • If all conditions pass, loads and returns AuthenticationData

Additional Changes

  • This PR modifies the API contract
  • This PR modifies the database schema
  • This PR modifies application configuration/environment variables

Motivation and Context

Some internal routes currently rely on AdminApiAuth using a shared admin_api_key. However, there are scenarios where we want to allow scoped access using an api-key associated with a specific merchant — only if it matches a configured fallback merchant from the merchant_ids set.

How did you test it?

The following APIs need to be validated with

  • AdminAPIKey
  • the API Key associated with the configured merchant_id in the ENVs.

Tested by setting the ENV through

ROUTER__FALLBACK_MERCHANT_IDS_API_KEY_AUTH__MERCHANT_IDS="merchant_1744036688, merchant_1744037289" cargo run

And also tested by specifying the values in the TOML file.

Merchant Account - Create

curl --location 'http://localhost:8080/accounts' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_PY3zf8m1f0HjtqxO7QS36ZRSGMP5u9IWsmDki4fwq5iY0W8e6RoF4WMwCLvlojJM' \
--data-raw '{
  "merchant_id": "merchant_1744040286",
  "locker_id": "m0010",
  "merchant_name": "Nike",
  "merchant_details": {
    "primary_contact_person": "John Test",
    "primary_email": "[email protected]",
    "primary_phone": "sunt laborum",
    "secondary_contact_person": "John Test2",
    "secondary_email": "[email protected]",
    "secondary_phone": "cillum do dolor id",
    "website": "https://www.example.com",
    "about_business": "Online Retail with a wide selection of organic products for North America",
    "address": {
      "line1": "1467",
      "line2": "Harrison Street",
      "line3": "Harrison Street",
      "city": "San Fransico",
      "state": "California",
      "zip": "94122",
      "country": "US",
      "first_name":"john",
      "last_name":"Doe"
    }
  },
  "return_url": "https://google.com/success",
  "webhook_details": {
    "webhook_version": "1.0.1",
    "webhook_username": "ekart_retail",
    "webhook_password": "password_ekart@123",
    "webhook_url":"https://webhook.site",
    "payment_created_enabled": true,
    "payment_succeeded_enabled": true,
    "payment_failed_enabled": true
  },
  "sub_merchants_enabled": false,
  "parent_merchant_id":"merchant_123",
  "metadata": {
    "city": "NY",
    "unit": "245"
  },
  "primary_business_details": [
    {
      "country": "US",
      "business": "default"
    }
  ],
  "organization_id": "org_aDQVlxlUjkkgfFO9rlwr"
}'

Merchant Account - Retrieve

curl --location 'http://localhost:8080/accounts/merchant_1744037289' \
--header 'Accept: application/json' \
--header 'api-key: dev_PY3zf8m1f0HjtqxO7QS36ZRSGMP5u9IWsmDki4fwq5iY0W8e6RoF4WMwCLvlojJM'

Merchant Account - Update

curl --location 'http://localhost:8080/accounts/merchant_1744037289' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_PY3zf8m1f0HjtqxO7QS36ZRSGMP5u9IWsmDki4fwq5iY0W8e6RoF4WMwCLvlojJM' \
--data-raw '{
  "merchant_id": "merchant_1744037289",
  "locker_id": "m0010",
  "merchant_name": "Nike New",
  "merchant_details": {
    "primary_contact_person": "John Test",
    "primary_email": "[email protected]",
    "primary_phone": "sunt laborum",
    "secondary_contact_person": "John Test2",
    "secondary_email": "[email protected]",
    "secondary_phone": "cillum do dolor id",
    "website": "https://www.example.com",
    "about_business": "Online Retail with a wide selection of organic products for North America",
    "address": {
      "line1": "1467",
      "line2": "Harrison Street",
      "line3": "Harrison Street",
      "city": "San Fransico",
      "state": "California",
      "zip": "94122",
      "country": "US",
      "first_name":"john",
      "last_name":"Doe"
    }
  },
  "return_url": "https://google.com/success",
  "webhook_details": {
    "webhook_version": "1.0.1",
    "webhook_username": "ekart_retail",
    "webhook_password": "password_ekart@123",
    "webhook_url":"https://webhook.site",
    "payment_created_enabled": true,
    "payment_succeeded_enabled": true,
    "payment_failed_enabled": true
  },
  "sub_merchants_enabled": false,
  "parent_merchant_id":"merchant_123",
  "metadata": {
    "city": "NY",
    "unit": "245"
  },
  "primary_business_details": [
    {
      "country": "US",
      "business": "default"
    }
  ]
}'

API Key - Create

curl --location 'http://localhost:8080/api_keys/merchant_1744037289' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
  "name": "API Key 1",
  "description": null,
  "expiration": "2038-01-19T03:14:08.000Z"
}'

API Key - Retrieve

curl --location 'http://localhost:8080/api_keys/merchant_1744037289/dev_Uyyi5bbsKgcsvwgtC4EJ' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin'

API Key - Update

curl --location 'http://localhost:8080/api_keys/merchant_1744037289/dev_Uyyi5bbsKgcsvwgtC4EJ' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
  "name": "Test API Key",
  "description": "My very awesome API key",
  "expiration": null
}'

API Key - List

curl --location 'http://localhost:8080/api_keys/merchant_1744036688/list' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin'

Merchant Account - List

Checklist

  • I formatted the code cargo +nightly fmt --all
  • I addressed lints thrown by cargo clippy
  • I reviewed the submitted code
  • I added unit tests for my changes where possible

@tsdk02 tsdk02 self-assigned this Apr 7, 2025
@tsdk02 tsdk02 requested review from a team as code owners April 7, 2025 13:20
Copy link

semanticdiff-com bot commented Apr 7, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  crates/router/src/services/authentication.rs  22% smaller
  crates/router/src/configs/secrets_transformers.rs  0% smaller
  crates/router/src/configs/settings.rs  0% smaller
  crates/router/src/routes/admin.rs  0% smaller
  crates/router/src/routes/api_keys.rs  0% smaller

ThisIsMani
ThisIsMani previously approved these changes Apr 7, 2025
Copy link
Contributor

@ThisIsMani ThisIsMani left a comment

Choose a reason for hiding this comment

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

Minor concerns.

@tsdk02 tsdk02 linked an issue Apr 7, 2025 that may be closed by this pull request
@tsdk02 tsdk02 added the C-feature Category: Feature request or enhancement label Apr 7, 2025
ThisIsMani
ThisIsMani previously approved these changes Apr 7, 2025
@SanchithHegde SanchithHegde merged commit d6c26c5 into main Apr 8, 2025
23 of 28 checks passed
@SanchithHegde SanchithHegde deleted the merchant-apikey-auth branch April 8, 2025 07:49
tsdk02 added a commit that referenced this pull request Apr 8, 2025
…h if AdminApiAuth fails (#7744)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
pixincreate added a commit that referenced this pull request Apr 10, 2025
…acilitapay-pix-pmt

* 'main' of github.com:juspay/hyperswitch: (21 commits)
  chore(version): 2025.04.10.0
  refactor(connector): [STRIPE] Remove sofort bank redirect from stripe (#7733)
  feat(connector): Add invoice number and email in AuthorizeDotNet connector (#7726)
  fix(router): fix retry_count and add validation for process_tracker (#7614)
  feat(payment_link): expose configurations for payment links (#7742)
  chore(version): 2025.04.09.0
  chore(postman): update Postman collection files
  feat(connector): [AIRWALLEX, ELAVON, NOVALNET, XENDIT] add in feature API (#7163)
  refactor: move merchant_key_store table to accounts schema (#7746)
  chore(postman): update `Stripe` response `status`, `error_code`, and `error_message` for deprecated `Sofort` (#7730)
  feat(connector): Add recovery support for recurly [v2] (#7497)
  refactor(cypress): update BOA configs for manual payments' refunds and connector agnostic (#7690)
  feat(router): Support `card` in `payment_method_subtype` [V2] (#7662)
  feat: Add open API reference for Intelligent router (#7727)
  ci(cypress-ci): remove wise payout from running in github ci (#7756)
  feat(authentication): create authentications to fallback to ApiKeyAuth if AdminApiAuth fails (#7744)
  chore(version): 2025.04.08.0
  feat(core): added force_3ds_challenge for decoupled txns (#7484)
  chore(version): 2025.04.07.0
  chore(postman): update Postman collection files
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature Category: Feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create authentications to fallback to ApiKeyAuth if AdminApiAuth fails
3 participants