Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: properly set casbin authz policy #1776

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,12 @@ OpenTDF uses Casbin to manage authorization policies. This document provides an

#### Key Aspects of Authorization Configuration

1. **Default Role**: The default role assigned to an authorized user if no specific role is found.
2. **Claim**: The claim in the OIDC token that should be used to map roles.
3. **Map**: Mapping between policy roles and IdP roles.
4. **CSV**: The authorization policy in CSV format.
5. **Model**: The Casbin policy model.
2. **Username Claim**: The claim in the OIDC token that should be used to extract a username.
3. **Group Claim**: The claim in the OIDC token that should be used to find the group claims.
4. **Map (Deprecated)**: Mapping between policy roles and IdP roles.
4. **Extension**: Policy that will extend the builtin policy
4. **CSV**: The authorization policy in CSV format. This will override the builtin policy.
5. **Model**: The Casbin policy model. This should only be set if you have a deep understanding of how casbin works.

#### Configuration in opentdf-example.yaml

Expand All @@ -263,19 +264,34 @@ server:
audience: 'http://localhost:8080'
issuer: http://keycloak:8888/auth/realms/opentdf
policy:
## Default role for all requests
default: "role:standard"

## Deprecated
## Dot notation is used to access nested claims (i.e. realm_access.roles)
claim: "realm_access.roles"

## Dot notation is used to access the username claim
username_claim: "email"

## Dot notation is used to access the groups claim
group_claim: "realm_access.roles"

## Deprecated: Use standard casbin policy groupings (g, <user/group>, <role>)
## Maps the external role to the OpenTDF role
## Note: left side is used in the policy, right side is the external role
map:
standard: opentdf-standard
admin: opentdf-admin

## Policy that will extend the builtin policy.
extension: |
p, role:admin, *, *, allow
p, role:standard, policy:attributes, read, allow
p, role:standard, policy:subject-mappings, read, allow
g, opentdf-admin, role:admin
g, alice@opentdf.io, role:standard
elizabethhealy marked this conversation as resolved.
Show resolved Hide resolved

## Custom policy (see examples https://github.com/casbin/casbin/tree/master/examples)
## This will overwrite the builtin policy. Use with caution.
csv: |
p, role:admin, *, *, allow
p, role:standard, policy:attributes, read, allow
Expand All @@ -286,6 +302,7 @@ server:
p, role:unknown, kas.AccessService/Rewrap, *, allow

## Custom model (see https://casbin.org/docs/syntax-for-models/)
## Avoid setting this unless you have a deep understanding of how casbin works.
model: |
[request_definition]
r = sub, res, act, obj
Expand All @@ -305,8 +322,7 @@ server:

#### Role Permissions

- **Org Admin**: Can read, write, and perform unsafe mutations.
- **Admin**: Can read and write.
- **Admin**: Can perform all operations.
- **Standard User**: Can read.
- **Public Endpoints**: Accessible without specific roles.

Expand Down
20 changes: 9 additions & 11 deletions opentdf-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,18 @@ server:
audience: 'http://localhost:8080'
issuer: http://localhost:8888/auth/realms/opentdf
policy:
## Default policy for all requests
default: #"role:standard"
## Dot notation is used to access nested claims (i.e. realm_access.roles)
claim: # realm_access.roles
## Maps the external role to the opentdf role
## Note: left side is used in the policy, right side is the external role
map:
# standard: opentdf-standard
# admin: opentdf-admin

## Custom policy (see examples https://github.com/casbin/casbin/tree/master/examples)
# Claim that represents the user (i.e. email)
username_claim: # preferred_username
# That claim to access groups (i.e. realm_access.roles)
groups_claim: # realm_access.roles
## Extends the builtin policy
extension: |
g, opentdf-admin, role:admin
g, opentdf-standard, role:standard
## Custom policy that overrides builtin policy (see examples https://github.com/casbin/casbin/tree/master/examples)
csv: #|
# p, role:admin, *, *, allow

## Custom model (see https://casbin.org/docs/syntax-for-models/)
model: #|
# [request_definition]
Expand Down
19 changes: 9 additions & 10 deletions opentdf-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,16 @@ server:
audience: 'http://localhost:8080'
issuer: http://keycloak:8888/auth/realms/opentdf
policy:
## Default policy for all requests
default: #"role:standard"
## Dot notation is used to access nested claims (i.e. realm_access.roles)
claim: # realm_access.roles
## Maps the external role to the opentdf role
## Note: left side is used in the policy, right side is the external role
map:
# standard: opentdf-standard
# admin: opentdf-admin

## Custom policy (see examples https://github.com/casbin/casbin/tree/master/examples)
# Claim that represents the user (i.e. email)
username_claim: # preferred_username
# That claim to access groups (i.e. realm_access.roles)
groups_claim: # realm_access.roles
## Extends the builtin policy
extension: |
g, opentdf-admin, role:admin
g, opentdf-standard, role:standard
## Custom policy that overrides builtin policy (see examples https://github.com/casbin/casbin/tree/master/examples)
csv: #|
# p, role:admin, *, *, allow
## Custom model (see https://casbin.org/docs/syntax-for-models/)
Expand Down
114 changes: 0 additions & 114 deletions opentdf-with-hsm.yaml

