summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-18 13:26:30 -0600
committermo khan <mo@mokhan.ca>2025-07-18 13:26:30 -0600
commite5142a2786b499291f6e98f328e10a9c44901ad2 (patch)
treea4592cee3af83b95a9d72418492b4df93459fad0
parent9d5b310de5b2266aeb40f8585df65564b8de19b9 (diff)
feat: authorize http resources
-rw-r--r--Makefile10
-rw-r--r--etc/authzd/spice.schema10
-rw-r--r--pkg/authz/check_service.go7
-rw-r--r--pkg/authz/init.go25
4 files changed, 47 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 114594e0..2e4efee7 100644
--- a/Makefile
+++ b/Makefile
@@ -62,8 +62,18 @@ run-spicedb-setup:
@$(ZED_CMD) relationship create project:1 maintainer user:mokhax
@$(ZED_CMD) relationship create project:1 developer user:tanuki
+run-spicedb-sparkle-relationships:
+ @$(ZED_CMD) relationship touch resource:/ reader user:*
+ @$(ZED_CMD) relationship touch resource:/callback reader user:*
+ @$(ZED_CMD) relationship touch resource:/dashboard reader user:root
+ @$(ZED_CMD) relationship touch resource:/dashboard/nav reader user:*
+ @$(ZED_CMD) relationship touch resource:/signout reader user:root
+ @$(ZED_CMD) relationship touch resource:/sparkles reader user:*
+ @$(ZED_CMD) relationship touch resource:/sparkles writer user:root
+
run-spicedb-permission-check:
@$(ZED_CMD) permission check project:1 read user:mokhax
@$(ZED_CMD) permission check project:1 write user:mokhax
@$(ZED_CMD) permission check project:1 read user:tanuki
@$(ZED_CMD) permission check project:1 write user:tanuki
+ @$(ZED_CMD) permission check resource:/ read user:public
diff --git a/etc/authzd/spice.schema b/etc/authzd/spice.schema
index 5f5c0dab..0f3494f7 100644
--- a/etc/authzd/spice.schema
+++ b/etc/authzd/spice.schema
@@ -15,3 +15,13 @@ definition project {
definition group {
}
+
+definition resource {
+ relation reader: user | user:*
+ relation writer: user | user:*
+
+ permission read = reader + writer
+ permission create = writer
+ permission update = writer
+ permission delete = writer
+}
diff --git a/pkg/authz/check_service.go b/pkg/authz/check_service.go
index 75ba3963..3e14c008 100644
--- a/pkg/authz/check_service.go
+++ b/pkg/authz/check_service.go
@@ -52,7 +52,12 @@ func (svc *CheckService) isAuthorized(ctx context.Context, r *auth.CheckRequest)
return false
}
- response, err := svc.client.CheckPermission(ctx, mapper.MapFrom[*auth.CheckRequest, *v1.CheckPermissionRequest](r))
+ request := mapper.MapFrom[*auth.CheckRequest, *v1.CheckPermissionRequest](r)
+ response, err := svc.client.CheckPermission(ctx, request)
+ log.WithFields(ctx, log.Fields{
+ "spice_request": request,
+ "spice_response": response,
+ })
if err != nil {
pls.LogError(ctx, err)
return false
diff --git a/pkg/authz/init.go b/pkg/authz/init.go
index e902e6d1..21927145 100644
--- a/pkg/authz/init.go
+++ b/pkg/authz/init.go
@@ -1,11 +1,14 @@
package authz
import (
+ "net/http"
+
v1 "github.com/authzed/authzed-go/proto/authzed/api/v1"
auth "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3"
"github.com/xlgmokha/x/pkg/log"
"github.com/xlgmokha/x/pkg/mapper"
"github.com/xlgmokha/x/pkg/x"
+ "google.golang.org/protobuf/types/known/structpb"
)
func init() {
@@ -24,8 +27,8 @@ func init() {
mapper.Register[*auth.CheckRequest, *v1.ObjectReference](func(r *auth.CheckRequest) *v1.ObjectReference {
return &v1.ObjectReference{
- ObjectType: "project",
- ObjectId: "1",
+ ObjectType: "resource",
+ ObjectId: r.Attributes.Request.Http.Path,
}
})
@@ -33,7 +36,7 @@ func init() {
//TODO:: username is not ideal but it works for demo purposes
username := r.Attributes.Request.Http.Headers["x-jwt-claim-username"]
if x.IsZero(username) {
- username = "*"
+ username = "public"
}
return &v1.SubjectReference{
@@ -45,7 +48,20 @@ func init() {
})
mapper.Register[*auth.CheckRequest, Permission](func(r *auth.CheckRequest) Permission {
- return "read"
+ switch r.GetAttributes().Request.Http.Method {
+ case http.MethodGet:
+ return "read"
+ case http.MethodPost:
+ return "create"
+ case http.MethodPut:
+ return "update"
+ case http.MethodPatch:
+ return "update"
+ case http.MethodDelete:
+ return "delete"
+ default:
+ return "read"
+ }
})
mapper.Register[*auth.CheckRequest, *v1.CheckPermissionRequest](func(r *auth.CheckRequest) *v1.CheckPermissionRequest {
@@ -53,6 +69,7 @@ func init() {
Resource: mapper.MapFrom[*auth.CheckRequest, *v1.ObjectReference](r),
Permission: mapper.MapFrom[*auth.CheckRequest, Permission](r).String(),
Subject: mapper.MapFrom[*auth.CheckRequest, *v1.SubjectReference](r),
+ Context: x.Must(structpb.NewStruct(map[string]any{})),
}
})
}