Change:
Currently the [audit policy decoder][1] silently drops unknown fields. For backwards compatibility, we probably cannot fail on unknown fields, but it would be good to at least log a warning when they're encountered. [1]: /sig api-machinery
/triage accepted
/help
This request has been marked as needing help from a contributor. Please ensure that the issue body includes answers to the following questions: Why are we solving this issue? To address this issue, are there any code changes? If there are code changes, what needs to be done in the code and what places can the assignee treat as reference points? Does this issue have zero to low barrier of entry? How can the assignee reach out to you for help? For more details on the requirements of such an issue, please see and ensure that they are met. If this request no longer meets these requirements, the label can be removed by commenting with the command. <detailsIn response to : /help Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
I'm not familiar with apiserver, but this seems like a simple one. /assign
How can we find unknown fields in the yaml file? Currently I'm think of converting both the yaml file and the decoded Policy struct to two map[string]interface{}, and compare both map to find out which keys are in the yaml file but not in the decoded struct, is there any better solution?
Courtesy on slack:

Discussion:
"fmt" "io/ioutil" <ins> "k8s.io/apimachinery/pkg/runtime" </ins> "k8s.io/apimachinery/pkg/runtime/schema" <ins> "k8s.io/apimachinery/pkg/runtime/serializer" </ins> auditinternal "k8s.io/apiserver/pkg/apis/audit" auditv1 "k8s.io/apiserver/pkg/apis/audit/v1" "k8s.io/apiserver/pkg/apis/audit/validation" "k8s.io/apiserver/pkg/audit" "k8s.io/klog/v2" )

func LoadPolicyFromBytes(policyDef []byte) (*auditinternal.Policy, error) { policy := &auditinternal.Policy{} <del> decoder := audit.Codecs.UniversalDecoder(apiGroupVersions...) </del> <ins> strictDecoder := serializer.NewCodecFactory(audit.Scheme, serializer.EnableStrict).UniversalDecoder() </ins> <del> _, gvk, err := decoder.Decode(policyDef, nil, policy) </del> <ins> // Try strict decoding first. _, gvk, err := strictDecoder.Decode(policyDef, nil, policy) </ins> if err != nil { <del> return nil, fmt.Errorf("failed decoding: %v", err) </del> <ins> if !runtime.IsStrictDecodingError(err) { return nil, fmt.Errorf("failed decoding: %w", err) } var ( lenientDecoder = audit.Codecs.UniversalDecoder(apiGroupVersions...) lenientErr     error ) _, gvk, lenientErr = lenientDecoder.Decode(policyDef, nil, policy) if lenientErr != nil { return nil, fmt.Errorf("failed lenient decoding: %w", lenientErr) } klog.Warningf("Audit policy contains errors, falling back to lenient decoding: %v", err) </ins> } // Ensure the policy file contained an apiVersion and kind.

"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apiserver/pkg/apis/audit" // import to call webhook's init() function to register audit.Policy to schema _ "k8s.io/apiserver/plugin/pkg/audit/webhook"

- level: Metadata ` <ins> const policyWithUnknownField = ` apiVersion: audit.k8s.io/v1 kind: Policy rules: - level: None resources: - group: coordination.k8s.io resources: - "leases" verbs: ["watch", "get", "list"] # invalid indentation on verbs ` </ins> var expectedPolicy = &audit.Policy{ Rules: []audit.PolicyRule{{ Level:           audit.LevelNone,

assert.Contains(t, err.Error(), "unknown group version field") } <ins> func TestParsePolicyWithUnknownField(t *testing.T) { f, err := writePolicy(t, policyWithUnknownField) require.NoError(t, err) defer os.Remove(f) _, err = LoadPolicyFromFile(f) require.NoError(t, err) } </ins> func TestPolicyCntCheck(t *testing.T) { var testCases = []struct { caseName, policy string