Issue:
Bug: feat(authz): Make permissions entity and scope aware



Currently the permissions we use doesn't have any entity level context. But some of our APIs need that context.
For example,
1. `payment/list` - This can only be accessible by merchant level users or higher. Profile level users should not be able to access it.
2. `payment/profile/list` - This can be accessible by all level of users.

With current setup, this is not directly possible by the permissions. We had to introduce `min_entity_level` to solve this, but this is very separated from the permissions.

To solve this, we need to have entity level context at permissions level itself.

### Scope for permissions
The write permissions currently doesn't have access to read APIs, but since write is a superset of read, they should be able to access read APIs as well.

So, this PR also introduces scope context in permissions.


Pull request description:
## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [x] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->

### Entity level context in Permissions
Currently the permissions we use doesn't have any entity level context. But some of our APIs need that context.
For example,
1. `payment/list` - This can only be accessible by merchant level users or higher. Profile level users should not be able to access it.
2. `payment/profile/list` - This can be accessible by all level of users.

With current setup, this is not directly possible by the permissions. We had to introduce `min_entity_level` to solve this, but this is very separated from the permissions.

To solve this, we need to have entity level context at permissions level itself.

### Scope for permissions
The write permissions currently doesn't have access to read APIs, but since write is a superset of read, they should be able to access read APIs as well.

So, this PR also introduces scope context in permissions.

