Skip to content

Commit fafbd91

Browse files
Add user attribute to keep gizmo resource id (#17952)
1 parent 47691b2 commit fafbd91

File tree

5 files changed

+68
-43
lines changed

5 files changed

+68
-43
lines changed

ydb/core/grpc_services/grpc_request_check_actor.h

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -39,37 +39,40 @@ bool TGRpcRequestProxyHandleMethods::ValidateAndReplyOnError(TCtx* ctx) {
3939
}
4040
}
4141

42-
inline const TVector<TEvTicketParser::TEvAuthorizeTicket::TEntry>& GetEntriesForAuthAndCheckRequest(TEvRequestAuthAndCheck::TPtr& ev) {
42+
inline TVector<TEvTicketParser::TEvAuthorizeTicket::TEntry> GetEntriesForAuthAndCheckRequest(TEvRequestAuthAndCheck::TPtr& ev, const TVector<std::pair<TString, TString>>& rootAttributes) {
4343
const bool isBearerToken = ev->Get()->YdbToken && ev->Get()->YdbToken->StartsWith("Bearer");
4444
const bool useAccessService = AppData()->AuthConfig.GetUseAccessService();
45-
const bool hasClusterAccessResourceId = !AppData()->AuthConfig.GetClusterAccessResourceId().empty();
4645
const bool needClusterAccessResourceCheck = AppData()->DomainsConfig.GetSecurityConfig().ViewerAllowedSIDsSize() > 0 ||
4746
AppData()->DomainsConfig.GetSecurityConfig().MonitoringAllowedSIDsSize() > 0;
4847

49-
if (!isBearerToken || !useAccessService || !hasClusterAccessResourceId || !needClusterAccessResourceCheck) {
50-
static const TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> emptyEntries = {};
51-
return emptyEntries;
48+
if (!isBearerToken || !useAccessService || !needClusterAccessResourceCheck) {
49+
return {};
5250
}
5351

54-
auto makeEntries = []() -> TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> {
55-
const TString& accessServiceType = AppData()->AuthConfig.GetAccessServiceType();
56-
TVector<TString> permissions;
57-
if (accessServiceType == "Yandex_v2") {
58-
permissions = {"ydb.developerApi.get", "ydb.developerApi.update"};
59-
} else if (accessServiceType == "Nebius_v1") {
60-
permissions = {"ydb.clusters.get", "ydb.clusters.monitor", "ydb.clusters.manage"};
61-
} else {
52+
const TString& accessServiceType = AppData()->AuthConfig.GetAccessServiceType();
53+
54+
if (accessServiceType == "Yandex_v2") {
55+
static const TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> entries = {
56+
{NKikimr::TEvTicketParser::TEvAuthorizeTicket::ToPermissions({"ydb.developerApi.get", "ydb.developerApi.update"}), {{"gizmo_id", "gizmo"}}}
57+
};
58+
return entries;
59+
} else if (accessServiceType == "Nebius_v1") {
60+
static const auto permissions = NKikimr::TEvTicketParser::TEvAuthorizeTicket::ToPermissions({
61+
"ydb.clusters.get", "ydb.clusters.monitor", "ydb.clusters.manage"
62+
});
63+
auto it = std::find_if(rootAttributes.begin(), rootAttributes.end(),
64+
[](const std::pair<TString, TString>& p) {
65+
return p.first == "container_id";
66+
});
67+
if (it == rootAttributes.end()) {
6268
return {};
6369
}
64-
const TString& clusterAccessResourceId = AppData()->AuthConfig.GetClusterAccessResourceId();
65-
TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> entries = {
66-
{NKikimr::TEvTicketParser::TEvAuthorizeTicket::ToPermissions(permissions), {{"gizmo_id", clusterAccessResourceId}}}
70+
return {
71+
{permissions, {{"gizmo_id", it->second}}}
6772
};
68-
return entries;
69-
};
70-
71-
static TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> entries = makeEntries();
72-
return entries;
73+
} else {
74+
return {};
75+
}
7376
}
7477

7578
template <typename TEvent>
@@ -99,14 +102,14 @@ class TGrpcRequestCheckActor
99102

100103
static const TVector<TString>& GetPermissions();
101104

102-
void InitializeAttributesFromSchema(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
105+
void InitializeAttributesFromSchema(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, const TVector<std::pair<TString, TString>>& rootAttributes) {
103106
CheckedDatabaseName_ = CanonizePath(schemeData.GetPath());
104107
if (!GrpcRequestBaseCtx_->TryCustomAttributeProcess(schemeData, this)) {
105-
ProcessCommonAttributes(schemeData);
108+
ProcessCommonAttributes(schemeData, rootAttributes);
106109
}
107110
}
108111

109-
void ProcessCommonAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
112+
void ProcessCommonAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, const TVector<std::pair<TString, TString>>& rootAttributes) {
110113
TVector<TEvTicketParser::TEvAuthorizeTicket::TEntry> entries;
111114
static std::vector<TString> allowedAttributes = {"folder_id", "service_account_id", "database_id"};
112115
TVector<std::pair<TString, TString>> attributes;
@@ -121,7 +124,7 @@ class TGrpcRequestCheckActor
121124
}
122125

123126
if constexpr (std::is_same_v<TEvent, TEvRequestAuthAndCheck>) {
124-
const auto& e = GetEntriesForAuthAndCheckRequest(Request_);
127+
const auto& e = GetEntriesForAuthAndCheckRequest(Request_, rootAttributes);
125128
entries.insert(entries.end(), e.begin(), e.end());
126129
}
127130

@@ -134,12 +137,12 @@ class TGrpcRequestCheckActor
134137
TBase::SetEntries(entries);
135138
}
136139

137-
void InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData);
140+
void InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, const TVector<std::pair<TString, TString>>& rootAttributes);
138141

139-
void Initialize(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
142+
void Initialize(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, const TVector<std::pair<TString, TString>>& rootAttributes) {
140143
TString peerName = GrpcRequestBaseCtx_->GetPeerName();
141144
TBase::SetPeerName(peerName);
142-
InitializeAttributes(schemeData);
145+
InitializeAttributes(schemeData, rootAttributes);
143146
TBase::SetDatabase(CheckedDatabaseName_);
144147
InitializeAuditSettings(schemeData);
145148
}
@@ -151,7 +154,8 @@ class TGrpcRequestCheckActor
151154
TAutoPtr<TEventHandle<TEvent>> request,
152155
IGRpcProxyCounters::TPtr counters,
153156
bool skipCheckConnectRights,
154-
const IFacilityProvider* facilityProvider)
157+
const IFacilityProvider* facilityProvider,
158+
const TVector<std::pair<TString, TString>>& rootAttributes)
155159
: Owner_(owner)
156160
, Request_(std::move(request))
157161
, Counters_(counters)
@@ -171,7 +175,7 @@ class TGrpcRequestCheckActor
171175
TBase::SetSecurityToken(TString(clientCertificates.front()));
172176
}
173177
}
174-
Initialize(schemeData);
178+
Initialize(schemeData, rootAttributes);
175179
}
176180

