cel_authorization_engine.cc
Go to the documentation of this file.
1 // Copyright 2020 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
18 
19 #include <stddef.h>
20 
21 #include <algorithm>
22 #include <utility>
23 
24 #include "absl/memory/memory.h"
25 #include "absl/strings/string_view.h"
26 #include "absl/types/optional.h"
27 #include "absl/types/span.h"
28 #include "upb/upb.h"
29 
30 #include <grpc/support/log.h>
31 
32 namespace grpc_core {
33 
34 namespace {
35 
36 // Symbols for traversing Envoy Attributes
37 constexpr char kUrlPath[] = "url_path";
38 constexpr char kHost[] = "host";
39 constexpr char kMethod[] = "method";
40 constexpr char kHeaders[] = "headers";
41 constexpr char kSourceAddress[] = "source_address";
42 constexpr char kSourcePort[] = "source_port";
43 constexpr char kDestinationAddress[] = "destination_address";
44 constexpr char kDestinationPort[] = "destination_port";
45 constexpr char kSpiffeId[] = "spiffe_id";
46 constexpr char kCertServerName[] = "cert_server_name";
47 
48 } // namespace
49 
50 std::unique_ptr<CelAuthorizationEngine>
52  const std::vector<envoy_config_rbac_v3_RBAC*>& rbac_policies) {
53  if (rbac_policies.empty() || rbac_policies.size() > 2) {
55  "Invalid rbac policies vector. Must contain either one or two rbac "
56  "policies.");
57  return nullptr;
58  } else if (rbac_policies.size() == 2 &&
59  (envoy_config_rbac_v3_RBAC_action(rbac_policies[0]) != kDeny ||
60  envoy_config_rbac_v3_RBAC_action(rbac_policies[1]) != kAllow)) {
62  "Invalid rbac policies vector. Must contain one deny \
63  policy and one allow policy, in that order.");
64  return nullptr;
65  } else {
66  return absl::make_unique<CelAuthorizationEngine>(rbac_policies);
67  }
68 }
69 
71  const std::vector<envoy_config_rbac_v3_RBAC*>& rbac_policies) {
72  for (const auto& rbac_policy : rbac_policies) {
73  // Extract array of policies and store their condition fields in either
74  // allow_if_matched_ or deny_if_matched_, depending on the policy action.
75  upb::Arena temp_arena;
76  size_t policy_num = kUpb_Map_Begin;
77  const envoy_config_rbac_v3_RBAC_PoliciesEntry* policy_entry;
78  while ((policy_entry = envoy_config_rbac_v3_RBAC_policies_next(
79  rbac_policy, &policy_num)) != nullptr) {
80  const upb_StringView policy_name_strview =
82  const std::string policy_name(policy_name_strview.data,
83  policy_name_strview.size);
84  const envoy_config_rbac_v3_Policy* policy =
86  const google_api_expr_v1alpha1_Expr* condition =
88  // Parse condition to make a pointer tied to the lifetime of arena_.
89  size_t serial_len;
90  const char* serialized = google_api_expr_v1alpha1_Expr_serialize(
91  condition, temp_arena.ptr(), &serial_len);
92  const google_api_expr_v1alpha1_Expr* parsed_condition =
93  google_api_expr_v1alpha1_Expr_parse(serialized, serial_len,
94  arena_.ptr());
95  if (envoy_config_rbac_v3_RBAC_action(rbac_policy) == kAllow) {
96  allow_if_matched_.insert(std::make_pair(policy_name, parsed_condition));
97  } else {
98  deny_if_matched_.insert(std::make_pair(policy_name, parsed_condition));
99  }
100  }
101  }
102 }
103 
104 std::unique_ptr<mock_cel::Activation> CelAuthorizationEngine::CreateActivation(
105  const EvaluateArgs& args) {
106  std::unique_ptr<mock_cel::Activation> activation;
107  for (const auto& elem : envoy_attributes_) {
108  if (elem == kUrlPath) {
109  absl::string_view url_path(args.GetPath());
110  if (!url_path.empty()) {
111  activation->InsertValue(kUrlPath,
113  }
114  } else if (elem == kHost) {
115  absl::string_view host(args.GetAuthority());
116  if (!host.empty()) {
117  activation->InsertValue(kHost,
119  }
120  } else if (elem == kMethod) {
121  absl::string_view method(args.GetMethod());
122  if (!method.empty()) {
123  activation->InsertValue(kMethod,
125  }
126  } else if (elem == kHeaders) {
127  std::vector<std::pair<mock_cel::CelValue, mock_cel::CelValue>>
128  header_items;
129  for (const auto& header_key : header_keys_) {
130  std::string temp_value;
131  absl::optional<absl::string_view> header_value =
132  args.GetHeaderValue(header_key, &temp_value);
133  if (header_value.has_value()) {
134  header_items.push_back(
135  std::pair<mock_cel::CelValue, mock_cel::CelValue>(
137  mock_cel::CelValue::CreateStringView(*header_value)));
138  }
139  }
141  absl::Span<std::pair<mock_cel::CelValue, mock_cel::CelValue>>(
142  header_items));
143  activation->InsertValue(kHeaders,
145  } else if (elem == kSourceAddress) {
146  absl::string_view source_address(args.GetPeerAddressString());
147  if (!source_address.empty()) {
148  activation->InsertValue(
149  kSourceAddress,
150  mock_cel::CelValue::CreateStringView(source_address));
151  }
152  } else if (elem == kSourcePort) {
153  activation->InsertValue(
154  kSourcePort, mock_cel::CelValue::CreateInt64(args.GetPeerPort()));
155  } else if (elem == kDestinationAddress) {
156  absl::string_view destination_address(args.GetLocalAddressString());
157  if (!destination_address.empty()) {
158  activation->InsertValue(
159  kDestinationAddress,
160  mock_cel::CelValue::CreateStringView(destination_address));
161  }
162  } else if (elem == kDestinationPort) {
163  activation->InsertValue(kDestinationPort, mock_cel::CelValue::CreateInt64(
164  args.GetLocalPort()));
165  } else if (elem == kSpiffeId) {
166  absl::string_view spiffe_id(args.GetSpiffeId());
167  if (!spiffe_id.empty()) {
168  activation->InsertValue(
169  kSpiffeId, mock_cel::CelValue::CreateStringView(spiffe_id));
170  }
171  } else if (elem == kCertServerName) {
172  absl::string_view cert_server_name(args.GetCommonName());
173  if (!cert_server_name.empty()) {
174  activation->InsertValue(
175  kCertServerName,
176  mock_cel::CelValue::CreateStringView(cert_server_name));
177  }
178  } else {
180  "Error: Authorization engine does not support evaluating "
181  "attribute %s.",
182  elem.c_str());
183  }
184  }
185  return activation;
186 }
187 
188 } // namespace grpc_core
grpc_core::EvaluateArgs
Definition: evaluate_args.h:34
log.h
kUpb_Map_Begin
#define kUpb_Map_Begin
Definition: upb/upb/upb.h:329
absl::Span
Definition: abseil-cpp/absl/types/span.h:152
grpc_core
Definition: call_metric_recorder.h:31
envoy_config_rbac_v3_Policy
struct envoy_config_rbac_v3_Policy envoy_config_rbac_v3_Policy
Definition: config/rbac/v3/rbac.upb.h:33
upb_StringView::data
const char * data
Definition: upb/upb/upb.h:73
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
envoy_config_rbac_v3_RBAC_policies_next
const UPB_INLINE envoy_config_rbac_v3_RBAC_PoliciesEntry * envoy_config_rbac_v3_RBAC_policies_next(const envoy_config_rbac_v3_RBAC *msg, size_t *iter)
Definition: config/rbac/v3/rbac.upb.h:123
elem
Timer elem
Definition: event_engine/iomgr_event_engine/timer_heap_test.cc:109
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
grpc_core::CelAuthorizationEngine::kAllow
@ kAllow
Definition: cel_authorization_engine.h:65
envoy_config_rbac_v3_RBAC_PoliciesEntry
struct envoy_config_rbac_v3_RBAC_PoliciesEntry envoy_config_rbac_v3_RBAC_PoliciesEntry
Definition: config/rbac/v3/rbac.upb.h:32
envoy_config_rbac_v3_RBAC_PoliciesEntry_key
UPB_INLINE upb_StringView envoy_config_rbac_v3_RBAC_PoliciesEntry_key(const envoy_config_rbac_v3_RBAC_PoliciesEntry *msg)
Definition: config/rbac/v3/rbac.upb.h:143
grpc_core::CelAuthorizationEngine::allow_if_matched_
std::map< const std::string, const google_api_expr_v1alpha1_Expr * > allow_if_matched_
Definition: cel_authorization_engine.h:75
grpc_core::CelAuthorizationEngine::CreateActivation
std::unique_ptr< mock_cel::Activation > CreateActivation(const EvaluateArgs &args)
Definition: cel_authorization_engine.cc:104
grpc_core::CelAuthorizationEngine::CelAuthorizationEngine
CelAuthorizationEngine(const std::vector< envoy_config_rbac_v3_RBAC * > &rbac_policies)
Definition: cel_authorization_engine.cc:70
grpc_core::CelAuthorizationEngine::kDeny
@ kDeny
Definition: cel_authorization_engine.h:66
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
envoy_config_rbac_v3_RBAC_action
UPB_INLINE int32_t envoy_config_rbac_v3_RBAC_action(const envoy_config_rbac_v3_RBAC *msg)
Definition: config/rbac/v3/rbac.upb.h:108
absl::optional::has_value
constexpr bool has_value() const noexcept
Definition: abseil-cpp/absl/types/optional.h:461
envoy_config_rbac_v3_Policy_condition
UPB_INLINE const struct google_api_expr_v1alpha1_Expr * envoy_config_rbac_v3_Policy_condition(const envoy_config_rbac_v3_Policy *msg)
Definition: config/rbac/v3/rbac.upb.h:216
upb_StringView::size
size_t size
Definition: upb/upb/upb.h:74
upb.h
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
absl::optional< absl::string_view >
grpc_core::CelAuthorizationEngine::arena_
upb::Arena arena_
Definition: cel_authorization_engine.h:76
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
cel_authorization_engine.h
grpc_core::CelAuthorizationEngine::envoy_attributes_
absl::flat_hash_set< std::string > envoy_attributes_
Definition: cel_authorization_engine.h:77
grpc_core::mock_cel::ContainerBackedMapImpl::Create
static std::unique_ptr< CelMap > Create(absl::Span< std::pair< CelValue, CelValue >>)
Definition: cel_value.h:94
upb::Arena::ptr
upb_Arena * ptr()
Definition: upb.hpp:76
upb::Arena
Definition: upb.hpp:68
upb_StringView
Definition: upb/upb/upb.h:72
envoy_config_rbac_v3_RBAC_PoliciesEntry_value
const UPB_INLINE envoy_config_rbac_v3_Policy * envoy_config_rbac_v3_RBAC_PoliciesEntry_value(const envoy_config_rbac_v3_RBAC_PoliciesEntry *msg)
Definition: config/rbac/v3/rbac.upb.h:151
grpc_core::CelAuthorizationEngine::header_keys_
absl::flat_hash_set< std::string > header_keys_
Definition: cel_authorization_engine.h:78
grpc_core::CelAuthorizationEngine::deny_if_matched_
std::map< const std::string, const google_api_expr_v1alpha1_Expr * > deny_if_matched_
Definition: cel_authorization_engine.h:73
grpc_core::CelAuthorizationEngine::CreateCelAuthorizationEngine
static std::unique_ptr< CelAuthorizationEngine > CreateCelAuthorizationEngine(const std::vector< envoy_config_rbac_v3_RBAC * > &rbac_policies)
Definition: cel_authorization_engine.cc:51
google_api_expr_v1alpha1_Expr
struct google_api_expr_v1alpha1_Expr google_api_expr_v1alpha1_Expr
Definition: syntax.upb.h:38
grpc_core::mock_cel::CelValue::CreateInt64
static CelValue CreateInt64(int64_t)
Definition: cel_value.h:68
absl::string_view::empty
constexpr bool empty() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:292
google_api_expr_v1alpha1_Expr_parse
UPB_INLINE google_api_expr_v1alpha1_Expr * google_api_expr_v1alpha1_Expr_parse(const char *buf, size_t size, upb_Arena *arena)
Definition: syntax.upb.h:154
method
NSString * method
Definition: ProtoMethod.h:28
grpc_core::mock_cel::CelValue::CreateMap
static CelValue CreateMap(const CelMap *)
Definition: cel_value.h:80
grpc_core::mock_cel::CelValue::CreateStringView
static CelValue CreateStringView(absl::string_view)
Definition: cel_value.h:72
google_api_expr_v1alpha1_Expr_serialize
UPB_INLINE char * google_api_expr_v1alpha1_Expr_serialize(const google_api_expr_v1alpha1_Expr *msg, upb_Arena *arena, size_t *len)
Definition: syntax.upb.h:173
port_platform.h
grpc_core::CelAuthorizationEngine::headers_
std::unique_ptr< mock_cel::CelMap > headers_
Definition: cel_authorization_engine.h:79


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:58:43