From e8d5feb181766059429259ce3345ddb1f667ded5 Mon Sep 17 00:00:00 2001 From: Doug Fawley Date: Tue, 24 Dec 2024 03:33:29 -0800 Subject: [PATCH] rbac: add method name to :path in headers (#7965) --- internal/xds/rbac/rbac_engine.go | 3 +++ test/xds/xds_server_rbac_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/internal/xds/rbac/rbac_engine.go b/internal/xds/rbac/rbac_engine.go index 344052cb04fd..8f376c400333 100644 --- a/internal/xds/rbac/rbac_engine.go +++ b/internal/xds/rbac/rbac_engine.go @@ -219,6 +219,9 @@ func newRPCData(ctx context.Context) (*rpcData, error) { if !ok { return nil, errors.New("missing method in incoming context") } + // gRPC-Go strips :path from the headers given to the application, but RBAC should be + // able to match against it. + md[":path"] = []string{mn} // The connection is needed in order to find the destination address and // port of the incoming RPC Call. diff --git a/test/xds/xds_server_rbac_test.go b/test/xds/xds_server_rbac_test.go index 831f2512a96a..f05cd05e5fd9 100644 --- a/test/xds/xds_server_rbac_test.go +++ b/test/xds/xds_server_rbac_test.go @@ -478,6 +478,30 @@ func (s) TestRBACHTTPFilter(t *testing.T) { wantStatusEmptyCall: codes.PermissionDenied, wantStatusUnaryCall: codes.OK, }, + // This test tests an RBAC HTTP Filter which is configured to allow only + // RPC's with certain paths ("UnaryCall") via the ":path" header. Only + // unary calls passing through this RBAC HTTP Filter should proceed as + // normal, and any others should be denied. + { + name: "allow-certain-path-by-header", + rbacCfg: &rpb.RBAC{ + Rules: &v3rbacpb.RBAC{ + Action: v3rbacpb.RBAC_ALLOW, + Policies: map[string]*v3rbacpb.Policy{ + "certain-path": { + Permissions: []*v3rbacpb.Permission{ + {Rule: &v3rbacpb.Permission_Header{Header: &v3routepb.HeaderMatcher{Name: ":path", HeaderMatchSpecifier: &v3routepb.HeaderMatcher_ExactMatch{ExactMatch: "/grpc.testing.TestService/UnaryCall"}}}}, + }, + Principals: []*v3rbacpb.Principal{ + {Identifier: &v3rbacpb.Principal_Any{Any: true}}, + }, + }, + }, + }, + }, + wantStatusEmptyCall: codes.PermissionDenied, + wantStatusUnaryCall: codes.OK, + }, // This test that a RBAC Config with nil rules means that every RPC is // allowed. This maps to the line "If absent, no enforcing RBAC policy // will be applied" from the RBAC Proto documentation for the Rules