---
This PR also improves the scalability of permissions, as the more entity levels being added in the control center, this will make it easy to extend the permissions as well.

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
4. `crates/router/src/configs`
5. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->
Closes [#6391](https://github.com/juspay/hyperswitch/issues/6391).

## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
This is an internal change, no APIs should be affected and all the APIs should be working as usual.

## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible


Testing:

This is an internal change, no APIs should be affected and all the APIs should be working as usual.

Patch:
diff --git a/crates/api_models/src/user_role.rs b/crates/api_models/src/user_role.rs
index e64639646d1..19027c3cbf8 100644
--- a/crates/api_models/src/user_role.rs
+++ b/crates/api_models/src/user_role.rs
@@ -1,23 +1,9 @@
-use common_enums::PermissionGroup;
+use common_enums::{ParentGroup, PermissionGroup};
 use common_utils::pii;
 use masking::Secret;
 
 pub mod role;
 
-#[derive(Clone, Debug, serde::Serialize, PartialEq, Eq, Hash)]
-pub enum ParentGroup {
-    Operations,
-    Connectors,
-    Workflows,
-    Analytics,
-    Users,
-    #[serde(rename = "MerchantAccess")]
-    Merchant,
-    #[serde(rename = "OrganizationAccess")]
-    Organization,
-    Recon,
-}
-
 #[derive(Debug, serde::Serialize)]
 pub struct AuthorizationInfoResponse(pub Vec<AuthorizationInfo>);
 
diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs
index 3ce9d079c63..c103153eec8 100644
--- a/crates/common_enums/src/enums.rs
+++ b/crates/common_enums/src/enums.rs
@@ -2890,6 +2890,47 @@ pub enum PermissionGroup {
     ReconOps,
 }
 
+#[derive(Clone, Debug, serde::Serialize, PartialEq, Eq, Hash, strum::EnumIter)]
+pub enum ParentGroup {
+    Operations,
+    Connectors,
+    Workflows,
+    Analytics,
+    Users,
+    #[serde(rename = "MerchantAccess")]
+    Merchant,
+    #[serde(rename = "OrganizationAccess")]
+    Organization,
+    Recon,
+}
+
+#[derive(Clone, Copy, Eq, PartialEq, Hash)]
+pub enum Resource {
+    Payment,
+    Refund,
+    ApiKey,
+    Account,
+    Connector,
+    Routing,
+    Dispute,
+    Mandate,
+    Customer,
+    Analytics,
+    ThreeDsDecisionManager,
+    SurchargeDecisionManager,
+    User,
+    WebhookEvent,
+    Payout,
+    Report,
+    Recon,
+}
+
+#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
+pub enum PermissionScope {
+    Read,
+    Write,
+}
+
 /// Name of banks supported by Hyperswitch
 #[derive(
     Clone,
diff --git a/crates/router/src/analytics.rs b/crates/router/src/analytics.rs
index aa6db56bb34..150931e9c8a 100644
--- a/crates/router/src/analytics.rs
+++ b/crates/router/src/analytics.rs
@@ -402,8 +402,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -441,8 +440,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Organization,
+                permission: Permission::OrganizationAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -487,8 +485,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -528,8 +525,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -567,8 +563,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Organization,
+                permission: Permission::OrganizationAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -613,8 +608,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -654,8 +648,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -693,8 +686,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Organization,
+                permission: Permission::OrganizationAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -739,8 +731,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -774,8 +765,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -813,8 +803,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -853,8 +842,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -893,8 +881,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -924,8 +911,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -953,8 +939,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Organization,
+                permission: Permission::OrganizationAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -989,8 +974,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1018,8 +1002,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1049,8 +1032,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1078,8 +1060,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Organization,
+                permission: Permission::OrganizationAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1114,8 +1095,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1139,8 +1119,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1168,8 +1147,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1201,8 +1179,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1235,8 +1212,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1267,8 +1243,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1318,8 +1293,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::GenerateReport,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantReportRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1367,8 +1341,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::GenerateReport,
-                minimum_entity_level: EntityType::Organization,
+                permission: Permission::OrganizationReportRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1423,8 +1396,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::GenerateReport,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileReportRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1474,8 +1446,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::GenerateReport,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantReportRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1523,8 +1494,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::GenerateReport,
-                minimum_entity_level: EntityType::Organization,
+                permission: Permission::OrganizationReportRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1579,8 +1549,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::GenerateReport,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileReportRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1630,8 +1599,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::GenerateReport,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantReportRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1679,8 +1647,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::GenerateReport,
-                minimum_entity_level: EntityType::Organization,
+                permission: Permission::OrganizationReportRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1734,8 +1701,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::GenerateReport,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileReportRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1773,8 +1739,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1798,8 +1763,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1830,8 +1794,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -1948,8 +1911,7 @@ pub mod routes {
                 .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -2065,8 +2027,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -2096,8 +2057,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -2132,8 +2092,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -2161,8 +2120,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Organization,
+                permission: Permission::OrganizationAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -2202,8 +2160,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -2248,8 +2205,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -2287,8 +2243,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Organization,
+                permission: Permission::OrganizationAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -2319,8 +2274,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -2349,8 +2303,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Organization,
+                permission: Permission::OrganizationAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -2386,8 +2339,7 @@ pub mod routes {
                     .map(ApplicationResponse::Json)
             },
             &auth::JWTAuth {
-                permission: Permission::Analytics,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAnalyticsRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
diff --git a/crates/router/src/core/user_role.rs b/crates/router/src/core/user_role.rs
index 1d188168e5c..284be4ab4ba 100644
--- a/crates/router/src/core/user_role.rs
+++ b/crates/router/src/core/user_role.rs
@@ -16,14 +16,14 @@ use crate::{
     routes::{app::ReqState, SessionState},
     services::{
         authentication as auth,
-        authorization::{info, roles},
+        authorization::{info, permission_groups::PermissionGroupExt, roles},
         ApplicationResponse,
     },
     types::domain,
     utils,
 };
 pub mod role;
-use common_enums::{EntityType, PermissionGroup};
+use common_enums::{EntityType, ParentGroup, PermissionGroup};
 use strum::IntoEnumIterator;
 
 // TODO: To be deprecated
@@ -44,11 +44,10 @@ pub async fn get_authorization_info_with_group_tag(
 ) -> UserResponse<user_role_api::AuthorizationInfoResponse> {
     static GROUPS_WITH_PARENT_TAGS: Lazy<Vec<user_role_api::ParentInfo>> = Lazy::new(|| {
         PermissionGroup::iter()
-            .map(|value| (info::get_parent_name(value), value))
+            .map(|group| (group.parent(), group))
             .fold(
                 HashMap::new(),
-                |mut acc: HashMap<user_role_api::ParentGroup, Vec<PermissionGroup>>,
-                 (key, value)| {
+                |mut acc: HashMap<ParentGroup, Vec<PermissionGroup>>, (key, value)| {
                     acc.entry(key).or_default().push(value);
                     acc
                 },
diff --git a/crates/router/src/routes/admin.rs b/crates/router/src/routes/admin.rs
index 78238d3af07..b197101d65f 100644
--- a/crates/router/src/routes/admin.rs
+++ b/crates/router/src/routes/admin.rs
@@ -1,5 +1,4 @@
 use actix_web::{web, HttpRequest, HttpResponse};
-use common_enums::EntityType;
 use router_env::{instrument, tracing, Flow};
 
 use super::app::AppState;
@@ -52,8 +51,7 @@ pub async fn organization_update(
             &auth::AdminApiAuth,
             &auth::JWTAuthOrganizationFromRoute {
                 organization_id,
-                required_permission: Permission::MerchantAccountWrite,
-                minimum_entity_level: EntityType::Organization,
+                required_permission: Permission::OrganizationAccountWrite,
             },
             req.headers(),
         ),
@@ -85,8 +83,7 @@ pub async fn organization_retrieve(
             &auth::AdminApiAuth,
             &auth::JWTAuthOrganizationFromRoute {
                 organization_id,
-                required_permission: Permission::MerchantAccountRead,
-                minimum_entity_level: EntityType::Organization,
+                required_permission: Permission::OrganizationAccountRead,
             },
             req.headers(),
         ),
@@ -139,8 +136,11 @@ pub async fn retrieve_merchant_account(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: Permission::MerchantAccountRead,
-                minimum_entity_level: EntityType::Profile,
+                // This should ideally be MerchantAccountRead, but since FE is calling this API for
+                // profile level users currently keeping this as ProfileAccountRead. FE is removing
+                // this API call for profile level users.
+                // TODO: Convert this to MerchantAccountRead once FE changes are done.
+                required_permission: Permission::ProfileAccountRead,
             },
             req.headers(),
         ),
@@ -172,7 +172,6 @@ pub async fn merchant_account_list(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromHeader {
                 required_permission: Permission::MerchantAccountRead,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
@@ -200,7 +199,6 @@ pub async fn merchant_account_list(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromHeader {
                 required_permission: Permission::MerchantAccountRead,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
@@ -232,7 +230,6 @@ pub async fn update_merchant_account(
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id: merchant_id.clone(),
                 required_permission: Permission::MerchantAccountWrite,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
@@ -298,8 +295,7 @@ pub async fn connector_create(
             &auth::AdminApiAuthWithMerchantIdFromRoute(merchant_id.clone()),
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id: merchant_id.clone(),
-                required_permission: Permission::MerchantConnectorAccountWrite,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: Permission::ProfileConnectorWrite,
             },
             req.headers(),
         ),
@@ -336,8 +332,7 @@ pub async fn connector_create(
         auth::auth_type(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromHeader {
-                required_permission: Permission::MerchantConnectorAccountWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantConnectorWrite,
             },
             req.headers(),
         ),
@@ -399,8 +394,7 @@ pub async fn connector_retrieve(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: Permission::MerchantConnectorAccountRead,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: Permission::ProfileConnectorRead,
             },
             req.headers(),
         ),
@@ -438,8 +432,7 @@ pub async fn connector_retrieve(
         auth::auth_type(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromHeader {
-                required_permission: Permission::MerchantConnectorAccountRead,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantConnectorRead,
             },
             req.headers(),
         ),
@@ -469,8 +462,7 @@ pub async fn connector_list(
         auth::auth_type(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromHeader {
-                required_permission: Permission::MerchantConnectorAccountRead,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantConnectorRead,
             },
             req.headers(),
         ),
@@ -517,8 +509,7 @@ pub async fn connector_list(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: Permission::MerchantConnectorAccountRead,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantConnectorRead,
             },
             req.headers(),
         ),
@@ -569,8 +560,7 @@ pub async fn connector_list_profile(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: Permission::MerchantConnectorAccountRead,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: Permission::ProfileConnectorRead,
             },
             req.headers(),
         ),
@@ -631,8 +621,7 @@ pub async fn connector_update(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id: merchant_id.clone(),
-                required_permission: Permission::MerchantConnectorAccountWrite,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: Permission::ProfileConnectorWrite,
             },
             req.headers(),
         ),
@@ -683,8 +672,7 @@ pub async fn connector_update(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id: merchant_id.clone(),
-                required_permission: Permission::MerchantConnectorAccountWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantConnectorWrite,
             },
             req.headers(),
         ),
@@ -739,8 +727,7 @@ pub async fn connector_delete(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: Permission::MerchantConnectorAccountWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantConnectorWrite,
             },
             req.headers(),
         ),
@@ -778,8 +765,7 @@ pub async fn connector_delete(
         auth::auth_type(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromHeader {
-                required_permission: Permission::MerchantConnectorAccountWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantConnectorWrite,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/routes/api_keys.rs b/crates/router/src/routes/api_keys.rs
index bbecaae9e80..1a2f60bcccb 100644
--- a/crates/router/src/routes/api_keys.rs
+++ b/crates/router/src/routes/api_keys.rs
@@ -1,5 +1,4 @@
 use actix_web::{web, HttpRequest, Responder};
-use common_enums::EntityType;
 use router_env::{instrument, tracing, Flow};
 
 use super::app::AppState;
@@ -33,8 +32,7 @@ pub async fn api_key_create(
             &auth::AdminApiAuthWithMerchantIdFromRoute(merchant_id.clone()),
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id: merchant_id.clone(),
-                required_permission: Permission::ApiKeyWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantApiKeyWrite,
             },
             req.headers(),
         ),
@@ -64,8 +62,7 @@ pub async fn api_key_create(
         auth::auth_type(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromHeader {
-                required_permission: Permission::ApiKeyWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantApiKeyWrite,
             },
             req.headers(),
         ),
@@ -99,8 +96,7 @@ pub async fn api_key_retrieve(
         auth::auth_type(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromHeader {
-                required_permission: Permission::ApiKeyRead,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantApiKeyRead,
             },
             req.headers(),
         ),
@@ -132,8 +128,7 @@ pub async fn api_key_retrieve(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id: merchant_id.clone(),
-                required_permission: Permission::ApiKeyRead,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantApiKeyRead,
             },
             req.headers(),
         ),
@@ -169,8 +164,7 @@ pub async fn api_key_update(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: Permission::ApiKeyWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantApiKeyWrite,
             },
             req.headers(),
         ),
@@ -203,8 +197,7 @@ pub async fn api_key_update(
         auth::auth_type(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromHeader {
-                required_permission: Permission::ApiKeyRead,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantApiKeyRead,
             },
             req.headers(),
         ),
@@ -236,8 +229,7 @@ pub async fn api_key_revoke(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id: merchant_id.clone(),
-                required_permission: Permission::ApiKeyWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantApiKeyWrite,
             },
             req.headers(),
         ),
@@ -269,8 +261,7 @@ pub async fn api_key_revoke(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id: merchant_id.clone(),
-                required_permission: Permission::ApiKeyWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantApiKeyWrite,
             },
             req.headers(),
         ),
@@ -305,8 +296,7 @@ pub async fn api_key_list(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: Permission::ApiKeyRead,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantApiKeyRead,
             },
             req.headers(),
         ),
@@ -336,8 +326,7 @@ pub async fn api_key_list(
         auth::auth_type(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromHeader {
-                required_permission: Permission::ApiKeyRead,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantApiKeyRead,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/routes/blocklist.rs b/crates/router/src/routes/blocklist.rs
index 4738df5ed2c..f54f61d8a00 100644
--- a/crates/router/src/routes/blocklist.rs
+++ b/crates/router/src/routes/blocklist.rs
@@ -1,6 +1,5 @@
 use actix_web::{web, HttpRequest, HttpResponse};
 use api_models::blocklist as api_blocklist;
-use common_enums::EntityType;
 use router_env::Flow;
 
 use crate::{
@@ -39,7 +38,6 @@ pub async fn add_entry_to_blocklist(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
                 permission: Permission::MerchantAccountWrite,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
@@ -78,7 +76,6 @@ pub async fn remove_entry_from_blocklist(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
                 permission: Permission::MerchantAccountWrite,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
@@ -119,7 +116,6 @@ pub async fn list_blocked_payment_methods(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
                 permission: Permission::MerchantAccountRead,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
@@ -160,7 +156,6 @@ pub async fn toggle_blocklist_guard(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
                 permission: Permission::MerchantAccountWrite,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/routes/connector_onboarding.rs b/crates/router/src/routes/connector_onboarding.rs
index f7494e182c1..8ecd321df94 100644
--- a/crates/router/src/routes/connector_onboarding.rs
+++ b/crates/router/src/routes/connector_onboarding.rs
@@ -1,6 +1,5 @@
 use actix_web::{web, HttpRequest, HttpResponse};
 use api_models::connector_onboarding as api_types;
-use common_enums::EntityType;
 use router_env::Flow;
 
 use super::AppState;
@@ -24,7 +23,6 @@ pub async fn get_action_url(
         core::get_action_url,
         &auth::JWTAuth {
             permission: Permission::MerchantAccountWrite,
-            minimum_entity_level: EntityType::Merchant,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -46,7 +44,6 @@ pub async fn sync_onboarding_status(
         core::sync_onboarding_status,
         &auth::JWTAuth {
             permission: Permission::MerchantAccountWrite,
-            minimum_entity_level: EntityType::Merchant,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -68,7 +65,6 @@ pub async fn reset_tracking_id(
         core::reset_tracking_id,
         &auth::JWTAuth {
             permission: Permission::MerchantAccountWrite,
-            minimum_entity_level: EntityType::Merchant,
         },
         api_locking::LockAction::NotApplicable,
     ))
diff --git a/crates/router/src/routes/customers.rs b/crates/router/src/routes/customers.rs
index 536bca10f3d..5ff155966a0 100644
--- a/crates/router/src/routes/customers.rs
+++ b/crates/router/src/routes/customers.rs
@@ -1,5 +1,4 @@
 use actix_web::{web, HttpRequest, HttpResponse, Responder};
-use common_enums::EntityType;
 #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
 use common_utils::id_type;
 use router_env::{instrument, tracing, Flow};
@@ -29,8 +28,7 @@ pub async fn customers_create(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::CustomerWrite,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantCustomerWrite,
             },
             req.headers(),
         ),
@@ -55,8 +53,7 @@ pub async fn customers_retrieve(
 
     let auth = if auth::is_jwt_auth(req.headers()) {
         Box::new(auth::JWTAuth {
-            permission: Permission::CustomerRead,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantCustomerRead,
         })
     } else {
         match auth::is_ephemeral_auth(req.headers()) {
@@ -98,8 +95,7 @@ pub async fn customers_retrieve(
 
     let auth = if auth::is_jwt_auth(req.headers()) {
         Box::new(auth::JWTAuth {
-            permission: Permission::CustomerRead,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantCustomerRead,
         })
     } else {
         match auth::is_ephemeral_auth(req.headers()) {
@@ -148,8 +144,7 @@ pub async fn customers_list(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::CustomerRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantCustomerRead,
             },
             req.headers(),
         ),
@@ -187,8 +182,7 @@ pub async fn customers_update(
         auth::auth_type(
             &auth::ApiKeyAuth,
             &auth::JWTAuth {
-                permission: Permission::CustomerWrite,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantCustomerWrite,
             },
             req.headers(),
         ),
@@ -225,8 +219,7 @@ pub async fn customers_update(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::CustomerWrite,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantCustomerWrite,
             },
             req.headers(),
         ),
@@ -256,8 +249,7 @@ pub async fn customers_delete(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::CustomerWrite,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantCustomerWrite,
             },
             req.headers(),
         ),
@@ -290,8 +282,7 @@ pub async fn customers_delete(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::CustomerWrite,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantCustomerWrite,
             },
             req.headers(),
         ),
@@ -328,8 +319,7 @@ pub async fn get_customer_mandates(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::MandateRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantMandateRead,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/routes/disputes.rs b/crates/router/src/routes/disputes.rs
index 22c1e3f1988..5577bb96ef0 100644
--- a/crates/router/src/routes/disputes.rs
+++ b/crates/router/src/routes/disputes.rs
@@ -1,7 +1,6 @@
 use actix_multipart::Multipart;
 use actix_web::{web, HttpRequest, HttpResponse};
 use api_models::disputes as dispute_models;
-use common_enums::EntityType;
 use router_env::{instrument, tracing, Flow};
 
 use crate::{core::api_locking, services::authorization::permissions::Permission};
@@ -50,8 +49,7 @@ pub async fn retrieve_dispute(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileDisputeRead,
             },
             req.headers(),
         ),
@@ -102,8 +100,7 @@ pub async fn retrieve_disputes_list(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantDisputeRead,
             },
             req.headers(),
         ),
@@ -160,8 +157,7 @@ pub async fn retrieve_disputes_list_profile(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileDisputeRead,
             },
             req.headers(),
         ),
@@ -195,8 +191,7 @@ pub async fn get_disputes_filters(state: web::Data<AppState>, req: HttpRequest)
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantDisputeRead,
             },
             req.headers(),
         ),
@@ -237,8 +232,7 @@ pub async fn get_disputes_filters_profile(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileDisputeRead,
             },
             req.headers(),
         ),
@@ -289,8 +283,7 @@ pub async fn accept_dispute(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeWrite,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileDisputeWrite,
             },
             req.headers(),
         ),
@@ -335,8 +328,7 @@ pub async fn submit_dispute_evidence(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeWrite,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileDisputeWrite,
             },
             req.headers(),
         ),
@@ -389,8 +381,7 @@ pub async fn attach_dispute_evidence(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeWrite,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileDisputeWrite,
             },
             req.headers(),
         ),
@@ -435,8 +426,7 @@ pub async fn retrieve_dispute_evidence(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileDisputeRead,
             },
             req.headers(),
         ),
@@ -478,8 +468,7 @@ pub async fn delete_dispute_evidence(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeWrite,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileDisputeWrite,
             },
             req.headers(),
         ),
@@ -508,8 +497,7 @@ pub async fn get_disputes_aggregate(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantDisputeRead,
             },
             req.headers(),
         ),
@@ -543,8 +531,7 @@ pub async fn get_disputes_aggregate_profile(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::DisputeRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileDisputeRead,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/routes/mandates.rs b/crates/router/src/routes/mandates.rs
index c0ccbfa9f8f..cb832d81a16 100644
--- a/crates/router/src/routes/mandates.rs
+++ b/crates/router/src/routes/mandates.rs
@@ -1,5 +1,4 @@
 use actix_web::{web, HttpRequest, HttpResponse};
-use common_enums::EntityType;
 use router_env::{instrument, tracing, Flow};
 
 use super::app::AppState;
@@ -117,8 +116,7 @@ pub async fn retrieve_mandates_list(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::MandateRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantMandateRead,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/routes/payment_methods.rs b/crates/router/src/routes/payment_methods.rs
index 8d95ee64ad0..0dbddbef77b 100644
--- a/crates/router/src/routes/payment_methods.rs
+++ b/crates/router/src/routes/payment_methods.rs
@@ -4,7 +4,6 @@
 ))]
 use actix_multipart::form::MultipartForm;
 use actix_web::{web, HttpRequest, HttpResponse};
-use common_enums::EntityType;
 use common_utils::{errors::CustomResult, id_type};
 use diesel_models::enums::IntentStatus;
 use error_stack::ResultExt;
@@ -881,15 +880,13 @@ pub async fn list_countries_currencies_for_connector_payment_method(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::MerchantConnectorAccountWrite,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileConnectorWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::MerchantConnectorAccountWrite,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileConnectorWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs
index f13a873473a..bca7bd37ccc 100644
--- a/crates/router/src/routes/payments.rs
+++ b/crates/router/src/routes/payments.rs
@@ -5,7 +5,6 @@ use crate::{
 pub mod helpers;
 
 use actix_web::{web, Responder};
-use common_enums::EntityType;
 use error_stack::report;
 use hyperswitch_domain_models::payments::HeaderPayload;
 use masking::PeekInterface;
@@ -93,8 +92,7 @@ pub async fn payments_create(
             _ => auth::auth_type(
                 &auth::HeaderAuth(auth::ApiKeyAuth),
                 &auth::JWTAuth {
-                    permission: Permission::PaymentWrite,
-                    minimum_entity_level: EntityType::Profile,
+                    permission: Permission::ProfilePaymentWrite,
                 },
                 req.headers(),
             ),
@@ -148,8 +146,7 @@ pub async fn payments_create_intent(
             _ => auth::auth_type(
                 &auth::HeaderAuth(auth::ApiKeyAuth),
                 &auth::JWTAuth {
-                    permission: Permission::PaymentWrite,
-                    minimum_entity_level: EntityType::Profile,
+                    permission: Permission::ProfilePaymentWrite,
                 },
                 req.headers(),
             ),
@@ -285,8 +282,7 @@ pub async fn payments_retrieve(
         auth::auth_type(
             &*auth_type,
             &auth::JWTAuth {
-                permission: Permission::PaymentRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfilePaymentRead,
             },
             req.headers(),
         ),
@@ -995,8 +991,7 @@ pub async fn payments_list(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::PaymentRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantPaymentRead,
             },
             req.headers(),
         ),
@@ -1031,8 +1026,7 @@ pub async fn profile_payments_list(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::PaymentRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfilePaymentRead,
             },
             req.headers(),
         ),
@@ -1065,8 +1059,7 @@ pub async fn payments_list_by_filter(
             )
         },
         &auth::JWTAuth {
-            permission: Permission::PaymentRead,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantPaymentRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -1097,8 +1090,7 @@ pub async fn profile_payments_list_by_filter(
             )
         },
         &auth::JWTAuth {
-            permission: Permission::PaymentRead,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfilePaymentRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -1123,8 +1115,7 @@ pub async fn get_filters_for_payments(
             payments::get_filters_for_payments(state, auth.merchant_account, auth.key_store, req)
         },
         &auth::JWTAuth {
-            permission: Permission::PaymentRead,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantPaymentRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -1147,8 +1138,7 @@ pub async fn get_payment_filters(
             payments::get_payment_filters(state, auth.merchant_account, None)
         },
         &auth::JWTAuth {
-            permission: Permission::PaymentRead,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantPaymentRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -1175,8 +1165,7 @@ pub async fn get_payment_filters_profile(
             )
         },
         &auth::JWTAuth {
-            permission: Permission::PaymentRead,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfilePaymentRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -1201,8 +1190,7 @@ pub async fn get_payments_aggregates(
             payments::get_aggregates_for_payments(state, auth.merchant_account, None, req)
         },
         &auth::JWTAuth {
-            permission: Permission::PaymentRead,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantPaymentRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -1262,8 +1250,7 @@ pub async fn payments_approve(
             _ => auth::auth_type(
                 &auth::HeaderAuth(auth::ApiKeyAuth),
                 &auth::JWTAuth {
-                    permission: Permission::PaymentWrite,
-                    minimum_entity_level: EntityType::Profile,
+                    permission: Permission::ProfilePaymentWrite,
                 },
                 http_req.headers(),
             ),
@@ -1327,8 +1314,7 @@ pub async fn payments_reject(
             _ => auth::auth_type(
                 &auth::HeaderAuth(auth::ApiKeyAuth),
                 &auth::JWTAuth {
-                    permission: Permission::PaymentWrite,
-                    minimum_entity_level: EntityType::Profile,
+                    permission: Permission::ProfilePaymentWrite,
                 },
                 http_req.headers(),
             ),
@@ -1970,8 +1956,7 @@ pub async fn get_payments_aggregates_profile(
             )
         },
         &auth::JWTAuth {
-            permission: Permission::PaymentRead,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfilePaymentRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
diff --git a/crates/router/src/routes/payouts.rs b/crates/router/src/routes/payouts.rs
index ad860195a2a..62d16c4c4d5 100644
--- a/crates/router/src/routes/payouts.rs
+++ b/crates/router/src/routes/payouts.rs
@@ -3,7 +3,6 @@ use actix_web::{
     http::header::HeaderMap,
     web, HttpRequest, HttpResponse, Responder,
 };
-use common_enums::EntityType;
 use common_utils::consts;
 use router_env::{instrument, tracing, Flow};
 
@@ -84,8 +83,7 @@ pub async fn payouts_retrieve(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::PayoutRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfilePayoutRead,
             },
             req.headers(),
         ),
@@ -237,8 +235,7 @@ pub async fn payouts_list(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::PayoutRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantPayoutRead,
             },
             req.headers(),
         ),
@@ -277,8 +274,7 @@ pub async fn payouts_list_profile(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::PayoutRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfilePayoutRead,
             },
             req.headers(),
         ),
@@ -317,8 +313,7 @@ pub async fn payouts_list_by_filter(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::PayoutRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantPayoutRead,
             },
             req.headers(),
         ),
@@ -357,8 +352,7 @@ pub async fn payouts_list_by_filter_profile(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::PayoutRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfilePayoutRead,
             },
             req.headers(),
         ),
@@ -390,8 +384,7 @@ pub async fn payouts_list_available_filters_for_merchant(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::PayoutRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantPayoutRead,
             },
             req.headers(),
         ),
@@ -429,8 +422,7 @@ pub async fn payouts_list_available_filters_for_profile(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::PayoutRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfilePayoutRead,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/routes/profiles.rs b/crates/router/src/routes/profiles.rs
index f2dc322af17..cbb7957987f 100644
--- a/crates/router/src/routes/profiles.rs
+++ b/crates/router/src/routes/profiles.rs
@@ -1,5 +1,4 @@
 use actix_web::{web, HttpRequest, HttpResponse};
-use common_enums::EntityType;
 use router_env::{instrument, tracing, Flow};
 
 use super::app::AppState;
@@ -34,7 +33,6 @@ pub async fn profile_create(
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
                 required_permission: permissions::Permission::MerchantAccountWrite,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
@@ -65,7 +63,6 @@ pub async fn profile_create(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromHeader {
                 required_permission: permissions::Permission::MerchantAccountWrite,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
@@ -97,8 +94,7 @@ pub async fn profile_retrieve(
             &auth::AdminApiAuthWithMerchantIdFromRoute(merchant_id.clone()),
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id: merchant_id.clone(),
-                required_permission: permissions::Permission::MerchantAccountRead,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: permissions::Permission::ProfileAccountRead,
             },
             req.headers(),
         ),
@@ -127,7 +123,6 @@ pub async fn profile_retrieve(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromHeader {
                 required_permission: permissions::Permission::MerchantAccountRead,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
@@ -161,8 +156,7 @@ pub async fn profile_update(
             &auth::JWTAuthMerchantAndProfileFromRoute {
                 merchant_id: merchant_id.clone(),
                 profile_id: profile_id.clone(),
-                required_permission: permissions::Permission::MerchantAccountWrite,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: permissions::Permission::ProfileAccountWrite,
             },
             req.headers(),
         ),
@@ -192,7 +186,6 @@ pub async fn profile_update(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromHeader {
                 required_permission: permissions::Permission::MerchantAccountWrite,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
@@ -244,7 +237,6 @@ pub async fn profiles_list(
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
                 required_permission: permissions::Permission::MerchantAccountRead,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
@@ -278,8 +270,7 @@ pub async fn profiles_list_at_profile_level(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: permissions::Permission::MerchantAccountRead,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: permissions::Permission::ProfileAccountRead,
             },
             req.headers(),
         ),
@@ -312,8 +303,7 @@ pub async fn toggle_connector_agnostic_mit(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: permissions::Permission::RoutingWrite,
-                minimum_entity_level: EntityType::Merchant,
+                permission: permissions::Permission::MerchantRoutingWrite,
             },
             req.headers(),
         ),
@@ -372,8 +362,7 @@ pub async fn payment_connector_list_profile(
             &auth::AdminApiAuthWithMerchantIdFromHeader,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: permissions::Permission::MerchantConnectorAccountRead,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: permissions::Permission::ProfileConnectorRead,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/routes/recon.rs b/crates/router/src/routes/recon.rs
index 1ec571ff7c9..cdc2ae758e9 100644
--- a/crates/router/src/routes/recon.rs
+++ b/crates/router/src/routes/recon.rs
@@ -1,5 +1,5 @@
 use actix_web::{web, HttpRequest, HttpResponse};
-use api_models::{enums::EntityType, recon as recon_api};
+use api_models::recon as recon_api;
 use router_env::Flow;
 
 use super::AppState;
@@ -38,8 +38,7 @@ pub async fn request_for_recon(state: web::Data<AppState>, http_req: HttpRequest
         (),
         |state, user, _, _| recon::send_recon_request(state, user),
         &authentication::JWTAuth {
-            permission: Permission::ReconAdmin,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantReconWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -55,8 +54,7 @@ pub async fn get_recon_token(state: web::Data<AppState>, req: HttpRequest) -> Ht
         (),
         |state, user, _, _| recon::generate_recon_token(state, user),
         &authentication::JWTAuth {
-            permission: Permission::ReconAdmin,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantReconWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
diff --git a/crates/router/src/routes/refunds.rs b/crates/router/src/routes/refunds.rs
index c76ee600efe..cbcfbcdcbf1 100644
--- a/crates/router/src/routes/refunds.rs
+++ b/crates/router/src/routes/refunds.rs
@@ -1,5 +1,4 @@
 use actix_web::{web, HttpRequest, HttpResponse};
-use common_enums::EntityType;
 use router_env::{instrument, tracing, Flow};
 
 use super::app::AppState;
@@ -49,8 +48,7 @@ pub async fn refunds_create(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RefundWrite,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRefundWrite,
             },
             req.headers(),
         ),
@@ -113,8 +111,7 @@ pub async fn refunds_retrieve(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RefundRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRefundRead,
             },
             req.headers(),
         ),
@@ -245,8 +242,7 @@ pub async fn refunds_list(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RefundRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantRefundRead,
             },
             req.headers(),
         ),
@@ -293,8 +289,7 @@ pub async fn refunds_list_profile(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RefundRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRefundRead,
             },
             req.headers(),
         ),
@@ -336,8 +331,7 @@ pub async fn refunds_filter_list(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RefundRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantRefundRead,
             },
             req.headers(),
         ),
@@ -374,8 +368,7 @@ pub async fn get_refunds_filters(state: web::Data<AppState>, req: HttpRequest) -
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RefundRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantRefundRead,
             },
             req.headers(),
         ),
@@ -419,8 +412,7 @@ pub async fn get_refunds_filters_profile(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RefundRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRefundRead,
             },
             req.headers(),
         ),
@@ -449,8 +441,7 @@ pub async fn get_refunds_aggregates(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RefundRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantRefundRead,
             },
             req.headers(),
         ),
@@ -507,8 +498,7 @@ pub async fn get_refunds_aggregate_profile(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RefundRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRefundRead,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/routes/routing.rs b/crates/router/src/routes/routing.rs
index 4c8d89fa87d..3e0355a884a 100644
--- a/crates/router/src/routes/routing.rs
+++ b/crates/router/src/routes/routing.rs
@@ -5,7 +5,6 @@
 
 use actix_web::{web, HttpRequest, Responder};
 use api_models::{enums, routing as routing_types, routing::RoutingRetrieveQuery};
-use common_enums::EntityType;
 use router_env::{
     tracing::{self, instrument},
     Flow,
@@ -44,15 +43,13 @@ pub async fn routing_create_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RoutingWrite,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRoutingWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::RoutingWrite,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileRoutingWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -87,15 +84,13 @@ pub async fn routing_link_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RoutingWrite,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRoutingWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::RoutingWrite,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileRoutingWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -137,16 +132,14 @@ pub async fn routing_link_config(
             &auth::ApiKeyAuth,
             &auth::JWTAuthProfileFromRoute {
                 profile_id: wrapper.profile_id,
-                required_permission: Permission::RoutingWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantRoutingWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuthProfileFromRoute {
             profile_id: wrapper.profile_id,
-            required_permission: Permission::RoutingWrite,
-            minimum_entity_level: EntityType::Merchant,
+            required_permission: Permission::MerchantRoutingWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -180,15 +173,13 @@ pub async fn routing_retrieve_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RoutingRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRoutingRead,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::RoutingRead,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileRoutingRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -222,15 +213,13 @@ pub async fn list_routing_configs(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RoutingRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantRoutingRead,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::RoutingRead,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantRoutingRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -264,15 +253,13 @@ pub async fn list_routing_configs_for_profile(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RoutingRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRoutingRead,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::RoutingRead,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileRoutingRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -308,16 +295,14 @@ pub async fn routing_unlink_config(
             &auth::ApiKeyAuth,
             &auth::JWTAuthProfileFromRoute {
                 profile_id: path,
-                required_permission: Permission::RoutingWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantRoutingWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuthProfileFromRoute {
             profile_id: path,
-            required_permission: Permission::RoutingWrite,
-            minimum_entity_level: EntityType::Merchant,
+            required_permission: Permission::MerchantRoutingWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -352,15 +337,13 @@ pub async fn routing_unlink_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RoutingWrite,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRoutingWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::RoutingWrite,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileRoutingWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -397,15 +380,13 @@ pub async fn routing_update_default_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RoutingWrite,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantRoutingWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::RoutingWrite,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantRoutingWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -437,15 +418,13 @@ pub async fn routing_update_default_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RoutingWrite,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantRoutingWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::RoutingWrite,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantRoutingWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -478,16 +457,14 @@ pub async fn routing_retrieve_default_config(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuthProfileFromRoute {
                 profile_id: path,
-                required_permission: Permission::RoutingRead,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantRoutingRead,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuthProfileFromRoute {
             profile_id: path,
-            required_permission: Permission::RoutingRead,
-            minimum_entity_level: EntityType::Merchant,
+            required_permission: Permission::MerchantRoutingRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -513,15 +490,13 @@ pub async fn routing_retrieve_default_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RoutingRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRoutingRead,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::RoutingRead,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileRoutingRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -553,15 +528,13 @@ pub async fn upsert_surcharge_decision_manager_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::SurchargeDecisionManagerWrite,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantSurchargeDecisionManagerWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::SurchargeDecisionManagerWrite,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantSurchargeDecisionManagerWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -590,15 +563,13 @@ pub async fn delete_surcharge_decision_manager_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::SurchargeDecisionManagerWrite,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantSurchargeDecisionManagerWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::SurchargeDecisionManagerWrite,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantSurchargeDecisionManagerWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -627,15 +598,13 @@ pub async fn retrieve_surcharge_decision_manager_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::SurchargeDecisionManagerRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantSurchargeDecisionManagerRead,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::SurchargeDecisionManagerRead,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantSurchargeDecisionManagerRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -667,15 +636,13 @@ pub async fn upsert_decision_manager_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::SurchargeDecisionManagerRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantThreeDsDecisionManagerWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::SurchargeDecisionManagerRead,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantThreeDsDecisionManagerWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -705,15 +672,13 @@ pub async fn delete_decision_manager_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::SurchargeDecisionManagerWrite,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantThreeDsDecisionManagerWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::SurchargeDecisionManagerWrite,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantThreeDsDecisionManagerWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -739,15 +704,13 @@ pub async fn retrieve_decision_manager_config(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::SurchargeDecisionManagerRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantThreeDsDecisionManagerRead,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuth {
-            permission: Permission::SurchargeDecisionManagerRead,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantThreeDsDecisionManagerRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -786,16 +749,14 @@ pub async fn routing_retrieve_linked_config(
                 &auth::HeaderAuth(auth::ApiKeyAuth),
                 &auth::JWTAuthProfileFromRoute {
                     profile_id,
-                    required_permission: Permission::RoutingRead,
-                    minimum_entity_level: EntityType::Profile,
+                    required_permission: Permission::ProfileRoutingRead,
                 },
                 req.headers(),
             ),
             #[cfg(feature = "release")]
             &auth::JWTAuthProfileFromRoute {
                 profile_id,
-                required_permission: Permission::RoutingRead,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: Permission::ProfileRoutingRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -820,15 +781,13 @@ pub async fn routing_retrieve_linked_config(
             auth::auth_type(
                 &auth::HeaderAuth(auth::ApiKeyAuth),
                 &auth::JWTAuth {
-                    permission: Permission::RoutingRead,
-                    minimum_entity_level: EntityType::Profile,
+                    permission: Permission::ProfileRoutingRead,
                 },
                 req.headers(),
             ),
             #[cfg(feature = "release")]
             &auth::JWTAuth {
-                permission: Permission::RoutingRead,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileRoutingRead,
             },
             api_locking::LockAction::NotApplicable,
         ))
@@ -871,16 +830,14 @@ pub async fn routing_retrieve_linked_config(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuthProfileFromRoute {
                 profile_id: wrapper.profile_id,
-                required_permission: Permission::RoutingRead,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: Permission::ProfileRoutingRead,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuthProfileFromRoute {
             profile_id: wrapper.profile_id,
-            required_permission: Permission::RoutingRead,
-            minimum_entity_level: EntityType::Profile,
+            required_permission: Permission::ProfileRoutingRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -911,8 +868,7 @@ pub async fn routing_retrieve_default_config_for_profiles(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RoutingRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantRoutingRead,
             },
             req.headers(),
         ),
@@ -920,8 +876,7 @@ pub async fn routing_retrieve_default_config_for_profiles(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::RoutingRead,
-                minimum_entity_level: EntityType::Merchant,
+                permission: Permission::MerchantRoutingRead,
             },
             req.headers(),
         ),
@@ -963,16 +918,14 @@ pub async fn routing_update_default_config_for_profile(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuthProfileFromRoute {
                 profile_id: routing_payload_wrapper.profile_id,
-                required_permission: Permission::RoutingWrite,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: Permission::ProfileRoutingWrite,
             },
             req.headers(),
         ),
         #[cfg(feature = "release")]
         &auth::JWTAuthProfileFromRoute {
             profile_id: routing_payload_wrapper.profile_id,
-            required_permission: Permission::RoutingWrite,
-            minimum_entity_level: EntityType::Profile,
+            required_permission: Permission::ProfileRoutingWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -1013,8 +966,7 @@ pub async fn toggle_success_based_routing(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuthProfileFromRoute {
                 profile_id: wrapper.profile_id,
-                required_permission: Permission::RoutingWrite,
-                minimum_entity_level: EntityType::Profile,
+                required_permission: Permission::ProfileRoutingWrite,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/routes/user.rs b/crates/router/src/routes/user.rs
index e07a2fa10ef..f52d0dca7a8 100644
--- a/crates/router/src/routes/user.rs
+++ b/crates/router/src/routes/user.rs
@@ -5,7 +5,7 @@ use api_models::{
     errors::types::ApiErrorResponse,
     user::{self as user_api},
 };
-use common_enums::{EntityType, TokenPurpose};
+use common_enums::TokenPurpose;
 use common_utils::errors::ReportSwitchExt;
 use router_env::Flow;
 
@@ -176,8 +176,7 @@ pub async fn set_dashboard_metadata(
         payload,
         user_core::dashboard_metadata::set_metadata,
         &auth::JWTAuth {
-            permission: Permission::MerchantAccountWrite,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileAccountWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -243,8 +242,7 @@ pub async fn user_merchant_account_create(
             user_core::create_merchant_account(state, auth, json_payload)
         },
         &auth::JWTAuth {
-            permission: Permission::MerchantAccountCreate,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::OrganizationAccountWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -267,8 +265,7 @@ pub async fn generate_sample_data(
         payload.into_inner(),
         sample_data::generate_sample_data_for_user,
         &auth::JWTAuth {
-            permission: Permission::PaymentWrite,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantPaymentWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -292,7 +289,6 @@ pub async fn delete_sample_data(
         sample_data::delete_sample_data_for_user,
         &auth::JWTAuth {
             permission: Permission::MerchantAccountWrite,
-            minimum_entity_level: EntityType::Merchant,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -312,8 +308,7 @@ pub async fn list_user_roles_details(
         payload.into_inner(),
         user_core::list_user_roles_details,
         &auth::JWTAuth {
-            permission: Permission::UsersRead,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileUserRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -395,8 +390,7 @@ pub async fn invite_multiple_user(
             user_core::invite_multiple_user(state, user, payload, req_state, auth_id.clone())
         },
         &auth::JWTAuth {
-            permission: Permission::UsersWrite,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileUserWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -421,8 +415,7 @@ pub async fn resend_invite(
             user_core::resend_invite(state, user, req_payload, auth_id.clone())
         },
         &auth::JWTAuth {
-            permission: Permission::UsersWrite,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileUserWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -504,8 +497,7 @@ pub async fn verify_recon_token(state: web::Data<AppState>, http_req: HttpReques
         (),
         |state, user, _req, _| user_core::verify_token(state, user),
         &auth::JWTAuth {
-            permission: Permission::ReconAdmin,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantReconWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
diff --git a/crates/router/src/routes/user_role.rs b/crates/router/src/routes/user_role.rs
index 777cbe1fd95..74847f06474 100644
--- a/crates/router/src/routes/user_role.rs
+++ b/crates/router/src/routes/user_role.rs
@@ -1,6 +1,6 @@
 use actix_web::{web, HttpRequest, HttpResponse};
 use api_models::user_role::{self as user_role_api, role as role_api};
-use common_enums::{EntityType, TokenPurpose};
+use common_enums::TokenPurpose;
 use router_env::Flow;
 
 use super::AppState;
@@ -31,8 +31,7 @@ pub async fn get_authorization_info(
             user_role_core::get_authorization_info_with_groups(state).await
         },
         &auth::JWTAuth {
-            permission: Permission::UsersRead,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantUserRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -69,8 +68,7 @@ pub async fn create_role(
         json_payload.into_inner(),
         role_core::create_role,
         &auth::JWTAuth {
-            permission: Permission::UsersWrite,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantUserWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -95,8 +93,7 @@ pub async fn get_role(
             role_core::get_role_with_groups(state, user, payload).await
         },
         &auth::JWTAuth {
-            permission: Permission::UsersRead,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileUserRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -119,8 +116,7 @@ pub async fn update_role(
         json_payload.into_inner(),
         |state, user, req, _| role_core::update_role(state, user, req, &role_id),
         &auth::JWTAuth {
-            permission: Permission::UsersWrite,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantUserWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -141,8 +137,7 @@ pub async fn update_user_role(
         payload,
         user_role_core::update_user_role,
         &auth::JWTAuth {
-            permission: Permission::UsersWrite,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileUserWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -202,8 +197,7 @@ pub async fn delete_user_role(
         payload.into_inner(),
         user_role_core::delete_user_role,
         &auth::JWTAuth {
-            permission: Permission::UsersWrite,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileUserWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -225,8 +219,7 @@ pub async fn get_role_information(
             user_role_core::get_authorization_info_with_group_tag().await
         },
         &auth::JWTAuth {
-            permission: Permission::UsersRead,
-            minimum_entity_level: EntityType::Profile
+            permission: Permission::ProfileUserRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -270,8 +263,7 @@ pub async fn list_roles_with_info(
             role_core::list_roles_with_info(state, user_from_token, request)
         },
         &auth::JWTAuth {
-            permission: Permission::UsersRead,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileUserRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -299,8 +291,7 @@ pub async fn list_invitable_roles_at_entity_level(
             )
         },
         &auth::JWTAuth {
-            permission: Permission::UsersRead,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileUserRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
@@ -328,8 +319,7 @@ pub async fn list_updatable_roles_at_entity_level(
             )
         },
         &auth::JWTAuth {
-            permission: Permission::UsersRead,
-            minimum_entity_level: EntityType::Profile,
+            permission: Permission::ProfileUserRead,
         },
         api_locking::LockAction::NotApplicable,
     ))
diff --git a/crates/router/src/routes/verification.rs b/crates/router/src/routes/verification.rs
index 17c946c4810..56ad42947c2 100644
--- a/crates/router/src/routes/verification.rs
+++ b/crates/router/src/routes/verification.rs
@@ -1,6 +1,5 @@
 use actix_web::{web, HttpRequest, Responder};
 use api_models::verifications;
-use common_enums::EntityType;
 use router_env::{instrument, tracing, Flow};
 
 use super::app::AppState;
@@ -34,8 +33,7 @@ pub async fn apple_pay_merchant_registration(
         auth::auth_type(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
-                permission: Permission::MerchantAccountWrite,
-                minimum_entity_level: EntityType::Profile,
+                permission: Permission::ProfileAccountWrite,
             },
             req.headers(),
         ),
@@ -70,7 +68,6 @@ pub async fn retrieve_apple_pay_verified_domains(
             &auth::HeaderAuth(auth::ApiKeyAuth),
             &auth::JWTAuth {
                 permission: Permission::MerchantAccountRead,
-                minimum_entity_level: EntityType::Merchant,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/routes/verify_connector.rs b/crates/router/src/routes/verify_connector.rs
index 29f8c154bc0..b8e089f0660 100644
--- a/crates/router/src/routes/verify_connector.rs
+++ b/crates/router/src/routes/verify_connector.rs
@@ -1,6 +1,5 @@
 use actix_web::{web, HttpRequest, HttpResponse};
 use api_models::verify_connector::VerifyConnectorRequest;
-use common_enums::EntityType;
 use router_env::{instrument, tracing, Flow};
 
 use super::AppState;
@@ -25,8 +24,7 @@ pub async fn payment_connector_verify(
             verify_connector::verify_connector_credentials(state, req, auth.profile_id)
         },
         &auth::JWTAuth {
-            permission: Permission::MerchantConnectorAccountWrite,
-            minimum_entity_level: EntityType::Merchant,
+            permission: Permission::MerchantConnectorWrite,
         },
         api_locking::LockAction::NotApplicable,
     ))
diff --git a/crates/router/src/routes/webhook_events.rs b/crates/router/src/routes/webhook_events.rs
index 8b94fb61f56..5039f72db31 100644
--- a/crates/router/src/routes/webhook_events.rs
+++ b/crates/router/src/routes/webhook_events.rs
@@ -1,5 +1,4 @@
 use actix_web::{web, HttpRequest, Responder};
-use common_enums::EntityType;
 use router_env::{instrument, tracing, Flow};
 
 use crate::{
@@ -44,8 +43,7 @@ pub async fn list_initial_webhook_delivery_attempts(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: Permission::WebhookEventRead,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantWebhookEventRead,
             },
             req.headers(),
         ),
@@ -84,8 +82,7 @@ pub async fn list_webhook_delivery_attempts(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: Permission::WebhookEventRead,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantWebhookEventRead,
             },
             req.headers(),
         ),
@@ -124,8 +121,7 @@ pub async fn retry_webhook_delivery_attempt(
             &auth::AdminApiAuth,
             &auth::JWTAuthMerchantFromRoute {
                 merchant_id,
-                required_permission: Permission::WebhookEventWrite,
-                minimum_entity_level: EntityType::Merchant,
+                required_permission: Permission::MerchantWebhookEventWrite,
             },
             req.headers(),
         ),
diff --git a/crates/router/src/services/authentication.rs b/crates/router/src/services/authentication.rs
index b64c5d14f32..e6da2b23301 100644
--- a/crates/router/src/services/authentication.rs
+++ b/crates/router/src/services/authentication.rs
@@ -10,7 +10,7 @@ use api_models::payment_methods::PaymentMethodIntentConfirm;
 use api_models::payouts;
 use api_models::{payment_methods::PaymentMethodListRequest, payments};
 use async_trait::async_trait;
-use common_enums::{EntityType, TokenPurpose};
+use common_enums::TokenPurpose;
 use common_utils::{date_time, id_type};
 use error_stack::{report, ResultExt};
 use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
@@ -1232,7 +1232,6 @@ where
 #[derive(Debug)]
 pub(crate) struct JWTAuth {
     pub permission: Permission,
-    pub minimum_entity_level: EntityType,
 }
 
 #[async_trait]
@@ -1252,7 +1251,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         Ok((
             (),
@@ -1282,7 +1280,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         Ok((
             UserFromToken {
@@ -1318,7 +1315,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         let key_manager_state = &(&state.session_state()).into();
         let key_store = state
@@ -1359,7 +1355,6 @@ where
 pub struct JWTAuthOrganizationFromRoute {
     pub organization_id: id_type::OrganizationId,
     pub required_permission: Permission,
-    pub minimum_entity_level: EntityType,
 }
 
 #[async_trait]
@@ -1379,7 +1374,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.required_permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         // Check if token has access to Organization that has been requested in the route
         if payload.org_id != self.organization_id {
@@ -1398,12 +1392,10 @@ where
 pub struct JWTAuthMerchantFromRoute {
     pub merchant_id: id_type::MerchantId,
     pub required_permission: Permission,
-    pub minimum_entity_level: EntityType,
 }
 
 pub struct JWTAuthMerchantFromHeader {
     pub required_permission: Permission,
-    pub minimum_entity_level: EntityType,
 }
 
 #[async_trait]
@@ -1423,7 +1415,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.required_permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         let merchant_id_from_header = HeaderMapStruct::new(request_headers)
             .get_id_type_from_header::<id_type::MerchantId>(headers::X_MERCHANT_ID)?;
@@ -1459,7 +1450,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.required_permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         let merchant_id_from_header = HeaderMapStruct::new(request_headers)
             .get_id_type_from_header::<id_type::MerchantId>(headers::X_MERCHANT_ID)?;
@@ -1526,7 +1516,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.required_permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         // Check if token has access to MerchantId that has been requested through query param
         if payload.merchant_id != self.merchant_id {
@@ -1563,7 +1552,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.required_permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         let key_manager_state = &(&state.session_state()).into();
         let key_store = state
@@ -1606,7 +1594,6 @@ pub struct JWTAuthMerchantAndProfileFromRoute {
     pub merchant_id: id_type::MerchantId,
     pub profile_id: id_type::ProfileId,
     pub required_permission: Permission,
-    pub minimum_entity_level: EntityType,
 }
 
 #[async_trait]
@@ -1638,7 +1625,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.required_permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         let key_manager_state = &(&state.session_state()).into();
         let key_store = state
@@ -1682,7 +1668,6 @@ where
 pub struct JWTAuthProfileFromRoute {
     pub profile_id: id_type::ProfileId,
     pub required_permission: Permission,
-    pub minimum_entity_level: EntityType,
 }
 
 #[async_trait]
@@ -1702,7 +1687,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.required_permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         let key_manager_state = &(&state.session_state()).into();
         let key_store = state
@@ -1798,7 +1782,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         let key_manager_state = &(&state.session_state()).into();
         let key_store = state
@@ -1859,7 +1842,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         let key_manager_state = &(&state.session_state()).into();
         let key_store = state
@@ -1923,7 +1905,6 @@ where
 
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         let key_manager_state = &(&state.session_state()).into();
         let key_store = state
@@ -2349,7 +2330,6 @@ where
         }
         let role_info = authorization::get_role_info(state, &payload).await?;
         authorization::check_permission(&self.permission, &role_info)?;
-        authorization::check_entity(self.minimum_entity_level, &role_info)?;
 
         let key_manager_state = &(&state.session_state()).into();
         let key_store = state
diff --git a/crates/router/src/services/authorization.rs b/crates/router/src/services/authorization.rs
index 78af4c00884..fe6ffac6ffc 100644
--- a/crates/router/src/services/authorization.rs
+++ b/crates/router/src/services/authorization.rs
@@ -112,18 +112,6 @@ pub fn check_permission(
         )
 }
 
-pub fn check_entity(
-    required_minimum_entity: common_enums::EntityType,
-    role_info: &roles::RoleInfo,
-) -> RouterResult<()> {
-    if required_minimum_entity > role_info.get_entity_type() {
-        Err(ApiErrorResponse::AccessForbidden {
-            resource: required_minimum_entity.to_string(),
-        })?;
-    }
-    Ok(())
-}
-
 fn get_redis_connection<A: SessionStateInfo>(state: &A) -> RouterResult<Arc<RedisConnectionPool>> {
     state
         .store()
diff --git a/crates/router/src/services/authorization/info.rs b/crates/router/src/services/authorization/info.rs
index 031e0b56729..dba96dac188 100644
--- a/crates/router/src/services/authorization/info.rs
+++ b/crates/router/src/services/authorization/info.rs
@@ -1,5 +1,5 @@
-use api_models::user_role::{GroupInfo, ParentGroup};
-use common_enums::PermissionGroup;
+use api_models::user_role::GroupInfo;
+use common_enums::{ParentGroup, PermissionGroup};
 use strum::IntoEnumIterator;
 
 // TODO: To be deprecated
diff --git a/crates/router/src/services/authorization/permission_groups.rs b/crates/router/src/services/authorization/permission_groups.rs
index aafc9cee943..3d1a0c8ea5b 100644
--- a/crates/router/src/services/authorization/permission_groups.rs
+++ b/crates/router/src/services/authorization/permission_groups.rs
@@ -1,97 +1,122 @@
-use common_enums::PermissionGroup;
-
-use super::permissions::Permission;
-
-pub fn get_permissions_vec(permission_group: &PermissionGroup) -> &[Permission] {
-    match permission_group {
-        PermissionGroup::OperationsView => &OPERATIONS_VIEW,
-        PermissionGroup::OperationsManage => &OPERATIONS_MANAGE,
-        PermissionGroup::ConnectorsView => &CONNECTORS_VIEW,
-        PermissionGroup::ConnectorsManage => &CONNECTORS_MANAGE,
-        PermissionGroup::WorkflowsView => &WORKFLOWS_VIEW,
-        PermissionGroup::WorkflowsManage => &WORKFLOWS_MANAGE,
-        PermissionGroup::AnalyticsView => &ANALYTICS_VIEW,
-        PermissionGroup::UsersView => &USERS_VIEW,
-        PermissionGroup::UsersManage => &USERS_MANAGE,
-        PermissionGroup::MerchantDetailsView => &MERCHANT_DETAILS_VIEW,
-        PermissionGroup::MerchantDetailsManage => &MERCHANT_DETAILS_MANAGE,
-        PermissionGroup::OrganizationManage => &ORGANIZATION_MANAGE,
-        PermissionGroup::ReconOps => &RECON,
-    }
+use common_enums::{ParentGroup, PermissionGroup, PermissionScope, Resource};
+
+pub trait PermissionGroupExt {
+    fn scope(&self) -> PermissionScope;
+    fn parent(&self) -> ParentGroup;
+    fn resources(&self) -> Vec<Resource>;
+    fn accessible_groups(&self) -> Vec<PermissionGroup>;
 }
 
-pub static OPERATIONS_VIEW: [Permission; 8] = [
-    Permission::PaymentRead,
-    Permission::RefundRead,
-    Permission::MandateRead,
-    Permission::DisputeRead,
-    Permission::CustomerRead,
-    Permission::GenerateReport,
-    Permission::PayoutRead,
-    Permission::MerchantAccountRead,
-];
+impl PermissionGroupExt for PermissionGroup {
+    fn scope(&self) -> PermissionScope {
+        match self {
+            Self::OperationsView
+            | Self::ConnectorsView
+            | Self::WorkflowsView
+            | Self::AnalyticsView
+            | Self::UsersView
+            | Self::MerchantDetailsView => PermissionScope::Read,
 
-pub static OPERATIONS_MANAGE: [Permission; 7] = [
-    Permission::PaymentWrite,
-    Permission::RefundWrite,
-    Permission::MandateWrite,
-    Permission::DisputeWrite,
-    Permission::CustomerWrite,
-    Permission::PayoutWrite,
-    Permission::MerchantAccountRead,
-];
+            Self::OperationsManage
+            | Self::ConnectorsManage
+            | Self::WorkflowsManage
+            | Self::UsersManage
+            | Self::MerchantDetailsManage
+            | Self::OrganizationManage
+            | Self::ReconOps => PermissionScope::Write,
+        }
+    }
 
-pub static CONNECTORS_VIEW: [Permission; 2] = [
-    Permission::MerchantConnectorAccountRead,
-    Permission::MerchantAccountRead,
-];
+    fn parent(&self) -> ParentGroup {
+        match self {
+            Self::OperationsView | Self::OperationsManage => ParentGroup::Operations,
+            Self::ConnectorsView | Self::ConnectorsManage => ParentGroup::Connectors,
+            Self::WorkflowsView | Self::WorkflowsManage => ParentGroup::Workflows,
+            Self::AnalyticsView => ParentGroup::Analytics,
+            Self::UsersView | Self::UsersManage => ParentGroup::Users,
+            Self::MerchantDetailsView | Self::MerchantDetailsManage => ParentGroup::Merchant,
+            Self::OrganizationManage => ParentGroup::Organization,
+            Self::ReconOps => ParentGroup::Recon,
+        }
+    }
 
-pub static CONNECTORS_MANAGE: [Permission; 2] = [
-    Permission::MerchantConnectorAccountWrite,
-    Permission::MerchantAccountRead,
-];
+    fn resources(&self) -> Vec<Resource> {
+        self.parent().resources()
+    }
 
-pub static WORKFLOWS_VIEW: [Permission; 5] = [
-    Permission::RoutingRead,
-    Permission::ThreeDsDecisionManagerRead,
-    Permission::SurchargeDecisionManagerRead,
-    Permission::MerchantConnectorAccountRead,
-    Permission::MerchantAccountRead,
-];
+    fn accessible_groups(&self) -> Vec<Self> {
+        match self {
+            Self::OperationsView => vec![Self::OperationsView],
+            Self::OperationsManage => vec![Self::OperationsView, Self::OperationsManage],
 
-pub static WORKFLOWS_MANAGE: [Permission; 5] = [
-    Permission::RoutingWrite,
-    Permission::ThreeDsDecisionManagerWrite,
-    Permission::SurchargeDecisionManagerWrite,
-    Permission::MerchantConnectorAccountRead,
-    Permission::MerchantAccountRead,
-];
+            Self::ConnectorsView => vec![Self::ConnectorsView],
+            Self::ConnectorsManage => vec![Self::ConnectorsView, Self::ConnectorsManage],
 
-pub static ANALYTICS_VIEW: [Permission; 3] = [
-    Permission::Analytics,
-    Permission::GenerateReport,
-    Permission::MerchantAccountRead,
-];
+            Self::WorkflowsView => vec![Self::WorkflowsView],
+            Self::WorkflowsManage => vec![Self::WorkflowsView, Self::WorkflowsManage],
+
+            Self::AnalyticsView => vec![Self::AnalyticsView],
 
-pub static USERS_VIEW: [Permission; 2] = [Permission::UsersRead, Permission::MerchantAccountRead];
+            Self::UsersView => vec![Self::UsersView],
+            Self::UsersManage => {
+                vec![Self::UsersView, Self::UsersManage]
+            }
 
-pub static USERS_MANAGE: [Permission; 2] =
-    [Permission::UsersWrite, Permission::MerchantAccountRead];
+            Self::ReconOps => vec![Self::ReconOps],
 
-pub static MERCHANT_DETAILS_VIEW: [Permission; 1] = [Permission::MerchantAccountRead];
+            Self::MerchantDetailsView => vec![Self::MerchantDetailsView],
+            Self::MerchantDetailsManage => {
+                vec![Self::MerchantDetailsView, Self::MerchantDetailsManage]
+            }
 
-pub static MERCHANT_DETAILS_MANAGE: [Permission; 6] = [
-    Permission::MerchantAccountWrite,
-    Permission::ApiKeyRead,
-    Permission::ApiKeyWrite,
-    Permission::MerchantAccountRead,
-    Permission::WebhookEventRead,
-    Permission::WebhookEventWrite,
+            Self::OrganizationManage => vec![Self::OrganizationManage],
+        }
+    }
+}
+
+pub trait ParentGroupExt {
+    fn resources(&self) -> Vec<Resource>;
+}
+
+impl ParentGroupExt for ParentGroup {
+    fn resources(&self) -> Vec<Resource> {
+        match self {
+            Self::Operations => OPERATIONS.to_vec(),
+            Self::Connectors => CONNECTORS.to_vec(),
+            Self::Workflows => WORKFLOWS.to_vec(),
+            Self::Analytics => ANALYTICS.to_vec(),
+            Self::Users => USERS.to_vec(),
+            Self::Merchant | Self::Organization => ACCOUNT.to_vec(),
+            Self::Recon => RECON.to_vec(),
+        }
+    }
+}
+
+pub static OPERATIONS: [Resource; 8] = [
+    Resource::Payment,
+    Resource::Refund,
+    Resource::Mandate,
+    Resource::Dispute,
+    Resource::Customer,
+    Resource::Payout,
+    Resource::Report,
+    Resource::Account,
 ];
 
-pub static ORGANIZATION_MANAGE: [Permission; 2] = [
-    Permission::MerchantAccountCreate,
-    Permission::MerchantAccountRead,
+pub static CONNECTORS: [Resource; 2] = [Resource::Connector, Resource::Account];
+
+pub static WORKFLOWS: [Resource; 5] = [
+    Resource::Routing,
+    Resource::ThreeDsDecisionManager,
+    Resource::SurchargeDecisionManager,
+    Resource::Connector,
+    Resource::Account,
 ];
 
-pub static RECON: [Permission; 1] = [Permission::ReconAdmin];
+pub static ANALYTICS: [Resource; 3] = [Resource::Analytics, Resource::Report, Resource::Account];
+
+pub static USERS: [Resource; 2] = [Resource::User, Resource::Account];
+
+pub static ACCOUNT: [Resource; 3] = [Resource::Account, Resource::ApiKey, Resource::WebhookEvent];
+
+pub static RECON: [Resource; 1] = [Resource::Recon];
diff --git a/crates/router/src/services/authorization/permissions.rs b/crates/router/src/services/authorization/permissions.rs
index 2121ba0f944..0521db7acc1 100644
--- a/crates/router/src/services/authorization/permissions.rs
+++ b/crates/router/src/services/authorization/permissions.rs
@@ -1,39 +1,75 @@
-use strum::Display;
+use common_enums::{EntityType, PermissionScope, Resource};
+use router_derive::generate_permissions;
 
-#[derive(
-    PartialEq, Display, Clone, Debug, Copy, Eq, Hash, serde::Deserialize, serde::Serialize,
-)]
-pub enum Permission {
-    PaymentRead,
-    PaymentWrite,
-    RefundRead,
-    RefundWrite,
-    ApiKeyRead,
-    ApiKeyWrite,
-    MerchantAccountRead,
-    MerchantAccountWrite,
-    MerchantConnectorAccountRead,
-    MerchantConnectorAccountWrite,
-    RoutingRead,
-    RoutingWrite,
-    DisputeRead,
-    DisputeWrite,
-    MandateRead,
-    MandateWrite,
-    CustomerRead,
-    CustomerWrite,
-    Analytics,
-    ThreeDsDecisionManagerWrite,
-    ThreeDsDecisionManagerRead,
-    SurchargeDecisionManagerWrite,
-    SurchargeDecisionManagerRead,
-    UsersRead,
-    UsersWrite,
-    MerchantAccountCreate,
-    WebhookEventRead,
-    WebhookEventWrite,
-    PayoutRead,
-    PayoutWrite,
-    GenerateReport,
-    ReconAdmin,
+generate_permissions! {
+    permissions: [
+        Payment: {
+            scopes: [Read, Write],
+            entities: [Profile, Merchant]
+        },
+        Refund: {
+            scopes: [Read, Write],
+            entities: [Profile, Merchant]
+        },
+        Dispute: {
+            scopes: [Read, Write],
+            entities: [Profile, Merchant]
+        },
+        Mandate: {
+            scopes: [Read, Write],
+            entities: [Merchant]
+        },
+        Customer: {
+            scopes: [Read, Write],
+            entities: [Merchant]
+        },
+        Payout: {
+            scopes: [Read],
+            entities: [Profile, Merchant]
+        },
+        ApiKey: {
+            scopes: [Read, Write],
+            entities: [Merchant]
+        },
+        Account: {
+            scopes: [Read, Write],
+            entities: [Profile, Merchant, Organization]
+        },
+        Connector: {
+            scopes: [Read, Write],
+            entities: [Profile, Merchant]
+        },
+        Routing: {
+            scopes: [Read, Write],
+            entities: [Profile, Merchant]
+        },
+        ThreeDsDecisionManager: {
+            scopes: [Read, Write],
+            entities: [Merchant]
+        },
+        SurchargeDecisionManager: {
+            scopes: [Read, Write],
+            entities: [Merchant]
+        },
+        Analytics: {
+            scopes: [Read],
+            entities: [Profile, Merchant, Organization]
+        },
+        Report: {
+            scopes: [Read],
+            entities: [Profile, Merchant, Organization]
+        },
+        User: {
+            scopes: [Read, Write],
+            entities: [Profile, Merchant]
+        },
+        WebhookEvent: {
+            scopes: [Read, Write],
+            entities: [Merchant]
+        },
+        Recon: {
+            scopes: [Write],
+            entities: [Merchant]
+        },
+    ]
 }
diff --git a/crates/router/src/services/authorization/roles.rs b/crates/router/src/services/authorization/roles.rs
index 19383f010f2..63d547bfa67 100644
--- a/crates/router/src/services/authorization/roles.rs
+++ b/crates/router/src/services/authorization/roles.rs
@@ -1,9 +1,9 @@
 use std::collections::HashSet;
 
-use common_enums::{EntityType, PermissionGroup, RoleScope};
+use common_enums::{EntityType, PermissionGroup, Resource, RoleScope};
 use common_utils::{errors::CustomResult, id_type};
 
-use super::{permission_groups::get_permissions_vec, permissions::Permission};
+use super::{permission_groups::PermissionGroupExt, permissions::Permission};
 use crate::{core::errors, routes::SessionState};
 
 pub mod predefined_roles;
@@ -30,8 +30,13 @@ impl RoleInfo {
         &self.role_name
     }
 
-    pub fn get_permission_groups(&self) -> &Vec<PermissionGroup> {
-        &self.groups
+    pub fn get_permission_groups(&self) -> Vec<PermissionGroup> {
+        self.groups
+            .iter()
+            .flat_map(|group| group.accessible_groups())
+            .collect::<HashSet<_>>()
+            .into_iter()
+            .collect()
     }
 
     pub fn get_scope(&self) -> RoleScope {
@@ -58,17 +63,19 @@ impl RoleInfo {
         self.is_updatable
     }
 
-    pub fn get_permissions_set(&self) -> HashSet<Permission> {
-        self.groups
+    pub fn get_resources_set(&self) -> HashSet<Resource> {
+        self.get_permission_groups()
             .iter()
-            .flat_map(|group| get_permissions_vec(group).iter().copied())
+            .flat_map(|group| group.resources())
             .collect()
     }
 
     pub fn check_permission_exists(&self, required_permission: &Permission) -> bool {
-        self.groups
-            .iter()
-            .any(|group| get_permissions_vec(group).contains(required_permission))
+        required_permission.entity_type() <= self.entity_type
+            && self.get_permission_groups().iter().any(|group| {
+                required_permission.scope() <= group.scope()
+                    && group.resources().contains(&required_permission.resource())
+            })
     }
 
     pub async fn from_role_id_in_merchant_scope(
diff --git a/crates/router_derive/src/lib.rs b/crates/router_derive/src/lib.rs
index 02179934e38..69865512a37 100644
--- a/crates/router_derive/src/lib.rs
+++ b/crates/router_derive/src/lib.rs
@@ -694,3 +694,58 @@ pub fn flat_struct_derive(input: proc_macro::TokenStream) -> proc_macro::TokenSt
 
     proc_macro::TokenStream::from(expanded)
 }
+
+/// Generates the permissions enum and implematations for the permissions
+///
+/// **NOTE:** You have to make sure that all the identifiers used
+/// in the macro input are present in the respective enums as well.
+///
+/// ## Usage
+/// ```
+/// use router_derive::generate_permissions;
+///
+/// enum Scope {
+///     Read,
+///     Write,
+/// }
+///
+/// enum EntityType {
+///    Profile,
+///    Merchant,
+///    Org,
+/// }
+///
+/// enum Resource {
+///    Payments,
+///    Refunds,
+/// }
+///
+/// generate_permissions! {
+///     permissions: [
+///         Payments: {
+///             scopes: [Read, Write],
+///             entities: [Profile, Merchant, Org]
+///         },
+///         Refunds: {
+///             scopes: [Read],
+///             entities: [Profile, Org]
+///         }
+///     ]
+/// }
+/// ```
+/// This will generate the following enum.
+/// ```
+/// enum Permission {
+///    ProfilePaymentsRead,
+///    ProfilePaymentsWrite,
+///    MerchantPaymentsRead,
+///    MerchantPaymentsWrite,
+///    OrgPaymentsRead,
+///    OrgPaymentsWrite,
+///    ProfileRefundsRead,
+///    OrgRefundsRead,
+/// ```
+#[proc_macro]
+pub fn generate_permissions(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+    macros::generate_permissions_inner(input)
+}
diff --git a/crates/router_derive/src/macros.rs b/crates/router_derive/src/macros.rs
index 9a8e514c5c1..32e6c213ca6 100644
--- a/crates/router_derive/src/macros.rs
+++ b/crates/router_derive/src/macros.rs
@@ -1,5 +1,6 @@
 pub(crate) mod api_error;
 pub(crate) mod diesel;
+pub(crate) mod generate_permissions;
 pub(crate) mod generate_schema;
 pub(crate) mod misc;
 pub(crate) mod operation;
@@ -14,6 +15,7 @@ use syn::DeriveInput;
 pub(crate) use self::{
     api_error::api_error_derive_inner,
     diesel::{diesel_enum_derive_inner, diesel_enum_text_derive_inner},
+    generate_permissions::generate_permissions_inner,
     generate_schema::polymorphic_macro_derive_inner,
 };
 
diff --git a/crates/router_derive/src/macros/generate_permissions.rs b/crates/router_derive/src/macros/generate_permissions.rs
new file mode 100644
index 00000000000..9b388f102cb
--- /dev/null
+++ b/crates/router_derive/src/macros/generate_permissions.rs
@@ -0,0 +1,135 @@
+use proc_macro::TokenStream;
+use quote::{format_ident, quote};
+use syn::{
+    braced, bracketed,
+    parse::{Parse, ParseBuffer, ParseStream},
+    parse_macro_input,
+    punctuated::Punctuated,
+    token::Comma,
+    Ident, Token,
+};
+
+struct ResourceInput {
+    resource_name: Ident,
+    scopes: Punctuated<Ident, Token![,]>,
+    entities: Punctuated<Ident, Token![,]>,
+}
+
+struct Input {
+    permissions: Punctuated<ResourceInput, Token![,]>,
+}
+
+impl Parse for Input {
+    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
+        let (_permission_label, permissions) = parse_label_with_punctuated_data(input)?;
+
+        Ok(Self { permissions })
+    }
+}
+
+impl Parse for ResourceInput {
+    fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
+        let resource_name: Ident = input.parse()?;
+        input.parse::<Token![:]>()?; // Expect ':'
+
+        let content;
+        braced!(content in input);
+
+        let (_scopes_label, scopes) = parse_label_with_punctuated_data(&content)?;
+        content.parse::<Comma>()?;
+
+        let (_entities_label, entities) = parse_label_with_punctuated_data(&content)?;
+
+        Ok(Self {
+            resource_name,
+            scopes,
+            entities,
+        })
+    }
+}
+
+fn parse_label_with_punctuated_data<T: Parse>(
+    input: &ParseBuffer<'_>,
+) -> syn::Result<(Ident, Punctuated<T, Token![,]>)> {
+    let label: Ident = input.parse()?;
+    input.parse::<Token![:]>()?; // Expect ':'
+
+    let content;
+    bracketed!(content in input); // Parse the list inside []
+    let data = Punctuated::<T, Token![,]>::parse_terminated(&content)?;
+
+    Ok((label, data))
+}
+
+pub fn generate_permissions_inner(input: TokenStream) -> TokenStream {
+    let input = parse_macro_input!(input as Input);
+
+    let res = input.permissions.iter();
+
+    let mut enum_keys = Vec::new();
+    let mut scope_impl_per = Vec::new();
+    let mut entity_impl_per = Vec::new();
+    let mut resource_impl_per = Vec::new();
+
+    let mut entity_impl_res = Vec::new();
+
+    for per in res {
+        let resource_name = &per.resource_name;
+        let mut permissions = Vec::new();
+
+        for scope in per.scopes.iter() {
+            for entity in per.entities.iter() {
+                let key = format_ident!("{}{}{}", entity, per.resource_name, scope);
+
+                enum_keys.push(quote! { #key });
+                scope_impl_per.push(quote! { Permission::#key => PermissionScope::#scope });
+                entity_impl_per.push(quote! { Permission::#key => EntityType::#entity });
+                resource_impl_per.push(quote! { Permission::#key => Resource::#resource_name });
+                permissions.push(quote! { Permission::#key });
+            }
+            let entities_iter = per.entities.iter();
+            entity_impl_res
+                .push(quote! { Resource::#resource_name => vec![#(EntityType::#entities_iter),*] });
+        }
+    }
+
+    let expanded = quote! {
+        #[derive(
+            Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, serde::Serialize, serde::Deserialize, strum::Display
+        )]
+        pub enum Permission {
+            #(#enum_keys),*
+        }
+
+        impl Permission {
+            pub fn scope(&self) -> PermissionScope {
+                match self {
+                    #(#scope_impl_per),*
+                }
+            }
+            pub fn entity_type(&self) -> EntityType {
+                match self {
+                    #(#entity_impl_per),*
+                }
+            }
+            pub fn resource(&self) -> Resource {
+                match self {
+                    #(#resource_impl_per),*
+                }
+            }
+        }
+
+        pub trait ResourceExt {
+            fn entities(&self) -> Vec<EntityType>;
+        }
+
+        impl ResourceExt for Resource {
+            fn entities(&self) -> Vec<EntityType> {
+                match self {
+                    #(#entity_impl_res),*
+                }
+            }
+        }
+    };
+    expanded.into()
+}