Skip to content

Instantly share code, notes, and snippets.

@gcmurphy
Created February 21, 2022 03:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gcmurphy/39c0d05427e3026207f1593b9400df00 to your computer and use it in GitHub Desktop.
Save gcmurphy/39c0d05427e3026207f1593b9400df00 to your computer and use it in GitHub Desktop.
experiment using rego as authorization middleware
package main
import(
"context"
"log"
"time"
"os"
"github.com/gofiber/fiber/v2"
"github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/rego"
)
var compiler *ast.Compiler
const (
examplePolicy = `
package example
default allow = false
allow {
input.role == "admin"
}
allow {
input.method == "GET"
input.path == "/"
}
`)
func main(){
compiler, err := ast.CompileModules(map[string]string {
"example.rego": examplePolicy,
})
if err != nil {
log.Fatalf("failed to compile built-in authorization policy - %s", err)
}
app := fiber.New()
app.Use(func (c *fiber.Ctx) error {
ctx, timeout := context.WithTimeout(context.Background(), time.Duration(5 * time.Second))
defer timeout()
role := os.Getenv("ROLE")
if role == "" {
role = "user"
}
rego := rego.New(
rego.Query("data.example.allow"),
rego.Compiler(compiler),
rego.Input(
map[string]interface{}{
"role": role,
"method": c.Method(),
"path": c.Path(),
},
),
)
rs, err := rego.Eval(ctx)
if err != nil {
log.Printf("unexpected error: %s", err)
return err
}
if !rs.Allowed(){
return c.SendStatus(403)
}
return c.Next()
})
app.Get("/", func (c *fiber.Ctx) error {
return c.SendString("access granted")
})
app.Get("/admin_only", func (c *fiber.Ctx) error {
return c.SendString("admin area access granted")
})
app.Listen(":3000")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment