Install a Local Delegate on macOS
The new Harness Delegate is currently in closed beta and available only to select customers. Access is determined by the product team and is based on current supported use cases and steps.
This guide walks you through installing the Harness Delegate on a macOS machine. For other platforms, see the Linux and Windows installation guides.
To learn more about the new delegate, including architecture, capabilities, and how it compares to the legacy delegate:
- New Delegate Overview — Complete guide to the new delegate
- Feature Parity — Detailed feature comparison
What's Supported
Supported Connectors
| Connector | Caveats |
|---|---|
| Docker Registry | Only the DockerHub provider type |
| Github | All authentication types are supported |
| Bitbucket | All authentication types are supported |
| HashiCorp Vault | Only AppRole and Token Auth; set Renewal Interval to 0 (zero) |
| AWS Secrets Manager | Only Access Key and IAM Role Credential Type |
Supported CI Steps
| Step Name | Caveats |
|---|---|
| Git Clone | Github and Bitbucket |
| Run | |
| Background | |
| Run Tests | |
| Upload to Artifactory | Requires jfrog CLI on host |
| Upload to GCS | |
| Upload to S3 | |
| Upload Artifacts to Harness Artifact Registry | |
| Save Cache to S3 | |
| Save Cache to GCS | |
| Restore Cache from S3 | |
| Restore Cache from GCS |
Quick Reference
| Command | Description |
|---|---|
./delegate install | Install and register the service |
./delegate start | Start the delegate service |
./delegate stop | Stop the service gracefully |
./delegate status | Show delegate status and details |
./delegate uninstall | Uninstall service (preserves config/logs) |
Important file locations:
| Mode | Config File | Logs | Service Definition |
|---|---|---|---|
| LaunchAgent | ~/.harness-delegate/config.env | ~/.harness-delegate/logs/ | ~/Library/LaunchAgents/harness-delegate.plist |
| LaunchDaemon | /opt/harness-delegate/config.env | /opt/harness-delegate/logs/ | /Library/LaunchDaemons/harness-delegate.plist |
Get Harness Credentials
Before installation, obtain your Account ID, Delegate Token, and Harness URL.
- Interactive Guide
- Step-by-Step
-
Open Delegate settings: In the left nav, click Project Settings, then under Project-level Resources, click Delegates.
-
Create a new delegate: Click + New Delegate and choose Docker as your delegate type.
-
Copy the credentials from the
docker runcommand:ACCOUNT_ID→ Your Account IDDELEGATE_TOKEN→ Your Delegate TokenMANAGER_HOST_AND_PORT→ Your Harness URL

