# How Jenkins Implements ACL and Authorization Strategies: Security Model Deep Dive

> Understand Jenkins security model ACL and authorization strategies. Learn how Jenkins enables flexible access controls with its two-layer security and support for custom plugins.

- Repository: [Jenkins/jenkins](https://github.com/jenkinsci/jenkins)
- Tags: deep-dive
- Published: 2026-06-19

---

**Jenkins uses a two-layer security model where AuthorizationStrategy supplies the root ACL that evaluates permissions against Authentications, allowing plugins to implement matrix, role-based, or custom access controls without modifying core permission checks.**

The Jenkins security model in the `jenkinsci/jenkins` repository centers on a pluggable architecture that separates policy definition from enforcement. Understanding how Jenkins ACL and authorization strategies interact is essential for securing CI/CD pipelines and developing custom security plugins. This architecture allows administrators to mix authentication realms with authorization strategies while maintaining fine-grained access control over jobs, views, nodes, and configuration.

## Core Components of the Jenkins Security Model

Jenkins security relies on two primary abstractions defined in `hudson.security`: the **AuthorizationStrategy** and the **ACL**. According to the jenkinsci/jenkins source code, these classes work together to determine whether a specific user or system process can perform an action.

### AuthorizationStrategy as the Policy Provider

The `AuthorizationStrategy` abstract class, located in [`core/src/main/java/hudson/security/AuthorizationStrategy.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/security/AuthorizationStrategy.java), serves as the entry point for all access control decisions. It provides the root ACL through the `getRootACL()` method, which all other ACLs ultimately delegate to.

```java
public abstract class AuthorizationStrategy {
    /** Returns the ultimate ACL that all other ACLs delegate to. */
    public abstract @NonNull ACL getRootACL();
}

```

### ACL as the Permission Enforcer

The `ACL` class in [`core/src/main/java/hudson/security/ACL.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/security/ACL.java) implements the actual permission-checking logic. It evaluates `Permission` objects against `Authentication` instances and recognizes three special principals: **SYSTEM2** (the internal system user), **EVERYONE** (matches any principal), and **ANONYMOUS** (the unauthenticated user).

## How the Root ACL Controls Access

When Jenkins starts, it initializes a single `AuthorizationStrategy` implementation—either `FullControlOnceLoggedInAuthorizationStrategy` or the unsecured `AuthorizationStrategy.UNSECURED`. The strategy's `getRootACL()` method returns the ultimate ACL stored in the global `Jenkins` object.

This root ACL has final authority over every permission request in the system. All other ACLs in the hierarchy ultimately delegate to this root instance, making it the central policy enforcement point for the entire Jenkins security model.

## Object-Specific ACLs for Fine-Grained Control

`AuthorizationStrategy` can override specific `getACL(...)` methods to supply custom ACLs for particular model objects. By default, these methods return the root ACL, but plugins can override them to implement per-job or per-view permissions.

```java
public @NonNull ACL getACL(@NonNull Job<?, ?> project) { return getRootACL(); }
public @NonNull ACL getACL(final @NonNull View view) { … }

```

This design enables matrix-based or role-based access control without modifying core permission checks. The **AuthorizationStrategy** determines which ACL applies to each object, while the **ACL** itself performs the actual permission evaluation.

## Permission Checking Mechanics in ACL

Every permission check flows through the `ACL` class. The convenience methods `checkPermission(Permission)`, `hasPermission(Permission)`, and `checkAnyPermission(...)` automatically retrieve the current `Authentication` via `Jenkins.getAuthentication2()` and delegate to `hasPermission2(Authentication, Permission)`.

The core check in `hasPermission2` is abstract, allowing concrete implementations to define their own logic. The built-in `UNSECURED_ACL` uses a lambda that always returns `true`:

```java
private static final ACL UNSECURED_ACL = ACL.lambda2((a, p) -> true);

```

When checking permissions, the system automatically grants access to `SYSTEM2` and evaluates the permission hierarchy through the `impliedBy` chain:

```java
public final void checkPermission(@NonNull Permission p) {
    Authentication a = Jenkins.getAuthentication2();
    if (a.equals(SYSTEM2)) return;                // system user → full access
    if (!hasPermission2(a, p)) {                  // delegate to concrete ACL
        while (!p.enabled && p.impliedBy != null) p = p.impliedBy;
        throw new AccessDeniedException3(a, p);
    }
}

```

## Impersonation and Context Handling

The `ACL` class provides utilities for temporary impersonation through the `as2(Authentication)` method, which creates an `ACLContext` defined in [`core/src/main/java/hudson/security/ACLContext.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/security/ACLContext.java). This pushes a new `Authentication` onto the thread-local `SecurityContextHolder`, allowing plugins to execute code as a different user.

```java
User bob = User.get("bob");
try (ACLContext ctx = ACL.as(bob)) {
    // code executed as bob
    Job<?,?> job = Jenkins.get().getItemByFullName("example", Job.class);
    job.scheduleBuild2(0);   // allowed only if bob has Job/Build permission
}

```

This pattern is essential when build steps need to trigger other jobs or access resources under the identity of the user who initiated the build, rather than the system user.

## Implementing Custom Authorization Strategies

To create a custom security model, extend `AuthorizationStrategy` and override `getRootACL()` to return a custom ACL implementation. Register the strategy with `@Extension` and `@Symbol` for the Jenkins configuration UI.

```java
@Extension @Symbol("simpleMatrix")
public class SimpleMatrixStrategy extends AuthorizationStrategy {
    private final Map<String, Set<String>> userToRoles = new ConcurrentHashMap<>();

    @Override
    public @NonNull ACL getRootACL() {
        return ACL.lambda2((auth, perm) -> {
            // grant everything to SYSTEM
            if (auth.equals(ACL.SYSTEM2)) return true;

            // look up roles assigned to the user name
            Set<String> roles = userToRoles.getOrDefault(auth.getName(), Set.of());
            // evaluate permission against roles (pseudo‑logic)
            return roles.stream().anyMatch(r -> RoleTable.isAllowed(r, perm));
        });
    }
}

```

The minimal implementation demonstrates the unsecured strategy pattern:

```java
public static final class Unsecured extends AuthorizationStrategy implements Serializable {
    @Override
    public @NonNull ACL getRootACL() {
        return UNSECURED_ACL;                // always true
    }
    private static final ACL UNSECURED_ACL = ACL.lambda2((a, p) -> true);
}

```

## Summary

- **AuthorizationStrategy** supplies the root ACL that determines all permission checks in Jenkins, as defined in [`core/src/main/java/hudson/security/AuthorizationStrategy.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/security/AuthorizationStrategy.java).
- **ACL** implements the actual enforcement logic in [`core/src/main/java/hudson/security/ACL.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/security/ACL.java), evaluating permissions against `Authentication` objects with special handling for `SYSTEM2`, `EVERYONE`, and `ANONYMOUS`.
- Object-specific ACLs allow fine-grained control via overridden `getACL()` methods in `AuthorizationStrategy`, enabling per-job or per-view security policies.
- Thread-local impersonation uses `ACL.as2()` and `ACLContext` to temporarily switch security contexts for operations requiring different user identities.
- Custom strategies extend `AuthorizationStrategy` and register via `@Extension` to integrate with Jenkins' pluggable security architecture without core modifications.

## Frequently Asked Questions

### What is the difference between AuthorizationStrategy and ACL in Jenkins?

`AuthorizationStrategy` acts as the policy provider that determines which ACL to use for specific objects, while `ACL` performs the actual permission evaluation against an `Authentication`. The strategy's `getRootACL()` method returns the ultimate decision-maker that all other ACLs delegate to, making it the final authority on every permission request.

### How does Jenkins handle permissions for the internal system user?

The `ACL` class automatically grants all permissions to `SYSTEM2` (accessible via `ACL.SYSTEM2`). In the `checkPermission` method, if the current authentication equals `SYSTEM2`, the check returns immediately without evaluating the permission, ensuring the internal Jenkins system has unrestricted access to all objects.

### Can plugins implement role-based access control without modifying Jenkins core?

Yes. Plugins can extend `AuthorizationStrategy` and override `getRootACL()` or specific `getACL(...)` methods to return custom ACL implementations. By using `ACL.lambda2()` or creating custom `ACL` subclasses, plugins can implement matrix-based, role-based, or external authorization strategies while integrating with the standard permission checking API defined in [`core/src/main/java/hudson/security/ACL.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/security/ACL.java).

### What files define the core Jenkins security interfaces?

The primary interfaces are defined in [`core/src/main/java/hudson/security/AuthorizationStrategy.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/security/AuthorizationStrategy.java) (strategy definition), [`core/src/main/java/hudson/security/ACL.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/security/ACL.java) (permission checking), [`core/src/main/java/hudson/security/ACLContext.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/security/ACLContext.java) (impersonation context), [`core/src/main/java/hudson/security/Permission.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/security/Permission.java) (permission definitions and hierarchy), and [`core/src/main/java/hudson/security/SecurityRealm.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/security/SecurityRealm.java) (authentication resolution).