How to Serve Resources from Jenkins

Article ID:360038990971
3 minute readKnowledge base

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..

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>/ (or http if not using https) 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>/ (or http if not using https) 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>/ (or http if not using https) to the System Properties field.

  • Stop / Start the Controller (not Restart, a Stop and Start is needed for the Ingress objects to be updated)

Tested product/plugin versions

  • CloudBees CI on Modern Platforms 2.332.3.4