Skip to content

Commit

Permalink
Add --zoom flag which expands the permissions of a specific identity
Browse files Browse the repository at this point in the history
  • Loading branch information
yuvalavra authored and yuvalavra committed Oct 26, 2022
1 parent 8119d6b commit f4e38ed
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 11 deletions.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ Ignore control plane pods and nodes in clusters that host the control plane.
```
./rbac-police eval lib/ --ignore-controlplane
```
### Nodes don't use NodeAuthorizer
Specify a custom user used by nodes in clusters that don't use the NodeAuthorizer.
```
./rbac-police eval lib/ --node-user=nodeclient
```
### Collect once for multiple evaluations
```
./rbac-police collect -o rbacDb.json
Expand All @@ -85,6 +80,12 @@ Or:
./rbac-police collect -o rbacDb.json
./rbac-police expand rbacDb.json
```
### View the permissions of a specific identity
Inspect the permissions of a single identity.
```
./rbac-police expand -z sa=kube-system:metrics-server
./rbac-police expand -z user=example@email.com
```
## Documentation
- [Policies](docs/policies.md)
Expand Down
8 changes: 4 additions & 4 deletions cmd/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ import (

// evalCmd represents the eval command
var (
evalConfig eval.EvalConfig
shortMode bool
violations []string

evalCmd = &cobra.Command{
Use: "eval <policies> [rbac-json]",
Short: "Evaulates RBAC permissions of Kubernetes identities using Rego policies",
Run: runEval,
}

evalConfig eval.EvalConfig
shortMode bool
violations []string
)

func runEval(cmd *cobra.Command, args []string) {
Expand Down
90 changes: 88 additions & 2 deletions cmd/expand.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"encoding/json"
"fmt"
"strings"

"github.com/PaloAltoNetworks/rbac-police/pkg/collect"
"github.com/PaloAltoNetworks/rbac-police/pkg/expand"
Expand All @@ -20,13 +21,29 @@ var (
This is done by repeating the entire permissions of each role under each identity that has it.`,
Run: runExpand,
}

zoomedIdentity string
)

func runExpand(cmd *cobra.Command, args []string) {
var (
collectResult collect.CollectResult
collectResult collect.CollectResult
output []byte
err error
zoomedType string
zoomedName string
zoomedNamespace string
)

// If zoomedIdentity is used, parse it
if zoomedIdentity != "" {
zoomedType, zoomedName, zoomedNamespace = parseZoomedIdentity(zoomedIdentity)
if zoomedType == "" {
cmd.Help()
return
}
}

// Get RBAC JSON
if len(args) > 0 {
if collectionOptionsSet() {
Expand Down Expand Up @@ -57,8 +74,47 @@ func runExpand(cmd *cobra.Command, args []string) {
return // error printed by Expand()
}

// Marshal results
if zoomedIdentity == "" {
output, err = marshalResults(expandResult)
} else {
// Zoom on a specific identity // TODO: consider only collecting / expanding the zoomed identity
if zoomedType == "sa" {
for _, sa := range expandResult.ServiceAccounts {
if sa.Name == zoomedName && sa.Namespace == zoomedNamespace {
output, err = marshalResults(sa)
break
}
}
} else if zoomedType == "node" {
for _, node := range expandResult.Nodes {
if node.Name == zoomedName {
output, err = marshalResults(node)
break
}
}
} else if zoomedType == "user" {
for _, user := range expandResult.Users {
if user.Name == zoomedName {
output, err = marshalResults(user)
break
}
}
} else if zoomedType == "group" {
for _, grp := range expandResult.Groups {
if grp.Name == zoomedName {
output, err = marshalResults(grp)
break
}
}
}
if len(output) == 0 {
fmt.Println("[!] Cannot find zoomed identity")
return
}
}

// Output expand results
output, err := marshalResults(expandResult)
if err != nil {
log.Errorln("runExpand: failed to marshal results with", err)
return
Expand All @@ -67,5 +123,35 @@ func runExpand(cmd *cobra.Command, args []string) {
}

func init() {
expandCmd.Flags().StringVarP(&zoomedIdentity, "zoom", "z", "", "only show the permissions of the specified identity, format is 'type=identity', e.g. 'sa=kube-system:default', 'user=example@email.com'")
rootCmd.AddCommand(expandCmd)
}

// Parses zoomedIdentity into a type, identity and namespace
func parseZoomedIdentity(zoomedIdentity string) (string, string, string) {
var zoomedNamespace string

// Parse type & name
separatorIndex := strings.Index(zoomedIdentity, "=")
if separatorIndex < 0 {
fmt.Println("[!] Cannot parse zoomed identity, format is 'type=identity'")
return "", "", ""
}
zoomedType := zoomedIdentity[:separatorIndex]
zoomedName := zoomedIdentity[separatorIndex+1:]

// Parse namespace for service accounts
if zoomedType == "sa" {
separatorIndex = strings.Index(zoomedName, ":")
if separatorIndex < 0 {
fmt.Println("[!] Cannot parse zoomed SA, format is 'sa=namespace:name'")
return "", "", ""
}
zoomedNamespace = zoomedName[:separatorIndex]
zoomedName = zoomedName[separatorIndex+1:]
} else if zoomedType != "node" && zoomedType != "user" && zoomedType != "group" {
fmt.Printf("[!] Unsupported type for zoomed identity '%s', supported types are 'sa', 'node', 'user' and 'group'\n", zoomedType)
return "", "", ""
}
return zoomedType, zoomedName, zoomedNamespace
}
1 change: 1 addition & 0 deletions docs/expand.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Usage:
Flags:
-h, --help help for expand
-z, --zoom string only show the permissions of the specified identity, format is 'type=identity', e.g. 'sa=kube-system:default', 'user=example@email.com'
Global Flags:
-a, --all-serviceaccounts collect data on all serviceAccounts, not only those assigned to a pod
Expand Down

0 comments on commit f4e38ed

Please sign in to comment.