177181
void Bootstrap(const TActorContext& ctx) {
@@ -614,11 +618,11 @@ class TGrpcRequestCheckActor
614618

615619
// default behavior - attributes in schema
616620
template <typename TEvent>
617-
void TGrpcRequestCheckActor<TEvent>::InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
621+
void TGrpcRequestCheckActor<TEvent>::InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, const TVector<std::pair<TString, TString>>& rootAttributes) {
618622
for (const auto& attr : schemeData.GetPathDescription().GetUserAttributes()) {
619623
Attributes_.emplace_back(std::make_pair(attr.GetKey(), attr.GetValue()));
620624
}
621-
InitializeAttributesFromSchema(schemeData);
625+
InitializeAttributesFromSchema(schemeData, rootAttributes);
622626
}
623627

624628
template<typename T>
@@ -662,9 +666,10 @@ IActor* CreateGrpcRequestCheckActor(
662666
TAutoPtr<TEventHandle<TEvent>> request,
663667
IGRpcProxyCounters::TPtr counters,
664668
bool skipCheckConnectRights,
669+
const TVector<std::pair<TString, TString>>& rootAttributes,
665670
const IFacilityProvider* facilityProvider) {
666671

667-
return new TGrpcRequestCheckActor<TEvent>(owner, schemeData, std::move(securityObject), std::move(request), counters, skipCheckConnectRights, facilityProvider);
672+
return new TGrpcRequestCheckActor<TEvent>(owner, schemeData, std::move(securityObject), std::move(request), counters, skipCheckConnectRights, facilityProvider, rootAttributes);
668673
}
669674

670675
}

ydb/core/grpc_services/grpc_request_proxy.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,25 @@ class TGRpcRequestProxyImpl
227227
}
228228

