Package: k8s-audit-filter
Filter K8s Audit LogsAbstractThis library provides a simple way to filter Kubernetes audit logs, if you, whit some reason, are not able to apply
audit policy directly at your cloud (e. g. in yandex cloud) and have to filter it with python script.
Also you can use this library to analyze audit logs.
The library does not provide any service, it just give you easy way to filter audit logs in your python script
withAuditFilterclass interfaces.Instalationpipinstallk8s-audit-filterUsageYou can easly modify your python script to filter audit logs.
Just importAuditFilterclass, init it with youraudit-policy.yamlfile and use it's methods.
See an example of modification
ofthis script:importjsonimportosimportboto3importstringimportrandomfromdatetimeimportdatetimefromk8s_audit_filterimportAuditFilter# import AuditFilter classdefget_random_alphanumeric_string(length):letters_and_digits=string.ascii_letters+string.digitsresult_str=''.join((random.choice(letters_and_digits)foriinrange(length)))returnresult_strclient=boto3.client(service_name='s3',endpoint_url='https://storage.yandexcloud.net',region_name='ru-central1')defhandler(event,context):forlog_datainevent['messages']:full_log=[]forlog_entryinlog_data['details']['messages']:kubernetes_log=json.loads(log_entry['message'])full_log.append(json.dumps(kubernetes_log))audit_filter=AuditFilter('path/to/audit_policy.yaml')# init AuditFilter class with path to audit policy filefiltered_log=[lineforlineinfull_logifaudit_filter.filter(full_log)]# filter audit logsbucket_name=os.environ.get('BUCKET_NAME')object_key='AUDIT/'+os.environ.get('CLUSTER_ID')+'/'+datetime.now().strftime('%Y-%m-%d-%H:%M:%S')+'-'+get_random_alphanumeric_string(5)object_value='\n'.join(filtered_log)# prepare data to load# load data to cloud storageclient.put_object(Bucket=bucket_name,Key=object_key,Body=object_value,StorageClass='COLD')Also you can update your policy dinamically, just useadd_ruleandremove_rulemethod:fromk8s_audit_filterimportAuditFilteraudit_filter=AuditFilter()# init AuditFilter class with blink audit policyaudit_filter.add_rule({'level':'Metadata'})audit_filter.filter({'level':'Metadata'})# return Trueaudit_filter.remove_rule({'level':'Metadata'})audit_filter.filter({'level':'Metadata'})# return FalseDescribing Audit PolicyYou can use find the way to describe k8s audit policy rules in Official Kubernetes Documentation athttps://kubernetes.io/docs/reference/config-api/apiserver-audit.v1/See example of audit policy:apiVersion:audit.k8s.io/v1# This is required.kind:Policyrules:# Include line in the audit log which contains verb "get" and have level "Metadata"-level:Metadataverbs:-"get"# Exclude line in the audit log which contains verb "create"-level:Noneverbs:-"create"-level:Requestusers:-"admin"-level:RequestuserGroups:-"system:admins"Describing Audit Policy in PythonIf you want to describe audit policy in python, you can describe it in the same way as in yaml file with dict:fromk8s_audit_filterimportAuditFilteraudit_filter=AuditFilter()rules=[{'level':'Metadata','verbs':['get']},{'level':'None','verbs':['create']},{'level':'Request','users':['admin']},{'level':'Request','userGroups':['system:admins']},{'level':'Request','namespaces':['kube-system']},{'level':'RequestResponse','resources':[{'group':'','resources':['deployments'],'resourceNames':['pods']},{'group':'apps','resources':['leases'],'resourceNames':['test']}]}]audit_filter.add_rules(rules)Supported RulesPlease note, thatlevelis required field for every rule, and should have of one of next values:None- do not log events that match this rule (this is ExcludeRule)Metadata- log line marked as "Metadata"Request- log line marked as "Request"RequestResponse- log line marked as "RequestResponse"The library supports the following rules k8s audit PolicyRules:levelverbsusersuserGroupsnamespacesresources- Partly supported. Please read about limitations belowLimitationsThe library does not support following k8s Audit rules:resources- please note, that unlike original k8s audit policy, empty string "" in "group" field will not return "core" group, but will return all groupsnonResourceURLs- notResourceURLs are not declared explicitly in audit logsomitStages- now it does not discern any stagesomitManagedFields- omitManagedFields is not declared explicitly in audit logs