Issue
-
I would like to serve resources from Jenkins. For instance, I would like to publish an HTML report. Because of the strict Content Security Policy set by Jenkins, I cannot load resources from other domains.
-
I see an administrative monitor stating
The default Content-Security-Policy is currently overridden using the hudson.model.DirectoryBrowserSupport.CSP system property, which is a potential security issue when browsing untrusted files. As an alternative, you can set up a Resource Root URL that Jenkins will use to serve some static files without adding Content-Security-Policy headers.
.
Environment
-
CloudBees CI (CloudBees Core) on modern cloud platforms - Managed controller >= 2.204
-
CloudBees CI (CloudBees Core) on modern cloud platforms - Operations Center >= 2.204
-
CloudBees CI (CloudBees Core) on traditional platforms - Client controller >= 2.204
-
CloudBees CI (CloudBees Core) on traditional platforms - Operations Center >= 2.204
-
CloudBees Jenkins Enterprise - Managed controller >= 2.204
-
CloudBees Jenkins Enterprise - Operations center >= 2.204
-
Jenkins LTS >= 2.204
Resolution
Up until Jenkins 2.204 (weekly 2.200), the only way to working around the strict content policy was to relax it. Please refer to What is Content Security Policy and how does it impact Jenkins? for more information on the topic.
Since Jenkins 2.204, a new feature allows to serve resource from another domain without modifying the Content Security Policy. The recommended solutions are documented at:
CloudBees CI in Modern Platforms Special Cases
In CloudBees CI in Modern Platforms, the Resource Root URL functionality requires 2 things once the DNS record has been set up:
-
that an ingress rule be added for the Resource host pointing to the controller service
-
that the Controller be configured with the Resource Root URL
The Controller Provisioning configuration solution explained in CloudBees CI on Modern platforms - Serving resources from Jenkins does this automatically and is the recommended solution. There are however a few cases where this solution might not be suited:
In such cases, either an additional Ingress rule or a custom Ingress object must be added to the controller’s provisioning. While this seems cumbersome, CasC for Operations Center and CasC for Controller can greatly help.
Using a separate Ingress class for the Resource host
In this case, an additional Ingress resource must be added as one Ingress resource can be bound to one Ingress Class only.
-
In the configuration of a Controller item, add an Ingress resource for the Resource Host and the correct Ingress class in the YAML section:
--- apiVersion: "networking.k8s.io/v1" kind: "Ingress" metadata: name: "${name}" spec: ingressClassName: <resource_ingress_class> rules: - host: "<resourceHost>" http: paths: - backend: service: name: "${name}" port: number: 80 path: "${path}" pathType: Prefix
-
Still in the configuration of a Controller item, add the System Property
MASTER_RESOURCE_URL=https://<resourceHost>/<controllerPath>/
(orhttp
if not usinghttps
) to the System Properties field. -
Stop / Start the Controller (not Restart, a Stop and Start is needed for the Ingress objects to be updated)
Using Subdomains
In this case, the controller ingress needs to be customized.
-
In the configuration of a Controller item, add an Ingress resource for the Controller Resource Host and the correct Ingress class in the YAML section:
--- apiVersion: "networking.k8s.io/v1" kind: "Ingress" spec: rules: - host: "<controllerResourceHost>" # Resource host for this controller http: paths: - backend: service: name: "${name}" port: number: 80 path: "${path}" pathType: Prefix
-
Still in the configuration of a Controller item, add the System Property
MASTER_RESOURCE_URL=https://<controllerResourceHost>/
(orhttp
if not usinghttps
) to the System Properties field. -
Stop / Start the Controller (not Restart, a Stop and Start is needed for the Ingress objects to be updated)
Using CloudBees CI on Modern Platforms < 2.204.2.2
Before CloudBees CI on Modern Platforms 2.204.2.2, there was no global feature to configure the Resource Root URL of controllers from Operations Center. The Ingresses and the Controllers needed to be configured manually.
Similar to using Subdomains:
-
In the configuration of a Controller item, add an Ingress resource for the Controller Resource Host and the correct Ingress class in the YAML section:
--- apiVersion: "networking.k8s.io/v1" kind: "Ingress" spec: rules: - host: "<resourceHost>" http: paths: - backend: service: name: "${name}" port: number: 80 path: "${path}" pathType: Prefix
-
Still in the configuration of a Controller item, add the System Property
MASTER_RESOURCE_URL=https://<resourceHost>/<controllerPath>/
(orhttp
if not usinghttps
) to the System Properties field. -
Stop / Start the Controller (not Restart, a Stop and Start is needed for the Ingress objects to be updated)