config: new flags '--disallow-(config|annotation)-exemptions' (#636)

This change follows up #635 and lets end-users decide to disallow exemption rules defined as part of the config file or the controller annotations (whether none, any or both). The main use case here is to be able to prevent users with edit privileges over a controller to add a new exemption rule through an annotation which may obfuscate the actual policies we want to enforce.

Signed-off-by: Maxime VISONNEAU <maxime.visonneau@gmail.com>

Co-authored-by: Robert Brennan <accounts@rbren.io>
This commit is contained in:
Maxime VISONNEAU
2021-09-27 17:56:59 +01:00
committed by GitHub
parent 19341205b7
commit 32c1150b28
6 changed files with 33 additions and 22 deletions

View File

@@ -25,7 +25,7 @@ import (
)
var configPath string
var disallowExemptions bool
var disallowExemptions, disallowConfigExemptions, disallowAnnotationExemptions bool
var logLevel string
var auditPath string
var displayName string
@@ -37,7 +37,9 @@ var (
func init() {
// Flags
rootCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "Location of Polaris configuration file.")
rootCmd.PersistentFlags().BoolVarP(&disallowExemptions, "disallow-exemptions", "", false, "Disallow any exemptions from configuration file.")
rootCmd.PersistentFlags().BoolVarP(&disallowExemptions, "disallow-exemptions", "", false, "Disallow any configured exemption.")
rootCmd.PersistentFlags().BoolVarP(&disallowConfigExemptions, "disallow-config-exemptions", "", false, "Disallow exemptions set within the configuration file.")
rootCmd.PersistentFlags().BoolVarP(&disallowAnnotationExemptions, "disallow-annotation-exemptions", "", false, "Disallow any exemption defined as a controller annotation.")
rootCmd.PersistentFlags().StringVarP(&logLevel, "log-level", "", logrus.InfoLevel.String(), "Logrus log level.")
flag.Parse()
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
@@ -63,10 +65,9 @@ var rootCmd = &cobra.Command{
os.Exit(1)
}
if disallowExemptions {
config.DisallowExemptions = true
}
config.DisallowExemptions = disallowExemptions
config.DisallowConfigExemptions = disallowConfigExemptions
config.DisallowAnnotationExemptions = disallowAnnotationExemptions
},
Run: func(cmd *cobra.Command, args []string) {
logrus.Error("You must specify a sub-command.")

View File

@@ -19,10 +19,12 @@ webhook
Runs the webhook webserver
# global flags
-c, --config string Location of Polaris configuration file.
--disallow-exemptions Disallow any exemptions from configuration file.
--kubeconfig string Paths to a kubeconfig. Only required if out-of-cluster.
--log-level string Logrus log level. (default "info")
-c, --config string Location of Polaris configuration file.
--disallow-exemptions Disallow any exemptions from configuration file.
--disallow-config-exemptions Disallow exemptions set within the configuration file.
--disallow-annotation-exemptions Disallow any exemption defined as a controller annotation.
--kubeconfig string Paths to a kubeconfig. Only required if out-of-cluster.
--log-level string Logrus log level. (default "info")
# dashboard flags
--audit-path string If specified, audits one or more YAML files instead of a cluster.

View File

@@ -29,11 +29,13 @@ import (
// Configuration contains all of the config for the validation checks.
type Configuration struct {
DisplayName string `json:"displayName"`
Checks map[string]Severity `json:"checks"`
CustomChecks map[string]SchemaCheck `json:"customChecks"`
Exemptions []Exemption `json:"exemptions"`
DisallowExemptions bool `json:"disallowExemptions"`
DisplayName string `json:"displayName"`
Checks map[string]Severity `json:"checks"`
CustomChecks map[string]SchemaCheck `json:"customChecks"`
Exemptions []Exemption `json:"exemptions"`
DisallowExemptions bool `json:"disallowExemptions"`
DisallowConfigExemptions bool `json:"disallowConfigExemptions"`
DisallowAnnotationExemptions bool `json:"disallowAnnotationExemptions"`
}
// Exemption represents an exemption to normal rules

View File

@@ -11,7 +11,7 @@ func (conf Configuration) IsActionable(ruleID string, objMeta metav1.Object, con
if severity, ok := conf.Checks[ruleID]; !ok || !severity.IsActionable() {
return false
}
if conf.DisallowExemptions {
if conf.DisallowExemptions || conf.DisallowConfigExemptions {
return true
}
for _, exemption := range conf.Exemptions {

View File

@@ -130,13 +130,17 @@ func writeTemplate(tmpl *template.Template, data *templateData, w http.ResponseW
func getConfigForQuery(base config.Configuration, query url.Values) config.Configuration {
c := base
exemptions := query.Get("disallowExemptions")
if exemptions == "false" {
c.DisallowExemptions = false
}
if exemptions == "true" {
switch query.Get("disallowExemptions") {
case "true":
c.DisallowExemptions = true
c.DisallowConfigExemptions = true
c.DisallowAnnotationExemptions = true
default:
c.DisallowExemptions = false
c.DisallowConfigExemptions = false
c.DisallowAnnotationExemptions = false
}
return c
}

View File

@@ -23,7 +23,9 @@ type schemaTestCase struct {
}
func resolveCheck(conf *config.Configuration, checkID string, test schemaTestCase) (*config.SchemaCheck, error) {
if !conf.DisallowExemptions && hasExemptionAnnotation(test.Resource.ObjectMeta, checkID) {
if !conf.DisallowExemptions &&
!conf.DisallowAnnotationExemptions &&
hasExemptionAnnotation(test.Resource.ObjectMeta, checkID) {
return nil, nil
}
check, ok := conf.CustomChecks[checkID]