This file was deleted.

5 changes: 3 additions & 2 deletions service/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ require (
github.com/Nerzal/gocloak/v13 v13.9.0
github.com/bmatcuk/doublestar v1.3.4
github.com/bufbuild/protovalidate-go v0.6.0
github.com/casbin/casbin/v2 v2.84.0
github.com/casbin/casbin/v2 v2.101.0
github.com/creasty/defaults v1.7.0
github.com/go-chi/cors v1.2.1
github.com/go-playground/validator/v10 v10.22.0
Expand Down Expand Up @@ -43,7 +43,8 @@ require (
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/casbin/govaluate v1.1.0 // indirect
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
github.com/casbin/govaluate v1.2.0 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/containerd/containerd v1.7.21 // indirect
Expand Down
6 changes: 6 additions & 0 deletions service/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,20 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/bufbuild/protovalidate-go v0.6.0 h1:Jgs1kFuZ2LHvvdj8SpCLA1W/+pXS8QSM3F/E2l3InPY=
github.com/bufbuild/protovalidate-go v0.6.0/go.mod h1:1LamgoYHZ2NdIQH0XGczGTc6Z8YrTHjcJVmiBaar4t4=
github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA=
github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyzCCRzZcxCgsZCi+RNlvYor5Q=
github.com/casbin/casbin/v2 v2.84.0 h1:WioxdvRbG/1lR7GMIhEHk4GwPcVOxQqhCGWpEUKJoGI=
github.com/casbin/casbin/v2 v2.84.0/go.mod h1:jX8uoN4veP85O/n2674r2qtfSXI6myvxW85f6TH50fw=
github.com/casbin/casbin/v2 v2.101.0 h1:y8qZRXcgv5omd3k/7kpaP03Hov82sXzCC5FAfm17lkw=
github.com/casbin/casbin/v2 v2.101.0/go.mod h1:LO7YPez4dX3LgoTCqSQAleQDo0S0BeZBDxYnPUl95Ng=
github.com/casbin/govaluate v1.1.0 h1:6xdCWIpE9CwHdZhlVQW+froUrCsjb6/ZYNcXODfLT+E=
github.com/casbin/govaluate v1.1.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A=
github.com/casbin/govaluate v1.2.0 h1:wXCXFmqyY+1RwiKfYo3jMKyrtZmOL3kHwaqDyCPOYak=
github.com/casbin/govaluate v1.2.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
Expand Down
10 changes: 0 additions & 10 deletions service/internal/auth/authn.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,6 @@ func normalizeURL(o string, u *url.URL) string {
return ou.String()
}

// deprecated
func (a *Authentication) ExtendAuthzDefaultPolicy(policies [][]string) error {
return a.enforcer.ExtendDefaultPolicy(policies)
}

// SetAuthzPolicy sets the policy for the casbin enforcer
func (a *Authentication) SetAuthzPolicy(policy string) error {
return a.enforcer.SetPolicy(policy)
}

// verifyTokenHandler is a http handler that verifies the token
func (a Authentication) MuxHandler(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down
15 changes: 6 additions & 9 deletions service/internal/auth/authn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"time"

"connectrpc.com/connect"
"github.com/creasty/defaults"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwk"
"github.com/lestrrat-go/jwx/v2/jws"
Expand Down Expand Up @@ -145,6 +146,10 @@ func (s *AuthSuite) SetupTest() {
}
}))

policyCfg := PolicyConfig{}
err = defaults.Set(&policyCfg)
s.Require().NoError(err)

auth, err := NewAuthenticator(
context.Background(),
Config{
Expand All @@ -154,6 +159,7 @@ func (s *AuthSuite) SetupTest() {
Audience: "test",
DPoPSkew: time.Hour,
TokenSkew: time.Minute,
Policy: policyCfg,
},
PublicRoutes: []string{
"/public",
Expand Down Expand Up @@ -549,15 +555,6 @@ func (s *AuthSuite) TestDPoPEndToEnd_HTTP() {
s.Equal(dpopJWK.N(), dpopJWKFromRequest.N())
}

func (s *AuthSuite) Test_AddAuthzPolicies() {
err := s.auth.ExtendAuthzDefaultPolicy([][]string{
{"p", "role:admin", "/path", "*", "allow"},
{"p", "role:standard", "/path2", "read", "deny"},
})
s.Require().NoError(err)
s.False(s.auth.enforcer.isDefaultPolicy)
}

func makeDPoPToken(t *testing.T, tc dpopTestCase) string {
jtiBytes := make([]byte, sdkauth.JTILength)
_, err := rand.Read(jtiBytes)
Expand Down
Loading
Loading