-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Mathis Joffre <[email protected]>
- Loading branch information
0 parents
commit b7a9d4f
Showing
16 changed files
with
3,105 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
### JetBrains template | ||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider | ||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||
|
||
# User-specific stuff | ||
.idea/**/workspace.xml | ||
.idea/**/tasks.xml | ||
.idea/**/usage.statistics.xml | ||
.idea/**/dictionaries | ||
.idea/**/shelf | ||
|
||
# Generated files | ||
.idea/**/contentModel.xml | ||
|
||
# Sensitive or high-churn files | ||
.idea/**/dataSources/ | ||
.idea/**/dataSources.ids | ||
.idea/**/dataSources.local.xml | ||
.idea/**/sqlDataSources.xml | ||
.idea/**/dynamic.xml | ||
.idea/**/uiDesigner.xml | ||
.idea/**/dbnavigator.xml | ||
|
||
# Gradle | ||
.idea/**/gradle.xml | ||
.idea/**/libraries | ||
|
||
# Gradle and Maven with auto-import | ||
# When using Gradle or Maven with auto-import, you should exclude module files, | ||
# since they will be recreated, and may cause churn. Uncomment if using | ||
# auto-import. | ||
# .idea/artifacts | ||
# .idea/compiler.xml | ||
# .idea/jarRepositories.xml | ||
# .idea/modules.xml | ||
# .idea/*.iml | ||
# .idea/modules | ||
# *.iml | ||
# *.ipr | ||
|
||
# CMake | ||
cmake-build-*/ | ||
|
||
# Mongo Explorer plugin | ||
.idea/**/mongoSettings.xml | ||
|
||
# File-based project format | ||
*.iws | ||
|
||
# IntelliJ | ||
out/ | ||
|
||
# mpeltonen/sbt-idea plugin | ||
.idea_modules/ | ||
|
||
# JIRA plugin | ||
atlassian-ide-plugin.xml | ||
|
||
# Cursive Clojure plugin | ||
.idea/replstate.xml | ||
|
||
# Crashlytics plugin (for Android Studio and IntelliJ) | ||
com_crashlytics_export_strings.xml | ||
crashlytics.properties | ||
crashlytics-build.properties | ||
fabric.properties | ||
|
||
# Editor-based Rest Client | ||
.idea/httpRequests | ||
|
||
# Android studio 3.1+ serialized cache file | ||
.idea/caches/build_file_checksums.ser | ||
|
||
### Go template | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, built with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Dependency directories (remove the comment below to include it) | ||
# vendor/ | ||
|
||
/.idea/vcs.xml | ||
/.idea/.gitignore | ||
/.idea/modules.xml | ||
/.idea/opa-middleware.iml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Open Policy Agent Gin Middleware | ||
|
||
This middleware integrates Open Policy Agent (OPA) to your gin 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 | ||
|
||
```bash | ||
go get github.com/Joffref/opa-middleware | ||
``` | ||
|
||
## Usage | ||
### Local policy engine | ||
```go | ||
package main | ||
|
||
import ( | ||
"github.com/Joffref/gin-opa-middleware" | ||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
var policy = ` | ||
package example.authz | ||
default allow := false | ||
allow { | ||
input.method == "GET" | ||
}` | ||
|
||
func main() { | ||
r := gin.Default() | ||
r.Use(opa.Middleware(context.Background(), &opa.Config{ | ||
Policy: policy, | ||
Query: "data.example.authz.allow", | ||
InputCreationMethod: func(c *gin.Context) (map[string]interface{}, error) { | ||
return map[string]interface{}{ | ||
"method": c.Request.Method, | ||
}, nil | ||
}, | ||
ExceptedResult: true, | ||
DeniedStatusCode: 403, | ||
Debug: true, | ||
Logger: log.New(gin.DefaultWriter, "[opa] ", log.LstdFlags), | ||
})) | ||
r.GET("/", func(c *gin.Context) { | ||
c.String(200, "Hello World!") | ||
}) | ||
r.Run() | ||
} | ||
``` | ||
### Remote policy engine | ||
```go | ||
package main | ||
|
||
import ( | ||
"github.com/Joffref/gin-opa-middleware" | ||
"github.com/gin-gonic/gin" | ||
) | ||
func main() { | ||
r := gin.Default() | ||
r.Use(opa.Middleware(context.Background(), &opa.Config{ | ||
URL: "http://localhost:8181", | ||
Query: "data.example.authz.allow", | ||
InputCreationMethod: func(c *gin.Context) (map[string]interface{}, error) { | ||
return map[string]interface{}{ | ||
"method": c.Request.Method, | ||
}, nil | ||
}, | ||
ExceptedResult: true, | ||
DeniedStatusCode: 403, | ||
Debug: true, | ||
Logger: log.New(gin.DefaultWriter, "[opa] ", log.LstdFlags), | ||
})) | ||
r.GET("/", func(c *gin.Context) { | ||
c.String(200, "Hello World!") | ||
}) | ||
err := r.Run(":8080") | ||
if err != nil { | ||
return | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package config | ||
|
||
import ( | ||
"errors" | ||
"github.com/open-policy-agent/opa/rego" | ||
"log" | ||
"net/http" | ||
"time" | ||
) | ||
|
||
// Config is the configuration for the middleware. | ||
type Config struct { | ||
// URL is the URL of the OPA server, if not set Middleware will use Policy field. | ||
// You must set either URL or Policy. | ||
URL string `json:"url,omitempty"` | ||
|
||
// Policy is the policy document to use, if not set Middleware will use URL field. | ||
// You must set either URL or Policy. | ||
Policy string `json:"policy,omitempty"` | ||
|
||
instantiatedPolicy *rego.PreparedEvalQuery | ||
|
||
// Query is the name of the policy to query. | ||
Query string `json:"query,omitempty"` | ||
|
||
// InputCreationMethod is a function that returns the value to be sent to the OPA server. | ||
InputCreationMethod func(r *http.Request) (map[string]interface{}, error) `json:"binding_method,omitempty"` | ||
|
||
// ExceptedResult is the result that the OPA server should return if the request is allowed. | ||
// Default to true. At the moment only boolean values are supported. | ||
ExceptedResult bool `json:"excepted_result,omitempty"` | ||
|
||
// DeniedStatusCode is the status code that should be returned if the request is denied. | ||
DeniedStatusCode int `json:"denied_status,omitempty"` | ||
|
||
// DeniedMessage is the message that should be returned if the request is denied. | ||
DeniedMessage string `json:"denied_message,omitempty"` | ||
|
||
// Headers is a list of headers to send to the OPA server. | ||
// All headers are sent to the OPA server except those in the IgnoredHeaders list. | ||
Headers map[string]string `json:"headers,omitempty"` | ||
|
||
// IgnoredHeaders is a list of headers to ignore when sending to the OPA server. | ||
IgnoredHeaders []string `json:"excepted_headers,omitempty"` | ||
|
||
// Debug is a flag that enables debug mode. | ||
Debug bool `json:"debug,omitempty"` | ||
|
||
// Logger is the logger that is use when debug mode is enabled. | ||
// If not set, the default logger is used. | ||
Logger *log.Logger `json:"logger,omitempty"` | ||
|
||
// Timeout is the timeout for the request policy evaluation. | ||
// If not set, the default is 10 seconds. | ||
Timeout time.Duration `json:"timeout,omitempty"` | ||
} | ||
|
||
func (c *Config) Validate() error { | ||
if c.Debug { | ||
if c.Logger == nil { | ||
c.Logger = log.Default() | ||
} | ||
} | ||
c.ExceptedResult = true | ||
if c.Timeout == 0 { | ||
c.Timeout = 10 * time.Second | ||
} | ||
if c.URL == "" && c.Policy == "" { | ||
return errors.New("[opa-middleware] You must set either URL or Policy") | ||
} | ||
if c.URL != "" && c.Policy != "" { | ||
return errors.New("[opa-middleware] You must set either URL or Policy") | ||
} | ||
if c.InputCreationMethod == nil { | ||
return errors.New("[opa-middleware] You must set BindingMethod") | ||
} | ||
if c.ExceptedResult != true && c.ExceptedResult != false { | ||
return errors.New("[opa-middleware] You must set ExceptedResult") | ||
} | ||
if c.Query == "" { | ||
return errors.New("[opa-middleware] You must set Query") | ||
} | ||
return nil | ||
} |
Oops, something went wrong.