229229
if (database) {
230+
TVector<std::pair<TString, TString>> rootAttributes;
231+
auto rootIt = Databases.find(RootDatabase);
232+
if (rootIt == Databases.end() || !rootIt->second.IsDatabaseReady() || !rootIt->second.SchemeBoardResult) {
233+
Counters->IncDatabaseUnavailableCounter();
234+
const TString error = "Grpc proxy is not ready to accept request, root database unknown";
235+
LOG_ERROR(ctx, NKikimrServices::GRPC_SERVER, error);
236+
const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::YDB_DB_NOT_READY, error);
237+
requestBaseCtx->RaiseIssue(issue);
238+
requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::UNAVAILABLE);
239+
requestBaseCtx->FinishSpan();
240+
return;
241+
}
242+
243+
const auto& schemeData = rootIt->second.SchemeBoardResult->DescribeSchemeResult;
244+
rootAttributes.reserve(schemeData.GetPathDescription().UserAttributesSize());
245+
for (const auto& attr : schemeData.GetPathDescription().GetUserAttributes()) {
246+
rootAttributes.emplace_back(std::make_pair(attr.GetKey(), attr.GetValue()));
247+
}
248+
230249
if (database->SchemeBoardResult) {
231250
const auto& domain = database->SchemeBoardResult->DescribeSchemeResult.GetPathDescription().GetDomainDescription();
232251
if (domain.HasResourcesDomainKey() && !skipResourceCheck && DynamicNode) {
@@ -272,6 +291,7 @@ class TGRpcRequestProxyImpl
272291
event.Release(),
273292
Counters,
274293
skipCheckConnectRigths,
294+
rootAttributes,
275295
this));
276296
return;
277297
}

ydb/core/grpc_services/grpc_request_proxy_simple.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class TGRpcRequestProxySimple
132132

133133
{
134134
TSchemeBoardEvents::TDescribeSchemeResult schemeData;
135-
Register(CreateGrpcRequestCheckActor<TEvent>(SelfId(), schemeData, nullptr, event.Release(), Counters, false, this));
135+
Register(CreateGrpcRequestCheckActor<TEvent>(SelfId(), schemeData, nullptr, event.Release(), Counters, false, {}, this));
136136
return;
137137
}
138138

ydb/core/protos/auth.proto

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ message TAuthConfig {
5858
optional string NodeRegistrationToken = 82 [default = "root@builtin", (Ydb.sensitive) = true];
5959
optional TPasswordComplexity PasswordComplexity = 83;
6060
optional TAccountLockout AccountLockout = 84;
61-
optional string ClusterAccessResourceId = 85 [default = "gizmo"];
6261
}
6362

6463
message TUserRegistryConfig {

ydb/core/security/ticket_parser_impl.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ class TTicketParserImpl : public TActorBootstrapped<TDerived> {
462462
pathsContainer->mutable_resource_path()->add_path()->set_id(id);
463463
}
464464

465-
static void AddNebiusContainerId(nebius::iam::v1::AuthorizeCheck* pathsContainer, const TString& id) {
465+
static void SetNebiusContainerId(nebius::iam::v1::AuthorizeCheck* pathsContainer, const TString& id) {
466466
pathsContainer->set_container_id(id);
467467
}
468468

@@ -474,16 +474,17 @@ class TTicketParserImpl : public TActorBootstrapped<TDerived> {
474474
AddNebiusResourcePath(pathsContainer, databaseId);
475475
}
476476

477-
// Use attribute "folder_id" as container id that contains our database
478-
// IAM can link roles for containers hierarchy
479-
if (const auto folderId = record.GetAttributeValue(permission, "folder_id"); folderId) {
480-
AddNebiusContainerId(pathsContainer, folderId);
481-
}
482-
483477
// Use attribute "gizmo_id" as container id that contains cluster access resource
484478
// IAM can link roles for cluster access resource
479+
// Note: "gizmo_id" and "folder_id" are always sent in separate TEvAuthorizeTicket requests
485480
if (const auto gizmoId = record.GetAttributeValue(permission, "gizmo_id"); gizmoId) {
486-
AddNebiusContainerId(pathsContainer, gizmoId);
481+
SetNebiusContainerId(pathsContainer, gizmoId);
482+
}
483+
484+
// Use attribute "folder_id" as container id that contains our database
485+
// IAM can link roles for containers hierarchy
486+
if (const auto folderId = record.GetAttributeValue(permission, "folder_id"); folderId) {
487+
SetNebiusContainerId(pathsContainer, folderId);
487488
}
488489
}
489490

0 commit comments

Comments
 (0)