summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2022-05-17 21:43:05 -0600
committermo khan <mo@mokhan.ca>2022-05-17 21:43:05 -0600
commitc73082d32546d0da4ed3ded11e554e34f5628f73 (patch)
tree30215ebeca7ba4bf6b177bcdc2246f3202770a55
parent800d1273a2ae24899d11953140df55ec23412b2d (diff)
use casbin to enforce authz
-rw-r--r--cmd/api/main.go200
-rw-r--r--cmd/gw/main.go10
-rw-r--r--go.mod18
-rw-r--r--go.sum37
-rw-r--r--pkg/api/model.conf11
-rw-r--r--pkg/api/policy.csv3
6 files changed, 178 insertions, 101 deletions
diff --git a/cmd/api/main.go b/cmd/api/main.go
index ef28543..1ca5e28 100644
--- a/cmd/api/main.go
+++ b/cmd/api/main.go
@@ -11,46 +11,99 @@ import (
"path/filepath"
"time"
- jwtmiddleware "github.com/auth0/go-jwt-middleware/v2"
- "github.com/auth0/go-jwt-middleware/v2/jwks"
- "github.com/auth0/go-jwt-middleware/v2/validator"
+ "github.com/casbin/casbin/v2"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/cors"
+ "github.com/go-chi/jwtauth/v5"
"github.com/joho/godotenv"
+ "github.com/lestrrat-go/jwx/v2/jwk"
+ "github.com/lestrrat-go/jwx/v2/jwt"
"github.com/xlgmokha/api-auth0/pkg/x"
)
-func BuildJwtMiddleware(issuerURL *url.URL) *jwtmiddleware.JWTMiddleware {
- provider := jwks.NewCachingProvider(issuerURL, 5*time.Minute)
- jwtValidator := x.Must(validator.New(provider.KeyFunc, validator.RS256, issuerURL.String(), []string{os.Getenv("AUTH0_AUDIENCE")},
- validator.WithCustomClaims(func() validator.CustomClaims { return &x.CustomClaims{} }),
- validator.WithAllowedClockSkew(time.Minute),
- ))
-
- errHandler := func(w http.ResponseWriter, r *http.Request, err error) {
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(http.StatusUnauthorized)
- w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, err)))
+func ValidAudience(audiences []string) bool {
+ for _, aud := range audiences {
+ if aud == os.Getenv("AUTH0_AUDIENCE") {
+ return true
+ }
}
- return jwtmiddleware.New(
- jwtValidator.ValidateToken,
- jwtmiddleware.WithCredentialsOptional(true),
- jwtmiddleware.WithErrorHandler(errHandler),
- jwtmiddleware.WithValidateOnOptions(false),
- )
+ return false
}
-func Authorize(middleware *jwtmiddleware.JWTMiddleware, requiredPermissions ...x.Permission) func(http.Handler) http.Handler {
+func Authorizer(e *casbin.Enforcer, keySet jwk.Set) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- middleware.
- CheckJWT(next).
- ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "required_permissions", requiredPermissions)))
+ raw := jwtauth.TokenFromHeader(r)
+ if raw == "" {
+ w.WriteHeader(http.StatusUnauthorized)
+ w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, "missing token")))
+ return
+ }
+
+ token, err := jwt.ParseString(raw, jwt.WithKeySet(keySet))
+ if err != nil {
+ w.WriteHeader(http.StatusUnauthorized)
+ w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, err)))
+ return
+ }
+
+ if !ValidAudience(token.Audience()) {
+ w.WriteHeader(http.StatusUnauthorized)
+ w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, "invalid audience")))
+ return
+ }
+
+ if ok, _ := e.Enforce(token.Subject(), r.URL.Path, r.Method); ok {
+ fmt.Printf("pass: %v %v %v\n", token.Subject(), r.URL.Path, r.Method)
+ next.ServeHTTP(w, r)
+ } else {
+ fmt.Printf("fail: %v %v %v\n", token.Subject(), r.URL.Path, r.Method)
+ w.WriteHeader(http.StatusUnauthorized)
+ w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, http.StatusText(http.StatusUnauthorized))))
+ }
})
}
}
+// func BuildJwtMiddleware(issuerURL *url.URL) *jwtmiddleware.JWTMiddleware {
+// provider := jwks.NewCachingProvider(issuerURL, 5*time.Minute)
+// jwtValidator := x.Must(
+// validator.New(
+// provider.KeyFunc,
+// validator.RS256,
+// issuerURL.String(),
+// []string{os.Getenv("AUTH0_AUDIENCE")},
+// validator.WithAllowedClockSkew(time.Minute),
+// validator.WithCustomClaims(func() validator.CustomClaims {
+// return &x.CustomClaims{}
+// }),
+// ),
+// )
+
+// errHandler := func(w http.ResponseWriter, r *http.Request, err error) {
+// w.Header().Set("Content-Type", "application/json")
+// w.WriteHeader(http.StatusUnauthorized)
+// w.Write([]byte(fmt.Sprintf(`{"message":"%v"}`, err)))
+// }
+// return jwtmiddleware.New(
+// jwtValidator.ValidateToken,
+// jwtmiddleware.WithCredentialsOptional(true),
+// jwtmiddleware.WithErrorHandler(errHandler),
+// jwtmiddleware.WithValidateOnOptions(false),
+// )
+// }
+
+// func Authorize(middleware *jwtmiddleware.JWTMiddleware, requiredPermissions ...x.Permission) func(http.Handler) http.Handler {
+// return func(next http.Handler) http.Handler {
+// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+// middleware.
+// CheckJWT(next).
+// ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), "required_permissions", requiredPermissions)))
+// })
+// }
+// }
+
func readFixture(path string) []byte {
finalPath := filepath.Join(x.Must(os.Getwd()), "pkg/api/fixtures", path)
return x.Must(ioutil.ReadFile(finalPath))
@@ -60,116 +113,113 @@ func main() {
if err := godotenv.Load(); err != nil {
log.Fatal(err)
}
-
- r := chi.NewRouter()
- r.Use(middleware.RequestID)
- r.Use(middleware.RealIP)
- r.Use(middleware.Logger)
- r.Use(middleware.Recoverer)
- r.Use(middleware.Timeout(30 * time.Second))
- r.Use(cors.AllowAll().Handler)
-
- issuer := x.Must(url.Parse("https://" + os.Getenv("AUTH0_DOMAIN") + "/"))
- token := BuildJwtMiddleware(issuer)
-
- r.Route("/api", func(r chi.Router) {
- r.Get("/public", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ url := x.Must(url.Parse("https://" + os.Getenv("AUTH0_DOMAIN") + "/.well-known/jwks.json")).String()
+ cache := jwk.NewCache(context.Background())
+ cache.Register(url, jwk.WithMinRefreshInterval(15*time.Minute))
+ cache.Refresh(context.Background(), url)
+ keySet := jwk.NewCachedSet(cache, url)
+
+ router := chi.NewRouter()
+ router.Use(middleware.RequestID)
+ router.Use(middleware.RealIP)
+ router.Use(middleware.Logger)
+ router.Use(middleware.Recoverer)
+ router.Use(middleware.Timeout(30 * time.Second))
+ router.Use(middleware.AllowContentType("application/json"))
+ router.Use(middleware.Heartbeat("/health"))
+ router.Use(cors.AllowAll().Handler)
+ router.Use(Authorizer(x.Must(casbin.NewEnforcer("pkg/api/model.conf", "pkg/api/policy.csv")), keySet))
+
+ // issuer := x.Must(url.Parse("https://" + os.Getenv("AUTH0_DOMAIN") + "/"))
+ // token := BuildJwtMiddleware(issuer)
+
+ router.Route("/api", func(router chi.Router) {
+ router.Use(middleware.SetHeader("Content-Type", "application/json"))
+ router.Get("/public", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"message":"public"}`))
})
- r.Route("/users", func(r chi.Router) {
- r.Use(Authorize(token, "read:users"))
+ router.Route("/users", func(router chi.Router) {
+ // router.Use(Authorize(token, "read:users"))
- r.Get("/", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ router.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"message":"users"}`))
})
})
- r.Route("/incidents", func(r chi.Router) {
- r.Use(Authorize(token, "read:incidents"))
+ router.Route("/incidents", func(router chi.Router) {
+ // router.Use(Authorize(token, "read:incidents"))
- r.Get("/", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ router.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"message":"incidents"}`))
})
})
// vercel hosted ?
- r.Route("/auth", func(r chi.Router) {
- r.Get("/providers", func(w http.ResponseWriter, r *http.Request) {
+ router.Route("/auth", func(router chi.Router) {
+ router.Get("/providers", func(w http.ResponseWriter, r *http.Request) {
})
- r.Get("/csrf", func(w http.ResponseWriter, r *http.Request) {
+ router.Get("/csrf", func(w http.ResponseWriter, r *http.Request) {
})
- r.Get("/signin/auth0", func(w http.ResponseWriter, r *http.Request) {
+ router.Get("/signin/auth0", func(w http.ResponseWriter, r *http.Request) {
})
})
- r.Route("/session", func(r chi.Router) {
- r.Get("/", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ router.Route("/session", func(router chi.Router) {
+ router.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write(readFixture("session.json"))
})
})
- r.Route("/notifications", func(r chi.Router) {
- r.Get("/", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ router.Route("/notifications", func(router chi.Router) {
+ router.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write(readFixture("notifications.json"))
})
- r.Get("/{id}", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ router.Get("/{id}", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write(readFixture(fmt.Sprintf("notifications/%v.json", chi.URLParam(r, "id"))))
})
})
- r.Route("/resources", func(r chi.Router) {
- r.Get("/{id}", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ router.Route("/resources", func(router chi.Router) {
+ router.Get("/{id}", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write(readFixture(fmt.Sprintf("resources/%v.json", chi.URLParam(r, "id"))))
})
})
- r.Route("/atlas", func(r chi.Router) {
- r.Get("/", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ router.Route("/atlas", func(router chi.Router) {
+ router.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write(readFixture("atlas.json"))
})
- r.Get("/{id}/capabilities", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ router.Get("/{id}/capabilities", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write(readFixture(fmt.Sprintf("atlas/%v/capabilities.json", chi.URLParam(r, "id"))))
})
- r.Get("/{id}/investigations", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ router.Get("/{id}/investigations", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write(readFixture(fmt.Sprintf("atlas/%v/investigations.json", chi.URLParam(r, "id"))))
})
- r.Get("/{id}/investigations/{iid}", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ router.Get("/{id}/investigations/{iid}", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write(readFixture(fmt.Sprintf("atlas/%v/investigations/%v.json", chi.URLParam(r, "id"), chi.URLParam(r, "iid"))))
})
- r.Get("/{id}/investigations/{iid}/conversation", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
+ router.Get("/{id}/investigations/{iid}/conversation", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write(readFixture(fmt.Sprintf("atlas/%v/investigations/%v/conversation.json", chi.URLParam(r, "id"), chi.URLParam(r, "iid"))))
})
})
})
- r.NotFound(func(w http.ResponseWriter, r *http.Request) {
+ router.NotFound(func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("%v %v Not Found\n", r.Method, r.URL.Path)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("[]"))
})
- log.Fatal(http.ListenAndServe("localhost:4000", r))
+ log.Fatal(http.ListenAndServe("localhost:4000", router))
}
diff --git a/cmd/gw/main.go b/cmd/gw/main.go
deleted file mode 100644
index 06bb384..0000000
--- a/cmd/gw/main.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package main
-
-import (
- "log"
- "net/http"
-)
-
-func main() {
- log.Fatal(http.ListenAndServe("localhost:8080", nil))
-}
diff --git a/go.mod b/go.mod
index f11eaf2..978a56e 100644
--- a/go.mod
+++ b/go.mod
@@ -3,28 +3,32 @@ module github.com/xlgmokha/api-auth0
go 1.18
require (
- github.com/auth0/go-jwt-middleware/v2 v2.0.1
+ github.com/casbin/casbin/v2 v2.47.1
github.com/coreos/go-oidc/v3 v3.1.0
github.com/go-chi/chi/v5 v5.0.7
github.com/go-chi/cors v1.2.1
github.com/go-chi/jwtauth/v5 v5.0.2
github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c
github.com/joho/godotenv v1.4.0
+ github.com/lestrrat-go/jwx/v2 v2.0.1
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
)
require (
- github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d // indirect
- github.com/goccy/go-json v0.7.6 // indirect
+ github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
+ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
+ github.com/goccy/go-json v0.9.7 // indirect
github.com/golang/protobuf v1.4.2 // indirect
+ github.com/google/go-cmp v0.5.7 // indirect
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
- github.com/lestrrat-go/blackmagic v1.0.0 // indirect
- github.com/lestrrat-go/httpcc v1.0.0 // indirect
- github.com/lestrrat-go/iter v1.0.1 // indirect
+ github.com/lestrrat-go/blackmagic v1.0.1 // indirect
+ github.com/lestrrat-go/httpcc v1.0.1 // indirect
+ github.com/lestrrat-go/httprc v1.0.1 // indirect
+ github.com/lestrrat-go/iter v1.0.2 // indirect
github.com/lestrrat-go/jwx v1.2.6 // indirect
github.com/lestrrat-go/option v1.0.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
- golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
+ golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
google.golang.org/appengine v1.6.6 // indirect
google.golang.org/protobuf v1.25.0 // indirect
diff --git a/go.sum b/go.sum
index 656cbc1..485de5d 100644
--- a/go.sum
+++ b/go.sum
@@ -33,8 +33,10 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
-github.com/auth0/go-jwt-middleware/v2 v2.0.1 h1:zAgDKL7nsfVBFl31GGxsSXkhuRzYe1fVtJcO3aMSrFU=
-github.com/auth0/go-jwt-middleware/v2 v2.0.1/go.mod h1:kDt7JgUuDEp1VutfUmO4ZxBLL51vlNu/56oDfXc5E0Y=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/casbin/casbin/v2 v2.47.1 h1:ZwR81xg9ymLoA391eeM7UW2tfnFqtdDJn4dJv7DFZOg=
+github.com/casbin/casbin/v2 v2.47.1/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
@@ -46,8 +48,9 @@ github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpA
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
-github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d h1:1iy2qD6JEhHKKhUOA9IWs7mjco7lnw2qx8FsRI2wirE=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -62,8 +65,9 @@ github.com/go-chi/jwtauth/v5 v5.0.2/go.mod h1:TeA7vmPe3uYThvHw8O8W13HOOpOd4MTgTo
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/goccy/go-json v0.7.6 h1:H0wq4jppBQ+9222sk5+hPLL25abZQiRuQ6YPnjO9c+A=
github.com/goccy/go-json v0.7.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
+github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -74,6 +78,7 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -99,6 +104,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
+github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@@ -126,15 +132,22 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
-github.com/lestrrat-go/blackmagic v1.0.0 h1:XzdxDbuQTz0RZZEmdU7cnQxUtFUzgCSPq8RCz4BxIi4=
github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ=
+github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80=
+github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
github.com/lestrrat-go/codegen v1.0.1/go.mod h1:JhJw6OQAuPEfVKUCLItpaVLumDGWQznd1VaXrBk9TdM=
-github.com/lestrrat-go/httpcc v1.0.0 h1:FszVC6cKfDvBKcJv646+lkh4GydQg2Z29scgUfkOpYc=
github.com/lestrrat-go/httpcc v1.0.0/go.mod h1:tGS/u00Vh5N6FHNkExqGGNId8e0Big+++0Gf8MBnAvE=
-github.com/lestrrat-go/iter v1.0.1 h1:q8faalr2dY6o8bV45uwrxq12bRa1ezKrB6oM9FUgN4A=
+github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
+github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
+github.com/lestrrat-go/httprc v1.0.1 h1:Cnc4NxIySph38pQPzKbjg5OkKsGR/Cf5xcWt5OlSUDI=
+github.com/lestrrat-go/httprc v1.0.1/go.mod h1:5Ml+nB++j6IC0e6LzefJnrpMQDKgDwDCaIQQzhbqhJM=
github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc=
+github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
+github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
github.com/lestrrat-go/jwx v1.2.6 h1:XAgfuHaOB7fDZ/6WhVgl8K89af768dU+3Nx4DlTbLIk=
github.com/lestrrat-go/jwx v1.2.6/go.mod h1:tJuGuAI3LC71IicTx82Mz1n3w9woAs2bYJZpkjJQ5aU=
+github.com/lestrrat-go/jwx/v2 v2.0.1 h1:BFhFnElL3HVa/e1sXTogmKbMlY2HgfEP1fozVc6/eYA=
+github.com/lestrrat-go/jwx/v2 v2.0.1/go.mod h1:xV8+xRcrKbmnScV8adOzUuuTrL8aAZJoY4q2JAqIYU8=
github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4=
github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -149,6 +162,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -164,8 +178,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
-golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38=
-golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f h1:OeJjE6G4dgCY4PIXvIRQbE8+RX+uXZyGhUy/ksMGJoc=
+golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -225,6 +239,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -270,15 +285,19 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/pkg/api/model.conf b/pkg/api/model.conf
new file mode 100644
index 0000000..cee2566
--- /dev/null
+++ b/pkg/api/model.conf
@@ -0,0 +1,11 @@
+[request_definition]
+r = sub, obj, act
+
+[policy_definition]
+p = sub, obj, act
+
+[policy_effect]
+e = some(where (p.eft == allow))
+
+[matchers]
+m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
diff --git a/pkg/api/policy.csv b/pkg/api/policy.csv
new file mode 100644
index 0000000..888c8cb
--- /dev/null
+++ b/pkg/api/policy.csv
@@ -0,0 +1,3 @@
+p, alice, data1, read
+p, bob, data2, write
+p, auth0|627b10e1019dd10068e03db4, /api/users, GET