opamiddleware

package module
v1.0.4 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2023 License: MIT Imports: 7 Imported by: 1

README

Open Policy Agent Middleware

This middleware integrates Open Policy Agent (OPA) to your http/gin/fiber app. You can use it to enforce policies on endpoints. You can use OPA as local policy engine, or as a remote policy engine.

Installation

go get github.com/Joffref/opa-middleware

Usage Generic with OPA and HTTP

Local based policy engine
package main

import (
	"github.com/Joffref/opa-middleware"
	"github.com/Joffref/opa-middleware/config"
	"net/http"
)

var Policy = `
package policy

default allow = false

allow {
	input.path = "/api/v1/users"
	input.method = "GET"
}`

type H struct {
	Name string
}

func (h *H) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello World : " + h.Name))
}

func main() {
	handler, err := opamiddleware.NewHTTPMiddleware(
		&config.Config{
			Policy: Policy,
			Query:  "data.policy.allow",
			InputCreationMethod: func(r *http.Request) (map[string]interface{}, error) {
				return map[string]interface{}{
					"path":   r.URL.Path,
					"method": r.Method,
				}, nil
			},
			ExceptedResult:   true,
			DeniedStatusCode: 403,
			DeniedMessage:    "Forbidden",
		},
		&H{
			Name: "John Doe",
		},
	)
	if err != nil {
		panic(err)
	}
	http.HandleFunc("/", handler.ServeHTTP)
	err = http.ListenAndServe(":8080", nil)
	if err != nil {
		return
	}
}
Remote based policy engine

The policy is the same as above, but the policy is stored in a remote server.

package main

import (
	"github.com/Joffref/opa-middleware"
	"github.com/Joffref/opa-middleware/config"
	"net/http"
)

type H struct {
	Name string
}

func (h *H) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Hello World : " + h.Name))
}

func main() {
	handler, err := opamiddleware.NewHTTPMiddleware(
		&config.Config{
			URL: "http://localhost:8181/",
			Query:  "data.policy.allow",
			InputCreationMethod: func(r *http.Request) (map[string]interface{}, error) {
				return map[string]interface{}{
					"path":   r.URL.Path,
					"method": r.Method,
				}, nil
			},
			ExceptedResult:   true,
			DeniedStatusCode: 403,
			DeniedMessage:    "Forbidden",
		},
		&H{
			Name: "John Doe",
		},
	)
	if err != nil {
		panic(err)
	}
	http.HandleFunc("/", handler.ServeHTTP)
	err = http.ListenAndServe(":8080", nil)
	if err != nil {
		return
	}
}

Usage with GIN

package main

import (
	"github.com/Joffref/opa-middleware"
	"github.com/Joffref/opa-middleware/config"
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	middleware, err := opamiddleware.NewGinMiddleware(
		&config.Config{
			URL:           "http://localhost:8181/",
			Query:            "data.policy.allow",
			ExceptedResult:   true,
			DeniedStatusCode: 403,
			DeniedMessage:    "Forbidden",
		},
		func(c *gin.Context) (map[string]interface{}, error) {
			return map[string]interface{}{
				"path":   c.Request.URL.Path,
				"method": c.Request.Method,
			}, nil
		},
	)
	if err != nil {
		return
	}
	r.Use(middleware.Use())
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run(":8080")
}

Usage with Fiber

package main

import (
	"github.com/Joffref/opa-middleware"
	"github.com/Joffref/opa-middleware/config"
	"github.com/gofiber/fiber/v2"
)

func main() {
	app := fiber.New()
	middleware, err := opamiddleware.NewFiberMiddleware(
		&config.Config{
			URL:           "http://localhost:8181/",
			Query:            "data.policy.allow",
			ExceptedResult:   true,
			DeniedStatusCode: 403,
			DeniedMessage:    "Forbidden",
		},
		func(c *fiber.Ctx) (map[string]interface{}, error) {
			return map[string]interface{}{
				"path":   c.Path(),
				"method": c.Method(),
			}, nil
		},
	)
	if err != nil {
		return
	}
	app.Use(middleware.Use())
	app.Get("/ping", func(c *fiber.Ctx) error {
		err := c.JSON("pong")
		if err != nil {
			return err
		}
		return nil
	})
	app.Listen(":8080")
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FiberInputCreationMethod

type FiberInputCreationMethod func(c *fiber.Ctx) (map[string]interface{}, error)

FiberInputCreationMethod is the method that is used to create the input for the policy.

type FiberMiddleware

type FiberMiddleware struct {
	// Config is the configuration for the middleware.
	Config *config.Config
	// InputCreationMethod is a function that returns the value to be sent to the OPA server.
	InputCreationMethod FiberInputCreationMethod `json:"binding_method,omitempty"`
}

func NewFiberMiddleware

func NewFiberMiddleware(cfg *config.Config, input FiberInputCreationMethod) (*FiberMiddleware, error)

NewFiberMiddleware is the constructor for the opa fiber middleware.

func (*FiberMiddleware) Use

func (g *FiberMiddleware) Use() func(c *fiber.Ctx) error

Use returns the handler for the middleware that is used by fiber to evaluate the request against the policy.

type GinInputCreationMethod

type GinInputCreationMethod func(c *gin.Context) (map[string]interface{}, error)

type GinMiddleware

type GinMiddleware struct {
	Config *config.Config
	// InputCreationMethod is a function that returns the value to be sent to the OPA server.
	InputCreationMethod GinInputCreationMethod `json:"binding_method,omitempty"`
}

func NewGinMiddleware

func NewGinMiddleware(cfg *config.Config, input GinInputCreationMethod) (*GinMiddleware, error)

NewGinMiddleware is the constructor for the opa gin middleware.

func (*GinMiddleware) Use

func (g *GinMiddleware) Use() func(c *gin.Context)

Use returns the handler for the middleware that is used by gin to evaluate the request against the policy.

type HTTPMiddleware

type HTTPMiddleware struct {
	Config *config.Config
	// Next is the next handler in the request chain.
	Next http.Handler
}

HTTPMiddleware is the middleware for http requests

func NewHTTPMiddleware

func NewHTTPMiddleware(cfg *config.Config, next http.Handler) (*HTTPMiddleware, error)

NewHTTPMiddleware returns a new HTTPMiddleware

func (*HTTPMiddleware) ServeHTTP

func (h *HTTPMiddleware) ServeHTTP(rw http.ResponseWriter, req *http.Request)

ServeHTTP serves the http request. Act as Use acts in other frameworks.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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