protoc-gen-authz

module
v0.0.0-...-af18c7d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 12, 2022 License: Apache-2.0

README

DEPRECATED : This repository is no longer maintained and has been moved to the protocel repository.

protoc-gen-authz

Coverage GoReportCard GitHub

About

protoc-gen-authz is an authorization plugin for the protocol buffers compiler protoc. It relies on the Common Expression Language specification for writing authorization rules and can use gRPC metadata against protobuf messages.

The only language supported is Go.

Installation

For installing the plugin, you can simply run the following command :

go install github.com/Neakxs/protoc-gen-authz/cmd/protoc-gen-go-authz

The binary will be placed in your $GOBIN location.

About CEL Environment

When writing rules, the following variables are avaible :

  • headers (map[string][]string type)
  • request (declared request message type)

The headers.get(string) receiver function has been added on the headers variable. It allows writing of easier rules by using the go func (http.Header) Get(string) function under the hood.

Usage

  1. Create protobuf definition
syntax = "proto3";

package service.v1;
option go_package = "github.com/Neakxs/protoc-gen-authz/example/service/v1";

import "authorize/authz.proto";
import "google/protobuf/empty.proto";

option (authorize.file) = {
    globals: {
        functions: [
            {
                key: 'canPong'
                value: '"X-Pong" in headers'
            }
        ]
    };
	rules: [
        {
            key: "service.v1.OrgService.Pong"
            value: { 
                expr: "canPong() && size(request.pong) > 0"
            }
        }
    ]
};

service OrgService {
    rpc Ping(PingRequest) returns (google.protobuf.Empty) {
        option (authorize.method).expr = '!canPong() && size(request.ping) > 0';
    };
    rpc Pong(PongRequest) returns (google.protobuf.Empty) {};
}

message PingRequest {
    string ping = 1;
}
message PongRequest {
    string pong = 1;
}
  1. Generate protobuf service
protoc \
    --go_out=. --go_opt=paths=source_relative \
    --go-grpc_out=. --go-grpc_out=paths=source_relative \
    --go-authz_out=. --go-authz_opt=paths=source_relative \
    github.com/org/proto/gen/go/service/v1/example.proto
  1. Implement gRPC service

  2. Add interceptors to your gRPC server

package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"net"
	"path"

	v1 "github.com/Neakxs/protoc-gen-authz/example/service/v1"
	"google.golang.org/grpc"
	"google.golang.org/protobuf/types/known/emptypb"
)

type orgServer struct {
	v1.UnimplementedOrgServiceServer
}

func (s *orgServer) Ping(context.Context, *v1.PingRequest) (*emptypb.Empty, error) {
	return &emptypb.Empty{}, nil
}

func (s *orgServer) Pong(context.Context, *v1.PongRequest) (*emptypb.Empty, error) {
	return &emptypb.Empty{}, nil
}

func main() {
	authzInterceptor, err := v1.NewOrgServiceAuthzInterceptor()
	if err != nil {
		panic(err)
	}
	srv := grpc.NewServer(
		grpc.UnaryInterceptor(authzInterceptor.GetUnaryServerInterceptor()),
		grpc.StreamInterceptor(authzInterceptor.GetStreamServerInterceptor()),
	)
	v1.RegisterOrgServiceServer(srv, &orgServer{})
	dir, err := ioutil.TempDir("/tmp", "*")
	if err != nil {
		panic(err)
	}
	fmt.Printf("Listening on unix://%s/unix.sock...\n", dir)
	lis, err := net.Listen("unix", path.Join(dir, "unix.sock"))
	if err != nil {
		panic(err)
	}
	if err := srv.Serve(lis); err != nil {
		panic(err)
	}
}
  1. Profit

Configuration

It is possible to use a configuration file for defining global functions across all your proto definitions.

With the example above, we can create a config.yml file :

version: v1
globals:
  functions:
    isAdmin: "x-admin" in context.metadata
rules:
  service.v1.OrgService.Pong:
    expr: "canPong() && size(request.pong) > 0"

You can then use it with the --go-authz_opt=config=path/to/config.yml option.

When the same function is defined inside a protobuf file and in the configuration, the protobuf one is used.

Directories

Path Synopsis
cmd
example
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL