Install the Nexus Apply plugin (secret endpoint)

A must-use plugin that lets fixes apply even when your host strips the auth header.

10 min read Advanced

When a CDN strips the Authorization header, this must-use plugin (mu-plugin) adds a REST endpoint that authenticates with a shared secret sent in the request body, which CDNs forward normally. It only sets Media Library alt text.

1. Generate a secret

Create a long random string (e.g. 48 hex characters). Keep it somewhere safe, you'll paste it into the plugin and into the platform's CMS connection.

2. Create the file

  1. 1In your host's File Manager, go to public_html/wp-content/.
  2. 2If there's no mu-plugins folder, create one named exactly mu-plugins.
  3. 3Inside it, create a file named exactly nexus-apply.php.
  4. 4Paste the code below, replacing YOUR_SHARED_SECRET with the secret you generated.
  5. 5Save.
wp-content/mu-plugins/nexus-apply.php
<?php
/**
 * Plugin Name: Nexus Apply
 * Sets Media Library alt text via a secret in the request body,
 * so it works on hosts that strip the Authorization header.
 */
add_action('rest_api_init', function () {
    register_rest_route('nexus/v1', '/set-alt', array(
        'methods'             => 'POST',
        'permission_callback' => '__return_true',
        'callback'            => function ($req) {
            $p      = $req->get_json_params();
            $secret = isset($p['secret']) ? (string) $p['secret'] : '';
            if (!hash_equals('YOUR_SHARED_SECRET', $secret)) {
                return new WP_REST_Response(array('ok' => false, 'error' => 'bad secret'), 403);
            }
            $id        = isset($p['media_id']) ? intval($p['media_id']) : 0;
            $alt       = isset($p['alt']) ? sanitize_text_field($p['alt']) : '';
            $overwrite = !empty($p['overwrite']);
            if (!$id || $alt === '') {
                return new WP_REST_Response(array('ok' => false, 'error' => 'need media_id and alt'), 400);
            }
            if (get_post_type($id) !== 'attachment') {
                return new WP_REST_Response(array('ok' => false, 'error' => 'not an attachment'), 404);
            }
            $existing = get_post_meta($id, '_wp_attachment_image_alt', true);
            if (!$overwrite && is_string($existing) && trim($existing) !== '') {
                return new WP_REST_Response(array('ok' => true, 'kept' => true, 'alt' => $existing), 200);
            }
            update_post_meta($id, '_wp_attachment_image_alt', $alt);
            return new WP_REST_Response(array('ok' => true, 'id' => $id, 'alt' => $alt), 200);
        },
    ));
    register_rest_route('nexus/v1', '/publish-post', array(
        'methods'             => 'POST',
        'permission_callback' => '__return_true',
        'callback'            => function ($req) {
            $p      = $req->get_json_params();
            $secret = isset($p['secret']) ? (string) $p['secret'] : '';
            if (!hash_equals('YOUR_SHARED_SECRET', $secret)) {
                return new WP_REST_Response(array('ok' => false, 'error' => 'bad secret'), 403);
            }
            $title   = isset($p['title']) ? sanitize_text_field($p['title']) : '';
            $content = isset($p['content']) ? (string) $p['content'] : '';
            if ($title === '' || $content === '') {
                return new WP_REST_Response(array('ok' => false, 'error' => 'need title and content'), 400);
            }
            $status  = (isset($p['status']) && $p['status'] === 'publish') ? 'publish' : 'draft';
            $args = array(
                'post_title'   => $title,
                'post_content' => $content,
                'post_excerpt' => isset($p['excerpt']) ? sanitize_text_field($p['excerpt']) : '',
                'post_name'    => isset($p['slug']) ? sanitize_title($p['slug']) : '',
                'post_status'  => $status,
                'post_type'    => 'post',
            );
            if (!empty($p['author_login'])) {
                $who    = sanitize_text_field($p['author_login']);
                $author = get_user_by('login', $who);
                if (!$author) { $author = get_user_by('slug', sanitize_title($who)); }
                if (!$author) {
                    $matches = get_users(array('search' => $who, 'search_columns' => array('display_name', 'user_login', 'user_nicename'), 'number' => 1));
                    if (!empty($matches)) { $author = $matches[0]; }
                }
                if ($author) { $args['post_author'] = $author->ID; }
            }
            // Our content is trusted (secret-gated), so keep its markup (div/details/class).
            kses_remove_filters();
            $post_id = wp_insert_post($args, true);
            kses_init_filters();
            if (is_wp_error($post_id)) {
                return new WP_REST_Response(array('ok' => false, 'error' => $post_id->get_error_message()), 500);
            }
            if (!empty($p['category'])) {
                $cat  = sanitize_text_field($p['category']);
                $term = term_exists($cat, 'category');
                if (!$term) { $term = wp_insert_term($cat, 'category'); }
                if (!is_wp_error($term) && isset($term['term_id'])) {
                    wp_set_post_categories($post_id, array((int) $term['term_id']));
                }
            }
            if (!empty($p['tags'])) {
                $tags = is_array($p['tags']) ? $p['tags'] : array_map('trim', explode(',', (string) $p['tags']));
                wp_set_post_tags($post_id, $tags, false);
            }
            // SEO plugin fields, Rank Math and Yoast keys (whichever is active reads them).
            if (!empty($p['focus_keyword'])) {
                update_post_meta($post_id, 'rank_math_focus_keyword', sanitize_text_field($p['focus_keyword']));
                update_post_meta($post_id, '_yoast_wpseo_focuskw', sanitize_text_field($p['focus_keyword']));
            }
            if (!empty($p['seo_title'])) {
                update_post_meta($post_id, 'rank_math_title', sanitize_text_field($p['seo_title']));
                update_post_meta($post_id, '_yoast_wpseo_title', sanitize_text_field($p['seo_title']));
            }
            if (!empty($p['seo_description'])) {
                update_post_meta($post_id, 'rank_math_description', sanitize_text_field($p['seo_description']));
                update_post_meta($post_id, '_yoast_wpseo_metadesc', sanitize_text_field($p['seo_description']));
            }
            if (!empty($p['faq_jsonld'])) {
                update_post_meta($post_id, '_nexus_faq_jsonld', $p['faq_jsonld']);
            }
            $thumb = null;
            if (!empty($p['featured_image_url'])) {
                require_once ABSPATH . 'wp-admin/includes/media.php';
                require_once ABSPATH . 'wp-admin/includes/file.php';
                require_once ABSPATH . 'wp-admin/includes/image.php';
                $att = media_sideload_image(esc_url_raw($p['featured_image_url']), $post_id, $title, 'id');
                if (!is_wp_error($att)) { set_post_thumbnail($post_id, $att); $thumb = $att; }
            }
            return new WP_REST_Response(array('ok' => true, 'id' => $post_id, 'link' => get_permalink($post_id), 'thumb' => $thumb), 200);
        },
    ));
    register_rest_route('nexus/v1', '/ping', array(
        'methods'             => 'GET',
        'permission_callback' => '__return_true',
        'callback'            => function () {
            return new WP_REST_Response(array('ok' => true, 'service' => 'nexus-apply', 'version' => 2), 200);
        },
    ));
    // Self-update: the trigger carries only the secret (no code), so a hosting
    // WAF has nothing to flag. The plugin then FETCHES the new version from the
    // app itself (outbound request, not inspected) and overwrites its own file.
    register_rest_route('nexus/v1', '/self-update', array(
        'methods'             => 'POST',
        'permission_callback' => '__return_true',
        'callback'            => function ($req) {
            $p      = $req->get_json_params();
            $secret = isset($p['secret']) ? (string) $p['secret'] : '';
            if (!hash_equals('YOUR_SHARED_SECRET', $secret)) {
                return new WP_REST_Response(array('ok' => false, 'error' => 'bad secret'), 403);
            }
            $url  = '__NEXUS_APP_URL__/api/nexus-plugin?project=__NEXUS_PROJECT__&secret=' . rawurlencode($secret);
            $resp = wp_remote_get($url, array('timeout' => 25));
            if (is_wp_error($resp)) {
                return new WP_REST_Response(array('ok' => false, 'error' => $resp->get_error_message()), 502);
            }
            $code = wp_remote_retrieve_body($resp);
            if (strpos($code, '<?php') !== 0 || strpos($code, 'Plugin Name: Nexus Apply') === false) {
                return new WP_REST_Response(array('ok' => false, 'error' => 'fetched code invalid'), 400);
            }
            $bytes = file_put_contents(__FILE__, $code);
            if ($bytes === false) {
                return new WP_REST_Response(array('ok' => false, 'error' => 'could not write file (check permissions)'), 500);
            }
            return new WP_REST_Response(array('ok' => true, 'bytes' => $bytes), 200);
        },
    ));
});

// On single posts: inject readable, scoped styling for our articles + the FAQ
// JSON-LD (saved by /publish-post). The CSS only targets .nexus-article, so it
// can't affect the rest of your theme.
add_action('wp_head', function () {
    if (is_singular('post')) {
        echo '<style>.nexus-article{max-width:760px;margin:0 auto;font-size:18px;line-height:1.75;color:#1f2430}.nexus-article h2{font-size:1.55em;font-weight:800;margin:2.2em 0 .7em;line-height:1.25;letter-spacing:-.01em}.nexus-article h3{font-size:1.2em;font-weight:700;margin:1.8em 0 .5em}.nexus-article p{margin:0 0 1.15em}.nexus-article ul,.nexus-article ol{margin:0 0 1.3em;padding-left:1.4em}.nexus-article li{margin:.45em 0}.nexus-article a{color:#de0d0d;text-decoration:underline;text-underline-offset:2px}.nexus-article strong{color:#0f172a}.nexus-article table{width:100%;border-collapse:collapse;margin:1.6em 0;font-size:.95em}.nexus-article th,.nexus-article td{border:1px solid #e5e7eb;padding:.6em .8em;text-align:left}.nexus-article th{background:#fafafa;font-weight:700}.nexus-faq{border:1px solid #e5e7eb;border-radius:14px;overflow:hidden;margin:.6em 0 2em}.nexus-faq details{border-bottom:1px solid #eee}.nexus-faq details:last-child{border-bottom:0}.nexus-faq summary{cursor:pointer;padding:1em 1.2em;font-weight:600;list-style:none}.nexus-faq summary::-webkit-details-marker{display:none}.nexus-faq details[open] summary{color:#de0d0d}.nexus-faq details>div{padding:0 1.2em 1.1em;color:#475569}.nexus-related{margin-top:2.5em;padding:1.2em 1.4em;background:#fafafa;border:1px solid #eee;border-radius:14px}.nexus-related h2{margin:0 0 .5em;font-size:1.1em}.nexus-related ul{margin:0;padding-left:1.2em}</style>';
        $jsonld = get_post_meta(get_the_ID(), '_nexus_faq_jsonld', true);
        if (is_string($jsonld) && $jsonld !== '') { echo $jsonld; }
    }
});

3. Confirm it's live

Visit yoursite.com/wp-json/nexus/v1/ping in a browser, you should see {"ok":true,"service":"nexus-apply"}. If you get a 404, the file name or folder is wrong.

4. Tell the platform to use it

In the CMS connection, put the same secret in the Token field so the platform routes alt applies through the endpoint. Contact support if you need the connection switched to this mode.

This endpoint sets alt text only. Link titles and content edits still need the Authorization header, so fix that (Fixes 1-2 in the auth-header guide) if you want those automated too.

To close the endpoint later, just delete nexus-apply.php. To rotate the secret, change it in both the file and the platform.

Related guides

Still stuck?

We’ll get back within one business day.

Contact support