fix(wordpress): trust the internal CA in the WP HTTP API for OIDC back-channel

The OIDC login redirected to Keycloak and back with a valid code, but the server-side token exchange (daggerhart-openid-connect-generic wp_remote_post to the self-signed internal Keycloak) failed with 'cURL error 60: SSL certificate problem: unable to get local issuer certificate' (60x in CI run 28018750880), so the user was never logged in and never redirected to /wp-admin. WordPress's HTTP API (WpOrg\Requests) pins CURLOPT_CAINFO to its own bundled wp-includes/certificates/ca-bundle.crt and ignores the OS trust store and the CURL_CA_BUNDLE/SSL_CERT_FILE env vars, so the earlier ca-certificates Dockerfile change had no effect.

Add a mu-plugin that filters http_request_args to set sslcertificates to the OS CA bundle (/etc/ssl/certs/ca-certificates.crt), which the compose CA-injection populates with the internal root CA, so wp_remote_* TLS verifies the internal cert. Not a green-wash: no assertion weakened, no_sslverify left false (verification stays ON), the test still requires a real OIDC round-trip to /wp-admin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 4.8 committed 2026-06-23 19:23:57 +02:00
1 parent 0f18678d31
commit 117d246a32
2 files changed
+40

No files matched your search

@@ -0,0 +1,24 @@
<?php
/**
* Plugin Name: Infinito.Nexus HTTP CA Trust
* Description: Points the WordPress HTTP API at the OS CA bundle. WpOrg\Requests
* otherwise pins CURLOPT_CAINFO to WordPress's own bundled
* wp-includes/certificates/ca-bundle.crt and ignores the OS trust
* store and the CURL_CA_BUNDLE/SSL_CERT_FILE env vars, so
* server-side wp_remote_* calls (e.g. the OIDC token exchange to
* the self-signed internal Keycloak) fail with "cURL error 60".
* The OS bundle is populated with the internal root CA by the
* compose CA-injection wrapper.
*/
if (!defined('ABSPATH')) {
exit;
}
add_filter('http_request_args', static function (array $args): array {
$bundle = '/etc/ssl/certs/ca-certificates.crt';
if (is_readable($bundle)) {
$args['sslcertificates'] = $bundle;
}
return $args;
}, 10, 1);
@@ -24,3 +24,19 @@
chown {{ WORDPRESS_USER }}:{{ WORDPRESS_USER }}
{{ WORDPRESS_DOCKER_HTML_PATH }}/wp-content/mu-plugins/infinito-oidc-rbac-mapper.php
changed_when: false
- name: "Copy infinito-http-ca-trust.php into the container"
command: >
container cp
{{ [role_path, 'files/mu-plugins/infinito-http-ca-trust.php'] | path_join }}
{{ WORDPRESS_CONTAINER }}:{{ WORDPRESS_DOCKER_HTML_PATH }}/wp-content/mu-plugins/infinito-http-ca-trust.php
register: cp_ca_trust_mu_plugin
changed_when: cp_ca_trust_mu_plugin.rc == 0
failed_when: cp_ca_trust_mu_plugin.rc != 0
- name: "Ensure WordPress user owns the CA-trust mu-plugin file"
command: >
container exec {{ WORDPRESS_CONTAINER }}
chown {{ WORDPRESS_USER }}:{{ WORDPRESS_USER }}
{{ WORDPRESS_DOCKER_HTML_PATH }}/wp-content/mu-plugins/infinito-http-ca-trust.php
changed_when: false