Repository: tfsec/tfsec
Pull request #473 (2020-10-26 17:26:23)

Ensure RBAC is enabled on AKS clusters 
Ensure RBAC is enabled on AKS clusters


Patch:
diff --git a/internal/app/tfsec/checks/azu007.go b/internal/app/tfsec/checks/azu007.go
new file mode 100644
index 000000000..87932e2cf
--- /dev/null
+++ b/internal/app/tfsec/checks/azu007.go
@@ -0,0 +1,78 @@
+package checks
+
+import (
+	"fmt"
+
+	"github.com/tfsec/tfsec/internal/app/tfsec/parser"
+	"github.com/tfsec/tfsec/internal/app/tfsec/scanner"
+	"github.com/zclconf/go-cty/cty"
+)
+
+const AZUAKSClusterRBACenabled scanner.RuleCode = "AZU007"
+const AZUAKSClusterRBACenabledDescription scanner.RuleSummary = "Ensure RBAC is enabled on AKS clusters"
+const AZUAKSClusterRBACenabledExplanation = `
+Using Kubernetes role-based access control (RBAC), you can grant users, groups, and service accounts access to only the resources they need.
+`
+const AZUAKSClusterRBACenabledBadExample = `
+resource "azurerm_kubernetes_cluster" "my-aks-cluster" {
+	role_based_access_control {
+		enabled = false
+	}
+}
+`
+const AZUAKSClusterRBACenabledGoodExample = `
+resource "azurerm_kubernetes_cluster" "my-aks-cluster" {
+	role_based_access_control {
+		enabled = true
+	}
+}
+`
+
+func init() {
+	scanner.RegisterCheck(scanner.Check{
+		Code: AZUAKSClusterRBACenabled,
+		Documentation: scanner.CheckDocumentation{
+			Summary:     AZUAKSClusterRBACenabledDescription,
+			Explanation: AZUAKSClusterRBACenabledExplanation,
+			BadExample:  AZUAKSClusterRBACenabledBadExample,
+			GoodExample: AZUAKSClusterRBACenabledGoodExample,
+			Links: []string{
+				"https://www.terraform.io/docs/providers/azurerm/r/kubernetes_cluster.html#role_based_access_control",
+				"https://docs.microsoft.com/en-us/azure/aks/concepts-identity",
+			},
+		},
+		Provider:       scanner.AzureProvider,
+		RequiredTypes:  []string{"resource"},
+		RequiredLabels: []string{"azurerm_kubernetes_cluster", "role_based_access_control"},
+		CheckFunc: func(check *scanner.Check, block *parser.Block, _ *scanner.Context) []scanner.Result {
+
+			rbacBlock := block.GetBlock("role_based_access_control")
+			if rbacBlock == nil {
+				return []scanner.Result{
+					check.NewResult(
+						fmt.Sprintf("Resource '%s' defines without RBAC", block.FullName()),
+						block.Range(),
+						scanner.SeverityError,
+					),
+				}
+			}
+
+			enabledAttr := rbacBlock.GetAttribute("enabled")
+			if enabledAttr.Type() == cty.Bool && enabledAttr.Value().False() {
+				return []scanner.Result{
+					check.NewResultWithValueAnnotation(
+						fmt.Sprintf(
+							"Resource '%s' RBAC disabled.",
+							block.FullName(),
+						),
+						enabledAttr.Range(),
+						enabledAttr,
+						scanner.SeverityError,
+					),
+				}
+			}
+
+			return nil
+		},
+	})
+}


Test patch:
diff --git a/internal/app/tfsec/test/azu007_test.go b/internal/app/tfsec/test/azu007_test.go
new file mode 100644
index 000000000..42379f1c2
--- /dev/null
+++ b/internal/app/tfsec/test/azu007_test.go
@@ -0,0 +1,55 @@
+package test
+
+import (
+	"testing"
+
+	"github.com/tfsec/tfsec/internal/app/tfsec/checks"
+	"github.com/tfsec/tfsec/internal/app/tfsec/scanner"
+)
+
+func Test_AZUAKSClusterRBACenabled(t *testing.T) {
+
+	var tests = []struct {
+		name                  string
+		source                string
+		mustIncludeResultCode scanner.RuleCode
+		mustExcludeResultCode scanner.RuleCode
+	}{
+		{
+			name: "check azurerm_kubernetes_cluster with no role_based_access_control define",
+			source: `
+resource "azurerm_kubernetes_cluster" "my-aks-cluster" {
+
+}`,
+			mustIncludeResultCode: checks.AZUAKSClusterRBACenabled,
+		},
+		{
+			name: "check azurerm_kubernetes_cluster with role_based_access_control disabled",
+			source: `
+resource "azurerm_kubernetes_cluster" "my-aks-cluster" {
+	role_based_access_control {
+		enabled = false
+	}
+}`,
+			mustIncludeResultCode: checks.AZUAKSClusterRBACenabled,
+		},
+		{
+			name: "check azurerm_kubernetes_cluster with RBAC enabled",
+			source: `
+resource "azurerm_kubernetes_cluster" "my-aks-cluster" {
+	role_based_access_control {
+		enabled = true
+	}
+}`,
+			mustExcludeResultCode: checks.AZUAKSClusterRBACenabled,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			results := scanSource(test.source)
+			assertCheckCode(t, test.mustIncludeResultCode, test.mustExcludeResultCode, results)
+		})
+	}
+
+}