diff options
author | Andrei Rykov <arykov@ydb.tech> | 2025-04-03 09:00:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-03 09:00:32 +0200 |
commit | 9742f093af95d8d12d08c43f1073be1b98f73135 (patch) | |
tree | 110f371a0ca073c24d6e8e21e200c9bd6a583df1 | |
parent | 942e7f77e7281494b175daea27ac42e8fc22942d (diff) | |
download | ydb-9742f093af95d8d12d08c43f1073be1b98f73135.tar.gz |
Configure cluster access resource Id for Nebius_v1 (#16614)
-rw-r--r-- | ydb/core/grpc_services/grpc_request_check_actor.h | 39 | ||||
-rw-r--r-- | ydb/core/protos/auth.proto | 1 | ||||
-rw-r--r-- | ydb/core/security/ticket_parser_impl.h | 6 | ||||
-rw-r--r-- | ydb/core/security/ticket_parser_ut.cpp | 24 |
4 files changed, 47 insertions, 23 deletions
diff --git a/ydb/core/grpc_services/grpc_request_check_actor.h b/ydb/core/grpc_services/grpc_request_check_actor.h index cafe74529cb..079ba24d419 100644 --- a/ydb/core/grpc_services/grpc_request_check_actor.h +++ b/ydb/core/grpc_services/grpc_request_check_actor.h @@ -40,17 +40,36 @@ bool TGRpcRequestProxyHandleMethods::ValidateAndReplyOnError(TCtx* ctx) { } inline const TVector<TEvTicketParser::TEvAuthorizeTicket::TEntry>& GetEntriesForAuthAndCheckRequest(TEvRequestAuthAndCheck::TPtr& ev) { - if (ev->Get()->YdbToken && ev->Get()->YdbToken->StartsWith("Bearer")) { - if (AppData()->AuthConfig.GetUseAccessService() - && (AppData()->DomainsConfig.GetSecurityConfig().ViewerAllowedSIDsSize() > 0 || AppData()->DomainsConfig.GetSecurityConfig().MonitoringAllowedSIDsSize() > 0)) { - static TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> entries = { - {NKikimr::TEvTicketParser::TEvAuthorizeTicket::ToPermissions({"ydb.developerApi.get", "ydb.developerApi.update"}), {{"gizmo_id", "gizmo"}}} - }; - return entries; + const bool isBearerToken = ev->Get()->YdbToken && ev->Get()->YdbToken->StartsWith("Bearer"); + const bool useAccessService = AppData()->AuthConfig.GetUseAccessService(); + const bool hasClusterAccessResourceId = !AppData()->AuthConfig.GetClusterAccessResourceId().empty(); + const bool needClusterAccessResourceCheck = AppData()->DomainsConfig.GetSecurityConfig().ViewerAllowedSIDsSize() > 0 || + AppData()->DomainsConfig.GetSecurityConfig().MonitoringAllowedSIDsSize() > 0; + + if (!isBearerToken || !useAccessService || !hasClusterAccessResourceId || !needClusterAccessResourceCheck) { + static const TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> emptyEntries = {}; + return emptyEntries; + } + + auto makeEntries = []() -> TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> { + const TString& accessServiceType = AppData()->AuthConfig.GetAccessServiceType(); + TVector<TString> permissions; + if (accessServiceType == "Yandex_v2") { + permissions = {"ydb.developerApi.get", "ydb.developerApi.update"}; + } else if (accessServiceType == "Nebius_v1") { + permissions = {"ydb.clusters.get", "ydb.clusters.monitor", "ydb.clusters.manage"}; + } else { + return {}; } - } - static TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> emptyEntries = {}; - return emptyEntries; + const TString& clusterAccessResourceId = AppData()->AuthConfig.GetClusterAccessResourceId(); + TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> entries = { + {NKikimr::TEvTicketParser::TEvAuthorizeTicket::ToPermissions(permissions), {{"gizmo_id", clusterAccessResourceId}}} + }; + return entries; + }; + + static TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> entries = makeEntries(); + return entries; } template <typename TEvent> diff --git a/ydb/core/protos/auth.proto b/ydb/core/protos/auth.proto index 6e713d7f2cb..3eb8b3408e3 100644 --- a/ydb/core/protos/auth.proto +++ b/ydb/core/protos/auth.proto @@ -58,6 +58,7 @@ message TAuthConfig { optional string NodeRegistrationToken = 82 [default = "root@builtin", (Ydb.sensitive) = true]; optional TPasswordComplexity PasswordComplexity = 83; optional TAccountLockout AccountLockout = 84; + optional string ClusterAccessResourceId = 85 [default = "gizmo"]; } message TUserRegistryConfig { diff --git a/ydb/core/security/ticket_parser_impl.h b/ydb/core/security/ticket_parser_impl.h index b50c3711044..7aae4a55b58 100644 --- a/ydb/core/security/ticket_parser_impl.h +++ b/ydb/core/security/ticket_parser_impl.h @@ -479,6 +479,12 @@ private: if (const auto folderId = record.GetAttributeValue(permission, "folder_id"); folderId) { AddNebiusContainerId(pathsContainer, folderId); } + + // Use attribute "gizmo_id" as container id that contains cluster access resource + // IAM can link roles for cluster access resource + if (const auto gizmoId = record.GetAttributeValue(permission, "gizmo_id"); gizmoId) { + AddNebiusContainerId(pathsContainer, gizmoId); + } } template <typename TTokenRecord> diff --git a/ydb/core/security/ticket_parser_ut.cpp b/ydb/core/security/ticket_parser_ut.cpp index cb6d3506b3c..2904d755835 100644 --- a/ydb/core/security/ticket_parser_ut.cpp +++ b/ydb/core/security/ticket_parser_ut.cpp @@ -1661,19 +1661,17 @@ Y_UNIT_TEST_SUITE(TTicketParserTest) { UNIT_ASSERT_C(result->Error.empty(), result->Error); UNIT_ASSERT_C(result->Token->IsExist("something.read-bbbb4554@as"), result->Token->ShortDebugString()); - if constexpr (!IsNebiusAccessService<TAccessServiceMock>()) { - // Authorization successful for gizmo resource - accessServiceMock.AllowedResourceIds.clear(); - accessServiceMock.AllowedResourceIds.emplace("gizmo"); - runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvAuthorizeTicket( - userToken, - {{"gizmo_id", "gizmo"}, }, - {"monitoring.view"})), 0); - result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle); - UNIT_ASSERT_C(result->Error.empty(), result->Error); - UNIT_ASSERT_C(result->Token->IsExist("monitoring.view@as"), result->Token->ShortDebugString()); - UNIT_ASSERT_C(result->Token->IsExist("monitoring.view-gizmo@as"), result->Token->ShortDebugString()); - } + // Authorization successful for gizmo resource + accessServiceMock.AllowedResourceIds.clear(); + accessServiceMock.AllowedResourceIds.emplace("gizmo"); + runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvAuthorizeTicket( + userToken, + {{"gizmo_id", "gizmo"}, }, + {"monitoring.view"})), 0); + result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle); + UNIT_ASSERT_C(result->Error.empty(), result->Error); + UNIT_ASSERT_C(result->Token->IsExist("monitoring.view@as"), result->Token->ShortDebugString()); + UNIT_ASSERT_C(result->Token->IsExist("monitoring.view-gizmo@as"), result->Token->ShortDebugString()); } Y_UNIT_TEST(Authorization) { |