Skip to content

Commit

Permalink
Added validation for v1 API config in RBAC plugin (#485)
Browse files Browse the repository at this point in the history
* api v1 mapping

Signed-off-by: Xuhang Cao <ccao@oberlin.edu>

* api v1 mapping

Signed-off-by: Xuhang Cao <ccao@oberlin.edu>

---------

Signed-off-by: Xuhang Cao <65797697+Xiaocao-Cxh@users.noreply.github.com>
  • Loading branch information
Xiaocao-Cxh authored and maia-iyer committed Sep 17, 2024
1 parent a3d7e11 commit 554e050
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
11 changes: 8 additions & 3 deletions docs/conf/agent/full.conf
Original file line number Diff line number Diff line change
Expand Up @@ -89,24 +89,29 @@ plugins {
API "/api/tornjak/clusters/create" { allowed_roles = ["admin"] }
API "/api/tornjak/clusters/edit" { allowed_roles = ["admin"] }
API "/api/tornjak/clusters/delete" { allowed_roles = ["admin"] }

APIv1 "GET /api/v1/spire/serverinfo" { allowed_roles = ["admin", "viewer"] }
APIv1 "GET /api/v1/spire/healthcheck" { allowed_roles = ["admin", "viewer"] }
APIv1 "GET /api/v1/spire/entries" { allowed_roles = ["admin", "viewer"] }
APIv1 "GET /api/v1/spire/agents" { allowed_roles = ["admin", "viewer"] }
APIv1 "POST /api/v1/spire/agents/ban" { allowed_roles = ["admin"] }
APIv1 "DELETE /api/v1/spire/agents" { allowed_roles = ["admin"] }
APIv1 "POST /api/v1/spire/agents/ban" { allowed_roles = ["admin"] }
APIv1 "POST /api/v1/spire/agents/jointoken" { allowed_roles = ["admin"] }
APIv1 "GET /api/v1/spire/entries" { allowed_roles = ["admin", "viewer"] }
APIv1 "POST /api/v1/spire/entries" { allowed_roles = ["admin"] }
APIv1 "DELETE /api/v1/spire/entries" { allowed_roles = ["admin"] }

# SPIRE Federation API calls
APIv1 "GET /api/v1/spire/bundle" { allowed_roles = ["admin", "viewer"] }
APIv1 "GET /api/v1/spire/federations/bundles" { allowed_roles = ["admin", "viewer"] }
APIv1 "POST /api/v1/spire/federations/bundles" { allowed_roles = ["admin"] }
APIv1 "PATCH /api/v1/spire/federations/bundles" { allowed_roles = ["admin"] }
APIv1 "DELETE /api/v1/spire/federations/bundles" { allowed_roles = ["admin"] }

# Tornjak API calls
APIv1 "GET /api/v1/tornjak/serverinfo" { allowed_roles = ["admin", "viewer"] }
APIv1 "GET /api/v1/tornjak/agents" { allowed_roles = ["admin", "viewer"] }
APIv1 "POST /api/v1/tornjak/selectors" { allowed_roles = ["admin"] }
APIv1 "GET /api/v1/tornjak/selectors" { allowed_roles = ["admin", "viewer"] }
APIv1 "GET /api/v1/tornjak/agents" { allowed_roles = ["admin", "viewer"] }
APIv1 "GET /api/v1/tornjak/clusters" { allowed_roles = ["admin", "viewer"] }
APIv1 "POST /api/v1/tornjak/clusters" { allowed_roles = ["admin"] }
APIv1 "PATCH /api/v1/tornjak/clusters" { allowed_roles = ["admin"] }
Expand Down
33 changes: 31 additions & 2 deletions pkg/agent/authorization/rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,22 @@ var staticAPIList = map[string]struct{}{
"/api/tornjak/clusters/edit": {},
"/api/tornjak/clusters/delete": {},
}
var staticAPIV1List = map[string]map[string]struct{}{
"/api/v1/spire/serverinfo" :{"GET": {}},
"/api/v1/spire/healthcheck" :{"GET": {}},
"/api/v1/spire/entries" :{"GET": {}, "POST": {}, "DELETE": {}},
"/api/v1/spire/agents" :{"GET": {}, "POST": {}, "DELETE": {}},
"/api/v1/spire/agent/ban" :{"POST": {}},
"/api/v1/spire/agents/jointoken" :{"POST": {}},
"/api/v1/tornjak/clusters" :{"GET": {}, "POST": {}, "PATCH": {}, "DELETE": {}},
"/api/v1/tornjak/selectors" :{"GET": {}, "POST": {}},
"/api/v1/tornjak/agents" :{"GET": {}},
"/api/v1/tornjak/serverinfo" :{"GET": {}},
"/api/v1/spire/bundle" :{"GET": {}},
"/api/v1/spire/federations/bundles" :{"GET": {}, "POST": {}, "DELETE": {}, "PATCH": {}},
}

func validateInitParameters(roleList map[string]string, apiMapping map[string][]string) error {
func validateInitParameters(roleList map[string]string, apiMapping map[string][]string, apiV1Mapping map[string]map[string][]string) error {
for api, allowList := range apiMapping {
// check that API exists
if _, ok := staticAPIList[api]; !ok {
Expand All @@ -49,11 +63,26 @@ func validateInitParameters(roleList map[string]string, apiMapping map[string][]
}
}
}
for path, method_dict := range apiV1Mapping {
for method, allowList := range method_dict {
// check that API exists
if _, ok := staticAPIV1List[path][method]; !ok {
return errors.Errorf("API path %s does not exist with method %s", path, method)
}

// check that each role exists in roleList
for _, allowedRole := range allowList {
if _, ok := roleList[allowedRole]; !ok {
return errors.Errorf("API %s lists undefined role %s", path, allowedRole)
}
}
}
}
return nil
}

func NewRBACAuthorizer(policyName string, roleList map[string]string, apiMapping map[string][]string, apiV1Mapping map[string]map[string][]string) (*RBACAuthorizer, error) {
err := validateInitParameters(roleList, apiMapping)
err := validateInitParameters(roleList, apiMapping, apiV1Mapping)
if err != nil {
return nil, errors.Errorf("Could not parse policy %s: invalid mapping: %v", policyName, err)
}
Expand Down

0 comments on commit 554e050

Please sign in to comment.