---
updatedAt: 2026-08-04T11:28:05.000Z
agentTools:
  siteIndex: https://docs.jfrog.com/llms.txt
  projectIndex: https://docs.jfrog.com/administration/llms.txt
---

# Getting Started With Workers

<br />

JFrog Workers provide a serverless, event-driven execution environment that allows you to extend the JFrog Platform with custom scripts. Instead of bending your business logic to fit a tool, Workers allow the platform to adapt to your unique needs.

This guide helps you identify how a Worker can solve your operational challenges, choose the right development interface, and build your first Worker. For more information, see [Workers Overview](https://docs.jfrog.com/administration/docs/workers-overview).

## Step 1: Identify the Problem

Before writing code, it is important to identify the specific pain point or gap in your workflow that a Worker can address. For a complete list of supported event types and what they trigger, see [Worker Event Types](/docs/worker-event-types).

Teams often start by creating a simple Worker to solve a specific problem.

* **Cross-Cluster Synchronization:** Capture the upload origin region for asynchronous federation or cross-cluster syncing. Or synchronize entities like projects across the JFrog Platform installation on a schedule.<br />For more information, see [Configure Scheduled Worker](/docs/create-and-manage-workers#configure-scheduled-worker).
* **Automated Metadata Management:** Eliminate manual tagging by using an [After Create Worker](/docs/workers-code-samples#after-create-worker-code-sample) to automatically apply a predefined set of properties to artifacts immediately upon upload. This ensures consistency in metadata and allows for high-speed querying.<br />For more information, see [Configure Event-Driven Workers for Artifactory](/docs/create-and-manage-workers#configure-event-driven-workers-for-artifactory).
* **Operational Governance and Redirection:** Prevent standard users from uploading artifacts directly into shared or production repositories. A [Before Upload Worker](/docs/workers-code-samples#before-upload-worker-code-sample) can intercept unauthorized uploads and redirect them to a quarantine repository for inspection.<br />For more information, see [Configure Event-Driven Workers for Access](/docs/create-and-manage-workers#configure-event-driven-workers-for-access).
* **Gradual Security Policy Adoption:** Roll out new security policies without disrupting developer workflows. You can use Workers in a "dry run mode" to trigger notifications regarding curation and blocking events, alerting teams of potential issues before enforcing active blocking.<br />For more information, see [Configure HTTP-Triggered Worker](/docs/create-and-manage-workers#configure-http-triggered-worker).

## Step 2: Choose Your Development Interface

Once you know what you want to build, choose how to create and manage it. Every method can create **Event-driven**, **HTTP-triggered**, and **Scheduled** Workers. See [Worker Types](/docs/worker-types) and [Create and Manage Workers](/docs/create-and-manage-workers).

* [**JFrog CLI**](/docs/create-and-manage-workers#jfrog-cli) **(Best Practice):** Treat your automation as production code. Version-control scripts, test locally, deploy via CI/CD, and roll out the same Worker to multiple JPDs.
* **[JFrog Platform UI](/docs/create-and-manage-workers#jfrog-platform-ui):** Explore capabilities with an in-browser TypeScript editor, autocompletion, and a testing pane.
* **[REST API](/docs/create-and-manage-workers#rest-api)**, **[MCP Server](/docs/create-and-manage-workers#mcp-server)** (natural-language tasks in an MCP client), and **[Terraform](/docs/create-and-manage-workers#terraform)** are equal alternatives for the same Worker types.

## Step 3: Define the Worker

We will create an event-driven Worker that blocks uploads to JFrog Artifactory if the target path does not match a specific regex pattern. Choose your preferred method below to generate the skeleton code.

#### Using the JFrog CLI (Best Practice)

1. Open your terminal and run the Worker initialization command: `jf worker init`
2. Follow the interactive prompts:
   * Select **Event Driven Worker**.
   * Select the **Before Upload** action.
   * Enter a name for your Worker (for example, `Path_checker`).

This generates a local workspace with a configuration file (`manifest.json`), a skeleton TypeScript file (`worker.ts`), and a local testing file.

#### Using the JFrog Platform UI

1. Log in to the JFrog Platform as an admin
2. Navigate to **Administration > Workers**
3. Click **+ New Worker > New Event Driven Worker**
4. Locate the **Before Upload** event, click **Add**, and select **Start with Skeleton**.

## Step 4: Write the Action

The Worker service requires you to export an anonymous default function containing your custom logic. The script below intercepts an upload request and blocks it if the target path does not match a specific folder structure ending in `.jar` or `.war`.

This function accepts two essential parameters:

* `context`**:** Your Worker's built-in toolbox. It provides utility functions and HTTP clients to securely interact with other JFrog Platform services.
* `data`**:** The JSON payload detailing the specific trigger event. For a `Before Upload` event, this includes the target repository and file path. You will modify a simulated version of this payload when testing.

In the TypeScript editor, replace the skeleton code with the following script:

```ts
export default async (context: PlatformContext, data: BeforeUploadRequest): Promise<BeforeUploadResponse> => {
  // This RegExp will match all repopaths that start with 'org/company/' and end with the extension .jar OR .war
  const authorizedPathRegEx = /^org\/company\/(?:\w+.\/)+[\w\-\.]+\.(?:jar|war)$/;
  let status: UploadStatus = UploadStatus.UPLOAD_UNSPECIFIED;
  let message = "";

  try {
    if (authorizedPathRegEx.exec(data.metadata.repoPath.path)) {
      status = UploadStatus.UPLOAD_PROCEED;
      message = `RepoPath '${data.metadata.repoPath.path}' is acceptable for the repository '${data.metadata.repoPath.key}'`;
    } else {
      status = UploadStatus.UPLOAD_STOP;
      message = `RepoPath '${data.metadata.repoPath.path}' does not match the regex ${authorizedPathRegEx} for the repository '${data.metadata.repoPath.key}'`;
    }
  } catch(error) {
    status = UploadStatus.UPLOAD_WARN;
    console.error(`could not check the path: ${error}`);
    message = `An error occurred during the check. Proceed with warning.`;
  }

  return {
    status,
    message,
    modifiedRepoPath: data.metadata.repoPath
  }
}
```

## Step 5: Test and Enable the Worker

Always test your Worker before enabling it for live traffic.

#### Using the JFrog CLI (Best Practice)

1. Open the generated testing file (for example, `worker.spec.ts`) in your workspace.
2. Replace the content of the file with:
   ```
   import { PlatformContext } from 'jfrog-workers';
   import { BeforeUploadRequest, UploadStatus } from './types';
   import { createMock, DeepMocked } from '@golevelup/ts-jest';
   import runWorker from './worker';

   describe("Path_checker tests", () => {
       let context: DeepMocked<PlatformContext>;

       beforeAll(() => {
           context = createMock<PlatformContext>();
       })

       it.each([
           {
               testCase: 'should accept uploading a jar file',
               path: 'org/company/folder/file.jar',
               expectedUploadStatus: UploadStatus.UPLOAD_PROCEED,
           },
           {
               testCase: 'should accept uploading a war file',
               path: 'org/company/folder/file.war',
               expectedUploadStatus: UploadStatus.UPLOAD_PROCEED,
           },
           {
               testCase: 'files in nested folder should be accepted',
               path: 'org/company/nested/folder/file.war',
               expectedUploadStatus: UploadStatus.UPLOAD_PROCEED,
           },
           {
               testCase: 'should deny uploading a non-jar and non-war file',
               path: 'org/company/folder/file.pdf',
               expectedUploadStatus: UploadStatus.UPLOAD_STOP,
           },
           {
               testCase: 'hould deny uploading a jar file that does not start with org/company',
               path: 'org/otherCompany/folder/file.jar',
               expectedUploadStatus: UploadStatus.UPLOAD_STOP,
           },
           {
               testCase: 'hould deny uploading a war file that does not start with org/company',
               path: 'org/otherCompany/folder/file.war',
               expectedUploadStatus: UploadStatus.UPLOAD_STOP,
           },
           {
               testCase: 'should deny uploading a file that is not in a folder',
               path: 'org/company/file.jar',
               expectedUploadStatus: UploadStatus.UPLOAD_STOP,
           }
       ])('$testCase', async ({path, expectedUploadStatus}) => {
           const request: DeepMocked<BeforeUploadRequest> = createMock<BeforeUploadRequest>({
               metadata: {
                   repoPath: {
                       path,
                   }
               }
           });
           await expect(runWorker(context, request)).resolves.toEqual(expect.objectContaining({
               status: expectedUploadStatus,
               modifiedRepoPath: { path },
           }))
       })

       it('should let pass the upload with warning in case of ', async () => {
           const request: DeepMocked<BeforeUploadRequest> = createMock<BeforeUploadRequest>({
               metadata: {},
           });
           await expect(runWorker(context, request)).resolves.toEqual(expect.objectContaining({
               status: UploadStatus.UPLOAD_WARN,
               modifiedRepoPath: undefined,
           }))
       })
   });
   ```
3. Open your terminal in the workspace directory and run your local tests to verify the logic: `npm install` `npm test`
4. Once the tests pass, open the `manifest.json` file. Under the `repositories` array, add the key of the repository you want to monitor (for example, `"maven"`), and ensure the `enabled` property is set to `true`.
5. Deploy and activate your Worker using the CLI: `jf worker deploy`

#### Using the JFrog Platform UI

Before enabling the Worker for live traffic, test it to ensure it behaves as expected.

1. In the Testing pane, modify the `path` property in the data structure to simulate an allowed upload request: `"path": "org/company/package1/subPackage/webapp.war"`.
2. Click **Run**. The Execution Results pane will display a success status (`1`), indicating the upload would proceed.
3. Do the same with `"path": "org/company/package1/subPackage/webapp.pdf"`. The Execution Results pane will display a status (`2`), indicating the upload would be rejected.
4. Enter a name for your Worker in the Name field. For example, enter `Path_checker`.
5. Click the **Settings (⚙️)** icon
6. Next to Repositories, click the **+** icon, select the repository you want this Worker to monitor, and click **OK**.
7. Select the **Enable Worker** checkbox to activate it, then click **Save**.

Your Worker is now actively monitoring the selected repository and will block any uploads that do not comply with your organization's pathing rules.