# How Jenkins Manages Workspaces with FilePath, WorkspaceBrowser, and DirectoryBrowserSupport

> Discover how Jenkins manages workspaces using FilePath, WorkspaceBrowser, and DirectoryBrowserSupport for efficient file operations and secure directory browsing.

- Repository: [Jenkins/jenkins](https://github.com/jenkinsci/jenkins)
- Tags: internals
- Published: 2026-07-28

---

**Jenkins uses the `WorkspaceBrowser` extension point to locate job workspaces, `FilePath` to abstract file operations across agents, and `DirectoryBrowserSupport` to securely render directory listings and handle downloads via the `/ws/` URL endpoint.**

Jenkins stores build artifacts and source code in job-specific workspaces that must be accessible through the web UI and API while maintaining strict security controls. In the jenkinsci/jenkins repository, the core workspace management architecture relies on three key components: **FilePath** for agent-side file abstraction, **WorkspaceBrowser** for workspace discovery, and **DirectoryBrowserSupport** for HTTP serving and security enforcement.

## The Workspace Management Architecture

### FilePath for Distributed File Operations

The `FilePath` class provides a unified interface for file operations across Jenkins controllers and agents. This abstraction allows workspace operations to execute remotely on build agents while being controlled from the controller, enabling seamless access to files regardless of where the build executed.

### WorkspaceBrowser Extension Point

Located in [`core/src/main/java/hudson/model/WorkspaceBrowser.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/model/WorkspaceBrowser.java), this abstract class defines the extension point for custom workspace location logic. Plugins implement the `getWorkspace(AbstractProject<?,?> project)` method to return a `FilePath` pointing to the workspace directory.

Method signature:

```java
public abstract @CheckForNull FilePath getWorkspace(AbstractProject<?,?> project)

```

Jenkins discovers implementations automatically through the extension mechanism, allowing multiple plugins to contribute workspace resolution strategies.

### DirectoryBrowserSupport for HTTP Serving

Implemented in [`core/src/main/java/hudson/model/DirectoryBrowserSupport.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/model/DirectoryBrowserSupport.java), this class handles HTTP requests for directory listings, individual file downloads, and ZIP archive generation. The constructor accepts parameters to configure the browsing experience:

```java
new DirectoryBrowserSupport(owner, base, title, icon, serveDirIndex)

```

Where `base` is the workspace `FilePath`, and `serveDirIndex` enables HTML directory listings when set to `true`. Users can download the entire workspace as a ZIP archive using the URL pattern `.../ws/*zip*/archive.zip`.

## Workspace Request Handling Pipeline

### Routing via AbstractProject.doWs()

When users navigate to `/job/<jobName>/ws/` or request specific files like `/job/<jobName>/ws/README.md`, Jenkins routes the request to `doWs()` in [`core/src/main/java/hudson/model/AbstractProject.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/model/AbstractProject.java) at line 1907. This method instantiates `DirectoryBrowserSupport` to serve the workspace content securely.

### Workspace Discovery with getSomeWorkspace()

The `getSomeWorkspace()` method at line 547 in [`core/src/main/java/hudson/model/AbstractProject.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/model/AbstractProject.java) iterates through all registered `WorkspaceBrowser` extensions using Jenkins' extension loader. It returns the first non-null `FilePath` found, falling back to the default file-path browser if no custom implementations are registered.

### Security Enforcement and CSP Headers

`DirectoryBrowserSupport` enforces the `Job/Workspace` permission before serving any files, returning a 403 error for unauthorized access as tested in [`test/src/test/java/jenkins/security/ResourceDomainTest.java`](https://github.com/jenkinsci/jenkins/blob/main/test/src/test/java/jenkins/security/ResourceDomainTest.java). The class also manages Content-Security-Policy headers via the `CSP_PROPERTY_NAME` constant, defaulting to `DEFAULT_CSP_VALUE` unless overridden by the `hudson.model.DirectoryBrowserSupport.CSP` system property, with test coverage in [`test/src/test/java/jenkins/security/csp/ContentSecurityPolicyTest.java`](https://github.com/jenkinsci/jenkins/blob/main/test/src/test/java/jenkins/security/csp/ContentSecurityPolicyTest.java).

## Configuration and Security Controls

### Symlink Escape Protection

To prevent directory traversal attacks, `DirectoryBrowserSupport` respects two system properties: `ALLOW_SYMLINK_ESCAPE` and `ALLOW_TMP_DISPLAY`. These control whether Jenkins follows symbolic links pointing outside the workspace directory or to temporary file locations, effectively sandboxing workspace access.

### Customizing Content Security Policy

Administrators can customize or disable CSP headers for workspace browsing by setting the system property:

```bash
java -Dhudson.model.DirectoryBrowserSupport.CSP="default-src 'self'; script-src 'none'" -jar jenkins.war

```

Setting the value to empty disables CSP entirely, though this reduces protection against XSS attacks in workspace HTML files.

## Building Custom Workspace Browsers

Plugins can extend `WorkspaceBrowser` to redirect workspace views to alternative locations or filtered views. The test suite in [`test/src/test/java/hudson/model/ProjectTest.java`](https://github.com/jenkinsci/jenkins/blob/main/test/src/test/java/hudson/model/ProjectTest.java) demonstrates this pattern with the `WorkspaceBrowserImpl` class:

```java
public static class WorkspaceBrowserImpl extends WorkspaceBrowser {
    @Override
    public @CheckForNull FilePath getWorkspace(AbstractProject<?,?> project) {
        // Custom logic: expose only the src subdirectory
        FilePath ws = project.getSomeWorkspace();
        return (ws != null) ? ws.child("src") : null;
    }
}

```

Register the implementation with `@Extension` to enable automatic discovery by `AbstractProject.getSomeWorkspace()`.

## Summary

- **FilePath** abstracts distributed file operations across Jenkins controllers and agents
- **WorkspaceBrowser** provides a pluggable extension point for custom workspace discovery logic
- **DirectoryBrowserSupport** securely serves workspace content via HTTP with permission checks and CSP headers
- The `AbstractProject.doWs()` method at line 1907 and `getSomeWorkspace()` at line 547 orchestrate workspace resolution and serving
- Security controls include `Job/Workspace` permission requirements, symlink escape protection via `ALLOW_SYMLINK_ESCAPE`, and configurable CSP policies

## Frequently Asked Questions

### What is the difference between WorkspaceBrowser and DirectoryBrowserSupport?

**WorkspaceBrowser** is responsible for locating and returning the `FilePath` object representing a job's workspace, while **DirectoryBrowserSupport** handles the HTTP layer, rendering directory listings and serving files. WorkspaceBrowser runs during the resolution phase to find the workspace, whereas DirectoryBrowserSupport manages the actual content delivery and security enforcement.

### How do I restrict access to Jenkins workspaces?

Access control is enforced through the **Job/Workspace** permission in Jenkins' security realm. Users must possess this permission on the specific job to view its workspace via the `/ws/` URL. Administrators can configure this through the Jenkins security matrix or role-based access control plugins, as verified in [`ResourceDomainTest.java`](https://github.com/jenkinsci/jenkins/blob/main/ResourceDomainTest.java).

### Can I customize the Content-Security-Policy for workspace browsing?

Yes. Set the `hudson.model.DirectoryBrowserSupport.CSP` system property to your desired CSP directive string when starting Jenkins. An empty value disables CSP headers entirely, though this is not recommended for production environments due to increased XSS risks from user-generated workspace content.

### How do I implement a custom workspace browser in a Jenkins plugin?

Extend the `WorkspaceBrowser` class from [`core/src/main/java/hudson/model/WorkspaceBrowser.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/model/WorkspaceBrowser.java) and override the `getWorkspace(AbstractProject<?,?> project)` method to return your custom `FilePath`. Annotate your class with `@Extension` to register it with Jenkins' extension system. The first non-null result from all registered browsers will be used when resolving the workspace location.