Control WordPress Plugin and Theme Auto-Updates with auto_update_plugin Filter (WP 5.5)

WordPress 5.5 added automatic updates for plugins and themes — an opt-in system controlled through the Plugins and Themes admin screens. Administrators can toggle auto-updates per plugin or theme, and WordPress applies approved updates automatically in the background during the next maintenance run. Before 5.5 this required either manual configuration in wp-config.php (the AUTOMATIC_UPDATER_DISABLED and auto_update_* constants) or a third-party plugin. The 5.5 UI makes the feature accessible to non-developers, but the filter layer beneath it is what matters for site managers and developers who need consistent, code-enforced update policies: auto_update_plugin and auto_update_theme filters let you return true or false for any specific slug, overriding whatever the UI setting says. This is essential for managed hosting environments, multisite networks, and CI/CD pipelines where human-per-site UI interaction is impractical.

Problem: You manage a WordPress multisite network and want to auto-update all security-related plugins (Wordfence, WP Mail SMTP) automatically but prevent auto-updates for WooCommerce and theme files that require manual QA before deployment.

Solution: Use the auto_update_plugin and auto_update_theme filters to return true or false based on the plugin slug, overriding UI settings programmatically from a must-use plugin or wp-config.php.

<?php
// ── Plugin auto-updates ────────────────────────────────────────────────
add_filter( 'auto_update_plugin', 'control_plugin_auto_updates', 10, 2 );

function control_plugin_auto_updates( $update, $item ) {
    // $item is an object from the Update API; $item->slug is the plugin folder name

    // Always auto-update these security plugins
    $always_update = [ 'wordfence', 'wp-mail-smtp', 'limit-login-attempts-reloaded' ];
    if ( in_array( $item->slug, $always_update, true ) ) {
        return true;
    }

    // Never auto-update WooCommerce or payment gateways (require manual QA)
    $never_update = [ 'woocommerce', 'woocommerce-gateway-stripe', 'woocommerce-paypal-payments' ];
    if ( in_array( $item->slug, $never_update, true ) ) {
        return false;
    }

    return $update; // respect UI setting for all others
}

// ── Theme auto-updates ─────────────────────────────────────────────────
add_filter( 'auto_update_theme', function ( $update, $item ) {
    // Never auto-update the active custom theme (manual review required)
    if ( get_stylesheet() === $item->theme ) {
        return false;
    }
    return $update;
}, 10, 2 );

// ── Core auto-updates (minor = security/maintenance, major = new versions)
add_filter( 'allow_minor_auto_core_updates', '__return_true'  ); // always apply security updates
add_filter( 'allow_major_auto_core_updates', '__return_false' ); // block major version upgrades

NOTE: Filters added in wp-config.php do not work — wp-config.php runs too early for the filter system. Put the code in a must-use plugin (wp-content/mu-plugins/auto-updates.php) which loads before regular plugins and applies to every site on a multisite network. The auto_update_plugin filter takes priority over the UI toggle — if the filter returns a non-null value, it overrides whatever the checkbox in the admin says.