package rbac

import "regexp"

// RBAC resource map
var (
	DefaultRBACPathPattern2ResourceMap = map[string]string{
		"get:/api/v1/serverless/orgs/(\\d+)/spend_limits":                                         "orgs/{org_id}/spend_limits/list",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/spend_limits":                         "orgs/{org_id}/projects/{project_id}/spend_limits/list",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/spend_limits":         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/spend_limits/get",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/spend_limits":        "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/spend_limits/create",
		"put:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/spend_limits":         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/spend_limits/update",
		"get:/api/v1/serverless/orgs/(\\d+)/spend_limits/predict":                                 "orgs/{org_id}/spend_limits/predict",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/spend_limits/predict":                 "orgs/{org_id}/projects/{project_id}/spend_limits/predict",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/spend_limits/predict": "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/spend_limits/predict",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/spend_limits/details": "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/spend_limits/details",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/spend_limits/measure": "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/spend_limits/query",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/resource_limit":       "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/resource_limit",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/databases":            "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/databases/list",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/databases":           "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/databases/create",

		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/branches":                     "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/list",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/branches":                    "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/create",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/branches/([\\w-]+)":           "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/{branch_id}/get",
		"delete:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/branches/([\\w-]+)":        "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/{branch_id}/delete",
		"put:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/branches/([\\w-]+)/password":  "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/{branch_id}/password/update",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/branches/([\\w-]+)/databases": "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/{branch_id}/databases/list",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/branches/([\\w-]+):reset":    "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/{branch_id}:reset",
		"patch:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/branches/([\\w-]+)":         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/{branch_id}/update",
		// br
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/backups":                          "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/backups/list",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/backups/([\\w-]+)":                "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/backups/{backup_id}/get",
		"get:/api/v1/serverless/orgs/(\\d+)/recycledInstances":                                                "serverless/orgs/{org_id}/recycledInstances/list",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/recycledInstances/([\\w-]+)":                      "serverless/orgs/{org_id}/projects/{project_id}/recycledInstances/{cluster_id}/get",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/recycledInstances/([\\w-]+)/backups":              "serverless/orgs/{org_id}/projects/{project_id}/recycledInstances/{cluster_id}/backups/list",
		"delete:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/recycledInstances/([\\w-]+)/backups/([\\w-]+)": "serverless/orgs/{org_id}/projects/{project_id}/recycledInstances/{cluster_id}/backups/{backup_id}/delete",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters:restore":                                "serverless/orgs/{org_id}/projects/{project_id}/clusters:restore",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/latest_restore_progress":          "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/restores/list",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/backup_retention":                 "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/backup_retention/get",
		// export
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/exports":                   "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/list",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/exports":                  "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/create",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/exports/([\\w-]+)":         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/{export_id}/get",
		"delete:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/exports/([\\w-]+)":      "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/{export_id}/delete",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/exports/([\\w-]+):cancel": "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/{export_id}:cancel",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+):parseFilter":               "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}:parseFilter",
		// index advisor
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/advise_indexes":       "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/advise_indexes",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/apply_advice":         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/apply_advice",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/close_advice":         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/close_advice",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/index_advices":         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/index_advices/list",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/index_advices/(\\d+)":  "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/index_advices/{advice_id}",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\d+)/index_advices_summary": "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/index_advices/summary",
		// import
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports:upload":                 "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports:startUpload",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports":                        "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports/create",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports":                         "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports/list",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports/([\\w-]+)":               "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports/{import_id}/get",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports/([\\w-]+):cancel":       "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports/{import_id}:cancel",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports:previewLocal":           "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports:previewLocal",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports:getTableColumns":         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports:getTableColumns",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports:getDataIngestionProfile": "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports:getDataIngestionProfile",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports:searchImportFiles":      "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports:searchImportFiles",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports:validate":               "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports:validate",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports:listTargetTables":        "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports:listTargetTables",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/imports:precheck":               "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports:precheck",
		// audit log
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/auditLog/files":                         "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:read",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/auditLog/files:download":               "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:write",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/auditLog/filterRules/([\\w-]+)":         "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog/filterRules/{filter_rule_id}:read",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/auditLog/filterRules":                   "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:read",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/auditLog/filterRules":                  "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:write",
		"delete:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/auditLog/filterRules/([\\w-]+)":      "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog/filterRules/{filter_rule_id}:write",
		"patch:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/auditLog/filterRules/([\\w-]+)":       "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog/filterRules/{filter_rule_id}:write",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/auditLog/config":                        "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:read",
		"patch:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/auditLog/config":                      "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:write",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/auditLog/config:precheck":              "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:write",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/auditLog/config:getCloudStorageProfile": "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:read",

		// migration
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration/precheck":                 "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/precheck:create",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration/tasks":                    "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/create",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration/tasks":                     "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/list",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration/tasks/([\\w-]+)":           "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/{id}/get",
		"delete:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration/tasks/([\\w-]+)":        "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/{id}/delete",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration/tasks/([\\w-]+):pause":    "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/{id}:pause",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration/tasks/([\\w-]+):resume":   "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/{id}:resume",
		"delete:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration/precheck/([\\w-]+)":     "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/precheck/{id}:cancel",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration/precheck/([\\w-]+)":        "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/precheck/{id}/get",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration:getSourceTables":          "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration:getSourceTables",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration:validateSourceConnection": "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration:validateSourceConnection",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration:validateTargetConnection": "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration:validateTargetConnection",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration:createVpcEndpoint":        "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration:createVpcEndpoint",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration:describeVpcEndpoint":      "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration:describeVpcEndpoint",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration:getVpcInfo":               "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration:getVpcInfo",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/migration/ip-whitelist":              "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/ip-whitelist",
		// private link connection
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/privateLinkConnections/([\\w-]+)":                "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections/{private_link_connection_id}:read",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/privateLinkConnections":                          "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections:read",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/privateLinkConnections":                         "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections:write",
		"delete:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/privateLinkConnections/([\\w-]+)":             "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections/{private_link_connection_id}:write",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/privateLinkConnections:getAvailabilityZones":     "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections:read",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/privateLinkConnections/([\\w-]+):attachDomains": "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections/{private_link_connection_id}:write",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/privateLinkConnections/([\\w-]+):detachDomains": "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections/{private_link_connection_id}:write",
		// changefeeds
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/changefeeds":                      "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:read",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/changefeeds/([\\w-]+)":            "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds/{changefeed_id}:read",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/changefeeds":                     "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:write",
		"delete:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/changefeeds/([\\w-]+)":         "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds/{changefeed_id}:write",
		"patch:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/changefeeds/([\\w-]+)":          "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds/{changefeed_id}:write",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/changefeeds/([\\w-]+):start":     "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds/{changefeed_id}:write",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/changefeeds/([\\w-]+):stop":      "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds/{changefeed_id}:write",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/changefeeds/([\\w-]+):scale":     "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds/{changefeed_id}:write",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/changefeeds:test":                "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:write",
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/changefeeds:listSpecifications":   "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:read",
		"post:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/changefeeds:describeSchemaTable": "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:write",
		// features
		"get:/api/v1/serverless/orgs/(\\d+)/projects/(\\d+)/clusters/(\\w+)/features:check": "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/features:read",
	}

	RBACOpenAPIPathPattern2ResourceMap = map[*regexp.Regexp]string{
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/branches$`):                         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/list",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/branches$`):                        "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/create",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/branches/([\w-]+)$`):                "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/{branch_id}/get",
		regexp.MustCompile(`^delete:/v1beta1/clusters/(\w+)/branches/([\w-]+)$`):             "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/{branch_id}/delete",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/branches/([\w-]+):reset$`):         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/{branch_id}:reset",
		regexp.MustCompile(`^patch:/v1beta1/clusters/(\w+)/branches/([\w-]+)/sqlUsers/.+$`):  "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/branches/{branch_id}/password/update",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/exports$`):                          "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/list",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/exports$`):                         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/create",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/exports/([\w-]+)$`):                 "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/{export_id}/get",
		regexp.MustCompile(`^delete:/v1beta1/clusters/(\w+)/exports/([\w-]+)$`):              "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/{export_id}/delete",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/exports/([\w-]+):cancel$`):         "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/{export_id}:cancel",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/exports/([\w-]+):download$`):       "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/{export_id}:download",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/exports/([\w-]+)/files$`):           "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/{export_id}/files:list",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/exports/([\w-]+)/files:download$`): "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/exports/{export_id}/files:download",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/imports:startUpload$`):             "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports:startUpload",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/imports:completeUpload$`):          "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports:completeUpload",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/imports:cancelUpload$`):            "orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports:cancelUpload",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/imports$`):                          "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports/list",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/imports$`):                         "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports/create",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/imports/([\w-]+)$`):                 "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports/{import_id}/get",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/imports/([\w-]+):cancel$`):         "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/imports/{import_id}:cancel",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/auditlogs$`):                        "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditlogs",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/auditlogs:download$`):              "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditlogs:download",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/auditlogs/filterRules/.+$`):         "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditlogs",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/auditlogs/filterRules$`):            "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditlogs",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/auditlogs/filterRules$`):           "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditlogs",
		regexp.MustCompile(`^patch:/v1beta1/clusters/(\w+)/auditlogs/filterRules/.+$`):       "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditlogs",
		regexp.MustCompile(`^delete:/v1beta1/clusters/(\w+)/auditlogs/filterRules/.+$`):      "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditlogs",
		// cdc
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/changefeeds$`):                      "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:read",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/changefeeds/([\w-]+)$`):             "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:read",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/changefeeds$`):                     "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:write",
		regexp.MustCompile(`^delete:/v1beta1/clusters/(\w+)/changefeeds/([\w-]+)$`):          "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:write",
		regexp.MustCompile(`^patch:/v1beta1/clusters/(\w+)/changefeeds/([\w-]+)$`):           "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:write",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/changefeeds/([\w-]+):start$`):      "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:write",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/changefeeds/([\w-]+):stop$`):       "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:write",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/changefeeds/([\w-]+):scale$`):      "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:write",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/changefeeds:test$`):                "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:write",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/changefeeds:listSpecifications$`):   "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:read",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/changefeeds:describeSchemaTable$`): "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/changefeeds:write",
		// audit log
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/auditLog/files$`):                   "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:read",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/auditLog/files:download$`):         "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:write",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/auditLog/filterRules/([\w-]+)$`):    "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:read",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/auditLog/filterRules$`):             "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:read",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/auditLog/filterRules$`):            "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:write",
		regexp.MustCompile(`^delete:/v1beta1/clusters/(\w+)/auditLog/filterRules/([\w-]+)$`): "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:write",
		regexp.MustCompile(`^patch:/v1beta1/clusters/(\w+)/auditLog/filterRules/([\w-]+)$`):  "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:write",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/auditLog/config$`):                  "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:read",
		regexp.MustCompile(`^patch:/v1beta1/clusters/(\w+)/auditLog/config$`):                "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:write",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/auditLog/config:precheck$`):        "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/auditLog:write",
		// private link connection
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/privateLinkConnections/([\w-]+)$`):                "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections:read",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/privateLinkConnections$`):                         "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections:read",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/privateLinkConnections$`):                        "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections:write",
		regexp.MustCompile(`^delete:/v1beta1/clusters/(\w+)/privateLinkConnections/([\w-]+)$`):             "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections:write",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/privateLinkConnections:getAvailabilityZones$`):    "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections:read",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/privateLinkConnections/([\w-]+):attachDomains$`): "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections:write",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/privateLinkConnections/([\w-]+):detachDomains$`): "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/privateLinkConnections:write",
		// migration
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/migrationPrechecks$`):            "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/precheck:create",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/migrations$`):                    "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/create",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/migrations$`):                     "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/list",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/migrations/([\w-]+)$`):            "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/{id}/get",
		regexp.MustCompile(`^delete:/v1beta1/clusters/(\w+)/migrations/([\w-]+)$`):         "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/{id}/delete",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/migrations/([\w-]+):pause$`):     "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/{id}:pause",
		regexp.MustCompile(`^post:/v1beta1/clusters/(\w+)/migrations/([\w-]+):resume$`):    "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/tasks/{id}:resume",
		regexp.MustCompile(`^delete:/v1beta1/clusters/(\w+)/migrationPrechecks/([\w-]+)$`): "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/precheck/{id}:cancel",
		regexp.MustCompile(`^get:/v1beta1/clusters/(\w+)/migrationPrechecks/([\w-]+)$`):    "serverless/orgs/{org_id}/projects/{project_id}/tidbs/{cluster_id}/migration/precheck/{id}/get",
	}

	RBACPathWhitelist = []string{
		"/health_check",
		"/ping",
		"/api/v1/serverless/pricing/details",
		"/api/v1/serverless/expensive_sql_email",
		"/api/v1/serverless/cost/predict",
		"/api/v1/serverless/imports:listSupportedDataTypes",
		"/api/v1/serverless/migration/supported-sources",
	}
)

const (
	RBACOrgIdKey                = "org_id"
	RBACProjectIdKey            = "project_id"
	RBACClusterIdKey            = "cluster_id"
	RBACBranchIdKey             = "branch_id"
	RBACExportIdKey             = "export_id"
	RBACImportIdKey             = "import_id"
	RBACMigrationTaskIdKey      = "migration/tasks/{id}"
	RBACMigrationPrecheckIdKey  = "migration/precheck/{id}"
	RBACAuditLogFilterRuleIdKey = "audit_log_filter_rule_id"
)
