This repository contains an authorization middleware for the Fiber framework in Go, allowing you to check if a user is authorized to perform a specific action on a resource. The middleware sends a POST request to an authorization service, passing the user's details, resource, and desired action.
Repository: lib-auth
go get -u github.com/LerianStudio/lib-auth/v2
In your environment configuration or .env file, set the following environment variables:
PLUGIN_AUTH_ADDRESS=http://localhost:4000 PLUGIN_AUTH_ENABLED=true
In your config.go file, configure the environment variables for the Auth Service:
type Config struct { Address string `env:"PLUGIN_AUTH_ADDRESS"` Enabled bool `env:"PLUGIN_AUTH_ENABLED"` } cfg := &Config{} logger := zap.InitializeLogger()
import "github.com/LerianStudio/lib-auth/v2/auth/middleware" authClient := middleware.NewAuthClient(cfg.Address, cfg.Enabled, &logger)
func NewRoutes(auth *authMiddleware.AuthClient, [...]) *fiber.App { f := fiber.New(fiber.Config{ DisableStartupMessage: true, }) applicationName := os.Getenv("APPLICATION_NAME") // Applications routes f.Get("/v1/applications", auth.Authorize(applicationName, "ledger", "get"), applicationHandler.GetApplications) }
The Authorize function:
- Receives the
sub(user),resource(resource), andaction(desired action). - Sends a POST request to the authorization service.
- Checks if the response indicates that the user is authorized.
- Allows the normal application flow or returns a 403 (Forbidden) error.
POST /v1/authorize Content-Type: application/json Authorization: Bearer your_token_here { "sub": "lerian/userId", "resource": "resourceName", "action": "get" }
The authorization service should return a JSON response in the following format:
{
"authorized": true,
"timestamp": "2025εΉ΄03ζ03ζ₯T12:00:00Z"
}Secure a gRPC server with the unary interceptor using per-method policies. It reuses the same auth service and tracing used by the HTTP middleware.
import ( "context" "google.golang.org/grpc" "github.com/LerianStudio/lib-auth/v2/auth/middleware" ) // Create the auth client once (same as HTTP) authClient := middleware.NewAuthClient(cfg.Address, cfg.Enabled, &logger) // Map full gRPC method names to authorization policies policies := middleware.PolicyConfig{ MethodPolicies: map[string]middleware.Policy{ "/balance.BalanceProto/CreateBalance": {Resource: "balances", Action: "post"}, }, // Constant subject base, matching HTTP usage (e.g., "midaz") SubResolver: func(ctx context.Context, _ string, _ any) (string, error) { return "midaz", nil }, } srv := grpc.NewServer( grpc.UnaryInterceptor(middleware.NewGRPCAuthUnaryPolicy(authClient, policies)), )
Notes:
- Keys in
MethodPoliciesmust be full method names in the form/package.Service/Method. - When
SubResolverreturns an empty string, the subject is derived from token claims. - If you already use multiple interceptors, prefer
grpc.ChainUnaryInterceptor(...)and include the auth interceptor alongside telemetry/logging.
The middleware captures and logs the following error types:
- Failure to create the request
- Failure to send the request
- Failure to read the response body
- Failure to deserialize the response JSON
- Errors from the authorization service (e.g., 401 Unauthorized, 403 Forbidden)
For questions or support, contact us at: contato@lerian.studio.