Using Config Auditing to debug cluster issues
Config Auditing reveals which configs was changed, what changes were made, when the modification occurred, and who made the changes. Auditing provides traceability, accountability, and recoverability.
Config Auditing simplifies:
- debugging issues caused by configuration changes (cyber forensics)
- restoring a config that was incorrectly modified or deleted
- identify users improperly changing configs
Overview
For every Config operation such as setConfig, Config.AuditLog is created and upserted, unless it is explicitly excluded from auditing. Each Config.AuditLog contains fields such as the Config#type, root Action, User#id, etc.
Set up
Enable/Disable auditing
To enable or disable auditing for the entire cluster, run the following as Cluster Admin. To disable for specific apps or configs, see "Excluding certain config operations from auditing"
// enable
Config.AuditLogConfig.inst().enable(); // Sets the path to write auditing data using the current app's default FileSystem
// disable
Config.AuditLogConfig.inst().disable();Common queries and usages
NOTE: The partition key for the Config.AuditLog table is ConfigType. This means filtering for configType is faster than filtering for other fields, and in fact specifying the configType for each query is currently required. See KvStore.Filesystem.
Config.AuditLog operations are restricted to Cluster Admin only.
Find all changes made to a specific config
JavaScriptConfig.AuditLog.fetch(Filter.eq('configType', 'myConfigType'));Find a change to type made by a specific user
JavaScriptConfig.AuditLog.fetch(Filter.eq('configType', 'myConfigType').and().eq('userId', 'myUserId'));Find changes across multiple types made by a specific user
JavaScriptconfigTypes = ["configType0", "configType1", "configType2"] result = [] for (let i = 0; i < configTypes.length; i++) { result.push.apply(result, Config.AuditLog.fetch(Filter.eq('configType', configTypes[i]).and().eq('userId', 'myUserId')).objs); }- Note again that the
configTypeis still required because of it is the partition key
- Note again that the
Excluding certain config operations from auditing
Config.AuditLogConfig.builder()
.excludeTypes(["CryptoPrivateKey"]) // excludes all config operations on `CryptoPrivateKey`s
.excludeAllNonPlatformTypes(false) // excludes all config operations on non-platform types
.excludeUserIds(["exampleuserid"]) // excludes all config operations by user with ID `exampleuserid`
.excludeAppIds(["cluster1-env1-app1"]) // excludes all config operations run on the app with ID `cluster1-env1-app1`
.build().setConfig()