Skip to content

Commit

Permalink
identify legacyTokenSecrets when collection is scoped to a namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
yuvalavra committed Sep 1, 2022
1 parent c78c9d2 commit 6eb7fc9
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func Execute() {
func init() {
rootCmd.PersistentFlags().StringVarP(&outFile, "out-file", "o", "", "save results to file")
rootCmd.PersistentFlags().BoolVarP(&loudMode, "loud", "l", false, "loud mode, print results regardless of -o")
// Collect config
rootCmd.PersistentFlags().BoolVarP(&collectConfig.AllServiceAccounts, "all-serviceaccounts", "a", false, "collect data on all serviceAccounts, not only those assigned to a pod")
rootCmd.PersistentFlags().BoolVarP(&collectConfig.DiscoverProtections, "discover-protections", "w", false, "discover features gates and admission controllers that protect against certain attacks, partly by emulating the attacks via impersonation & dry-run write operations")
rootCmd.PersistentFlags().BoolVar(&collectConfig.IgnoreControlPlane, "ignore-controlplane", false, "don't collect data on control plane nodes and pods. Identified by either the 'node-role.kubernetes.io/control-plane' or 'node-role.kubernetes.io/master' labels. ServiceAccounts will not be linked to control plane components")
Expand Down
18 changes: 13 additions & 5 deletions pkg/collect/discover_protections.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
// and populate the cluster's metadata with them for policies to consume.
// NOTE: Uses impersonation and dry-run write operations, which won't affect the cluster, but may be logged / audited on.
func discoverRelevantControlPlaneFeatures(collectConfig CollectConfig, kubeConfig clientcmd.ClientConfig, clusterDb *ClusterDb, metadata *ClusterMetadata) {
if legacyTokenSecretsReducted(clusterDb) {
if legacyTokenSecretsReducted(clusterDb, collectConfig.Namespace) {
metadata.Features = append(metadata.Features, "LegacyTokenSecretsReducted")
}
// If NodeAuthorization is used, check for NodeRestriction
Expand All @@ -38,13 +38,21 @@ func discoverRelevantControlPlaneFeatures(collectConfig CollectConfig, kubeConfi
}

// Best effort test for whether serviceAccount tokens are stored as secrets
func legacyTokenSecretsReducted(clusterDb *ClusterDb) bool {
func legacyTokenSecretsReducted(clusterDb *ClusterDb, ns string) bool {
// If collection is scoped to ns, use it's default serviceAccount for testing,
// Otherwise use kube-system:replicaset-controller
saName := "default"
if ns == "" {
ns = "kube-system"
saName = "replicaset-controller"
}

for _, serviceAccount := range clusterDb.ServiceAccounts {
if serviceAccount.ObjectMeta.Namespace != "kube-system" {
if serviceAccount.ObjectMeta.Namespace != ns {
continue
}
// Arbitrarily chose the replicaset-controller for testing
if serviceAccount.ObjectMeta.Name != "replicaset-controller" {

if serviceAccount.ObjectMeta.Name != saName {
continue
}
// Return true if there are no auto-generated secrets for the serviceAccount
Expand Down

0 comments on commit 6eb7fc9

Please sign in to comment.