Keep these values ready — you'll use them in the installation command.
Download and Install the Delegate
The macOS delegate supports two installation modes:
- LaunchAgent (User Service): Default mode. Runs when you're logged in. Enable auto-login (see Step 5) to ensure it starts after reboots.
- LaunchDaemon (System Service): Available in version 1.34.0+. Runs at system boot without a GUI session. Recommended for EC2 macOS instances or environments where security policies prohibit auto-login.
Step 1: Download the Binary
Replace <VERSION> with the latest version (e.g., 1.34.0).
For arm64 (Apple Silicon):
curl -L "https://app.harness.io/public/shared/delegates/<VERSION>/delegate-darwin-arm64" -o delegate
chmod +x delegate
For amd64 (Intel):
curl -L "https://app.harness.io/public/shared/delegates/<VERSION>/delegate-darwin-amd64" -o delegate
chmod +x delegate
Example using version 1.34.0:
curl -L "https://app.harness.io/public/shared/delegates/1.34.0/delegate-darwin-arm64" -o delegate
Step 2: Install with Credentials
Run the install command with the credentials you obtained from the previous step. Choose the service mode that matches your environment.
Option A: LaunchAgent (User Service) — Default
The delegate runs as a user-level service. It starts when you log in and stops when you log out.
./delegate install --account=[Your Account ID] \
--token=[Your Delegate Token] \
--url=[Your Harness URL] \
--name=[Your Delegate Name]
Option B: LaunchDaemon (System Service) — Version 1.34.0+
The delegate runs as a system-level service that starts at boot without requiring a GUI session. This mode is recommended for EC2 macOS instances and environments where security policies prohibit auto-login.
All LaunchDaemon operations require sudo because the delegate interacts with the system domain (/Library/LaunchDaemons/) instead of the user domain. The --user flag specifies the macOS user account the delegate process runs as.
sudo ./delegate install --account=[Your Account ID] \
--token=[Your Delegate Token] \
--url=[Your Harness URL] \
--name=[Your Delegate Name] \
--mode=system \
--user=[Your macOS Username]
If you don't specify a name, the delegate defaults to harness-delegate.
Optional: Add tags for delegate selection
Tags are useful for routing specific pipelines to this delegate:
./delegate install --account=[Your Account ID] \
--token=[Your Delegate Token] \
--url=[Your Harness URL] \
--name=[Your Delegate Name] \
--tags="production,macos"
For LaunchDaemon mode, add sudo, --mode=system, and --user:
sudo ./delegate install --account=[Your Account ID] \
--token=[Your Delegate Token] \
--url=[Your Harness URL] \
--name=[Your Delegate Name] \
--mode=system \
--user=[Your macOS Username] \
--tags="production,macos"
View all available installation options
./delegate install --help
--account: Your Harness account ID (required)--token: Delegate authentication token (required)--url: Harness server URL (required)--name: Custom delegate name (default:harness-delegate)--tags: Comma-separated tags for delegate selection (optional)--mode: Service mode:systemfor LaunchDaemon, omit for default LaunchAgent (optional, version 1.34.0+)--user: macOS user account the delegate process runs as (required when--mode=system)--env-file: Path to config file (default:~/.harness-delegate/config.env)--graceful-exit-timeout: Shutdown timeout in seconds (default: 300)--auto-restart-on-failure: Auto-restart on failure (default: true)
What this command creates:
LaunchAgent mode:
- Workspace directory:
~/.harness-delegate - Configuration file:
~/.harness-delegate/config.env - Service definition:
~/Library/LaunchAgents/harness-delegate.plist
LaunchDaemon mode:
- Workspace directory:
/opt/harness-delegate - Configuration file:
/opt/harness-delegate/config.env - Service definition:
/Library/LaunchDaemons/harness-delegate.plist
Step 3: Start the Service
For LaunchAgent mode:
./delegate start
For LaunchDaemon mode:
sudo ./delegate start
You should see a success message with the config location and log file path.

Step 4: Verify Installation
Check the delegate status:
./delegate status

View logs in real time:
tail -f ~/.harness-delegate/logs/delegate.log
For LaunchDaemon mode:
tail -f /opt/harness-delegate/logs/delegate.log
Navigate to Project Settings > Delegates in the Harness UI. You should see your delegate with a Connected status.

Step 5: Enable Auto-Login (LaunchAgent Only)
If you installed the delegate as a LaunchDaemon (system service), skip this step. The daemon starts automatically at boot without requiring a user session.
Since the LaunchAgent delegate runs as a user service, enable auto-login to ensure it starts after system reboots:
- Open System Settings (or System Preferences on older macOS).
- Navigate to Users & Groups.
- Click the lock icon and authenticate.
- Select Login Options.
- Set Automatic login to your user account.
Additional Configuration
Update Delegate Settings
For LaunchAgent mode:
- Stop the service:
./delegate stop - Edit the config:
nano ~/.harness-delegate/config.env - Start the service:
./delegate start
For LaunchDaemon mode:
- Stop the service:
sudo ./delegate stop - Edit the config:
sudo nano /opt/harness-delegate/config.env - Start the service:
sudo ./delegate start
Docker Configuration for Container-Based Steps
If you plan to use Docker with container-based CI steps on macOS, configure your Docker runtime settings to avoid permission-related issues. The delegate requires proper filesystem access between your local machine and the Docker VM.
Docker / Rancher Desktop
For optimal compatibility, configure the following settings in your Docker/Rancher Desktop preferences:
-
Filesystem Mount Type: Select reverse-sshfs as your mount type. Go to Preferences > Virtual Machine > Volumes tab and choose reverse-sshfs instead of 9p or virtiofs.
-
Virtual Machine Type: Select QEMU as your emulation type. Go to Preferences > Virtual Machine > Emulation tab and choose QEMU instead of VZ (Apple Virtualization framework).

