aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Rykov <arykov@ydb.tech>2025-04-03 09:00:32 +0200
committerGitHub <noreply@github.com>2025-04-03 09:00:32 +0200
commit9742f093af95d8d12d08c43f1073be1b98f73135 (patch)
tree110f371a0ca073c24d6e8e21e200c9bd6a583df1
parent942e7f77e7281494b175daea27ac42e8fc22942d (diff)
downloadydb-9742f093af95d8d12d08c43f1073be1b98f73135.tar.gz
Configure cluster access resource Id for Nebius_v1 (#16614)
-rw-r--r--ydb/core/grpc_services/grpc_request_check_actor.h39
-rw-r--r--ydb/core/protos/auth.proto1
-rw-r--r--ydb/core/security/ticket_parser_impl.h6
-rw-r--r--ydb/core/security/ticket_parser_ut.cpp24
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) {