These settings ensure proper permission mapping between your local filesystem and the Docker VM. Without them, you may encounter "Permission denied" errors when running containerized steps.
Colima
If you are using Colima as your Docker runtime on macOS, start it with the following recommended settings:
colima start --vm-type qemu --mount-type sshfs --cpu 8 --memory 20 --mount ~:w --mount /private/tmp/engine:/private/tmp/engine:w
This ensures the VM uses QEMU emulation and sshfs mounts, which provide the correct filesystem permission mapping needed by the delegate. The --mount ~:w flag grants write access to your home directory, and --mount /private/tmp/engine:/private/tmp/engine:w mounts the engine's temporary directory so the delegate can read output files written by containerized steps.
Unlike Rancher Desktop, which automatically maps system directories into the VM, Colima only mounts your home directory by default. The delegate uses /tmp/engine/ (which resolves to /private/tmp/engine on macOS) to exchange output files between containerized steps and the host. Without this mount, pipelines that export output variables from container-based steps will fail with an error like:
stat /tmp/engine/<hash>-output.env: no such file or directory
If you still encounter this error after adding the mount flag, SSH into the Colima VM and create the directory manually:
colima ssh -- sudo mkdir -p /private/tmp/engine
Proxy Configuration
The delegate inherits system-level proxies by default, but you can set a custom proxy through the delegate config. Edit the delegate's config.env file (see file locations for the path based on your service mode) and add:
PROXY_HOST=3.139.239.136
PROXY_PORT=3128
PROXY_SCHEME=http
PROXY_USER=proxy_user
PROXY_PASSWORD=password
NO_PROXY="localhost,127.0.0.1,.corp.local,10.0.0.0/8"
Alternatively, set environment variables:
export HTTP_PROXY="http://USER:PASSWORD@PROXY_HOST:PORT"
export HTTPS_PROXY="http://USER:PASSWORD@PROXY_HOST:PORT"
export NO_PROXY="localhost,127.0.0.1,.corp.local,10.0.0.0/8"
Manual Plugin Installation
Some CI steps can run directly on the host. Harness automatically downloads required plugins, but manual installation is needed when your infrastructure lacks internet connectivity (e.g., behind a proxy or firewall).
-
Download the plugin from its source (e.g., drone-git v1.7.6).
-
Decompress:
zstd -d plugin-darwin-arm64.zst(orplugin-darwin-amd64.zstfor Intel). -
Move to the plugins directory:
mkdir -p ~/.harness-delegate/default/plugin/drone-git/
mv plugin-darwin-* ~/.harness-delegate/default/plugin/drone-git/
chmod +x ~/.harness-delegate/default/plugin/drone-git/plugin-darwin-*
Manage the Delegate
- Stop:
./delegate stop— Gracefully shuts down (waits up to 5 minutes for tasks to complete). Usesudo ./delegate stopfor LaunchDaemon mode. - Uninstall:
./delegate uninstall— Removes service registration (preserves config, logs, and binary). - Upgrade:
- Download the new binary: Replace the existing
delegatefile. - Stop the delegate:
./delegate stop - Start the delegate:
./delegate start
- Download the new binary: Replace the existing
Configure Pipeline Delegate
For the CI stages that you want to use the new delegate with, define the stage variable HARNESS_CI_INTERNAL_ROUTE_TO_RUNNER and set it to true.
Then, set your pipeline's build infrastructure as usual. Ensure that you have set Local as the Infrastructure and that the Operating System and Architecture match the delegate you installed.
Delegate Configuration
The config.env file location depends on your service mode:
- LaunchAgent (default):
~/.harness-delegate/config.env - LaunchDaemon:
/opt/harness-delegate/config.env - Custom workdir:
{workdir}/config.env
For configuration options that apply across all platforms — including stage capacity limits, graceful shutdown, containerless steps, init scripts, log rotation, metrics, and token management — see the Delegate Configuration Reference.
Configure Custom Working Directory
By default, the delegate stores its configuration files, logs, and cache in a standard location.
Default locations:
- LaunchAgent:
~/.harness-delegate - LaunchDaemon:
/opt/harness-delegate
How to configure:
Use the --workdir flag during installation:
./delegate install --account=[Account ID] \
--token=[Delegate Token] \
--url=[Harness URL] \
--name=[Your Delegate Name] \
--workdir=/custom/path/to/workdir
Or set the HARNESS_WORKDIR environment variable before running the binary directly:
export HARNESS_WORKDIR=/custom/path/to/workdir
./delegate server --env-file config.env
The delegate automatically creates the directory and subdirectories. Ensure the delegate process has read/write permissions for this directory.
Debugging
Logs
You can find the delegate logs in the following locations:
- LaunchAgent (default):
~/.harness-delegate/logs/delegate.log - LaunchDaemon:
/opt/harness-delegate/logs/delegate.log - Custom workdir:
{workdir}/logs/delegate.log
View logs in real time:
LaunchAgent:
tail -f ~/.harness-delegate/logs/delegate.log
LaunchDaemon:
tail -f /opt/harness-delegate/logs/delegate.log
Upgrading the Delegate
There is currently no automated upgrade mechanism for the new delegate. The upgrade process involves stopping the delegate, downloading the latest binary, and starting it again.
- Stop the running delegate.
- Download the latest binary from the installation step, replacing the existing
delegatefile. - Start the delegate.
Troubleshooting
Docker Client Not Initialized
If your Local (Docker) infrastructure stages fail with a "docker client is not initialized" error, the delegate is likely using the wrong Docker socket path. This commonly occurs when using Rancher Desktop as your Docker runtime, where the Docker socket symlink must be recreated after every restart.
Identify the correct Docker socket path for your runtime:
docker context ls
This outputs a table showing each configured Docker context and its socket endpoint:
NAME DESCRIPTION DOCKER ENDPOINT ERROR
default Current DOCKER_HOST based configuration unix:///var/run/docker.sock
desktop-linux Docker Desktop unix:///Users/myUser/.docker/run/docker.sock
rancher-desktop * Rancher Desktop moby context unix:///Users/myUser/.rd/docker.sock
Find the context that matches your active Docker runtime (marked with *), and copy its DOCKER ENDPOINT value. Then add it to config.env:
DOCKER_HOST="unix:///Users/myUser/.rd/docker.sock"
Replace the path with the correct socket endpoint for your setup. Restart the delegate for the change to take effect.
If you're using Rancher Desktop and see this error after restarting it, the Docker socket symlink may need to be recreated:
sudo rm /var/run/docker.sock
sudo ln -s ~/.rd/docker.sock /var/run/docker.sock
Output Variable Errors with Colima
If a pipeline step running inside a container exports an output variable and you see an error like:
stat /tmp/engine/<hash>-output.env: no such file or directory
The delegate writes output .env files to /tmp/engine/ on the host, which resolves to /private/tmp/engine on macOS. Colima only mounts your home directory into the underlying Lima VM by default, so the host cannot read files written by the container to this path.
Restart Colima with an explicit mount for the engine directory:
colima start --vm-type qemu --mount-type sshfs --mount ~:w --mount /private/tmp/engine:/private/tmp/engine:w
If the error persists, the /private directory may not exist inside the Linux VM. Create it manually:
colima ssh -- sudo mkdir -p /private/tmp/engine
For full Colima configuration details, see the Colima section under Additional Configuration.