# How to Set Up and Use the ipswd Daemon for Remote REST API Operations

> Learn to set up and use the ipswd daemon to transform the ipsw tool into a RESTful HTTP service for remote firmware analysis operations via HTTP or Unix domain sockets.

- Repository: [blacktop/ipsw](https://github.com/blacktop/ipsw)
- Tags: how-to-guide
- Published: 2026-02-26

---

**The ipswd daemon transforms the ipsw command-line tool into a lightweight RESTful HTTP service, enabling remote machines and CI pipelines to execute firmware analysis operations over HTTP or Unix domain sockets.**

The **ipswd** daemon is part of the [blacktop/ipsw](https://github.com/blacktop/ipsw) open-source project, providing a server mode that exposes core `ipsw` functionality through a structured REST API. By running the daemon, you can offload IPSW scanning, symbolication, and AEA lookup tasks to a dedicated service, allowing distributed systems to interact with Apple firmware data without local command-line installation.

## Architecture of the ipswd Daemon

Understanding the daemon's internal structure helps troubleshoot configuration issues and extend functionality.

### Command Entry Point

The binary entry point resides in [`cmd/ipswd/main.go`](https://github.com/blacktop/ipsw/blob/main/cmd/ipswd/main.go), which simply invokes `cmd.Execute()` to register the CLI command tree.

```go
// cmd/ipswd/main.go
cmd.Execute()

```

This lightweight main function delegates all operational logic to subcommands, following standard Go CLI patterns.

### Start Command Implementation

The `start` subcommand creates the daemon instance and initiates the server. In [`cmd/ipswd/cmd/start.go`](https://github.com/blacktop/ipsw/blob/main/cmd/ipswd/cmd/start.go), the `RunE` function instantiates the daemon and calls its `Start()` method:

```go
// cmd/ipswd/cmd/start.go
daemon := daemon.NewDaemon()
daemon.Start()

```

This sequence triggers the full initialization chain: configuration loading, database setup, and HTTP server creation.

### Daemon Core Orchestration

The [`internal/daemon/daemon.go`](https://github.com/blacktop/ipsw/blob/main/internal/daemon/daemon.go) file contains the primary orchestration logic, wiring together three critical components:

1. **Configuration** – Loaded from `~/.config/ipsw/config.yml` (or a custom path via `--config`)
2. **Database layer** – Initialized through `setupDB()`, supporting SQLite, PostgreSQL, or in-memory storage
3. **HTTP server** – Constructed by [`api/server/server.go`](https://github.com/blacktop/ipsw/blob/main/api/server/server.go)

The `Start()` method coordinates these dependencies, ensuring the database connection is established before the server begins accepting requests.

### Server Configuration

The HTTP server configuration is defined in [`api/server/server.go`](https://github.com/blacktop/ipsw/blob/main/api/server/server.go) through a struct that specifies:

- **Host and port** (default `127.0.0.1:3993`)
- **Unix socket path** (optional alternative to TCP)
- **Debug mode** flag
- **Log file** destination
- **PEM database** path for AEA operations
- **Kernel symbol signatures** directory

### API Routing Structure

Routes are registered under the `/v1` prefix, with specific handlers located in `api/server/routes/`. Key endpoints include:

- `/v1/syms/scan` – Kernel symbol scanning
- `/v1/aea/*` – AEA lookup operations
- `/v1/version` – Server version information

## Configuration and Setup

Proper configuration ensures the daemon listens on the correct interface and maintains persistent data where required.

### Configuration File Location

The daemon searches for [`config.yml`](https://github.com/blacktop/ipsw/blob/main/config.yml) in `~/.config/ipsw/` by default. You can override this with the `--config` flag. The repository provides a reference template in [`config.example.yml`](https://github.com/blacktop/ipsw/blob/main/config.example.yml):

```yaml
daemon:
  host: 127.0.0.1
  port: 3993
  debug: false
  log_file: /var/log/ipswd.log

```

Copy this template to the config directory and modify values to match your deployment environment.

### Database Options

The `setupDB()` function in [`daemon.go`](https://github.com/blacktop/ipsw/blob/main/daemon.go) supports three storage backends:

- **SQLite** – File-based storage suitable for single-node deployments
- **PostgreSQL** – Network database for high-availability setups
- **In-memory** – Volatile storage for testing or ephemeral workloads

Configure the driver in [`config.yml`](https://github.com/blacktop/ipsw/blob/main/config.yml) under the database section. If omitted, the daemon may initialize an SQLite file automatically in the config directory.

## Starting and Managing the Daemon

Once configured, launch the service using the CLI.

### Starting the Service

Execute the `start` command to initialize the daemon:

```bash
ipswd start

```

This command reads the configuration, establishes database connections, and binds the HTTP server to the configured address.

### Checking Daemon Status

Verify the service is operational by querying the version endpoint:

```bash
curl http://localhost:3993/v1/version

```

Alternatively, use the built-in status command:

```bash
ipswd status

```

## Using the REST API

With the daemon running, clients can execute `ipsw` operations via HTTP requests.

### Scanning IPSW Files

To scan an IPSW file for kernel symbols remotely, send a POST request to the scan endpoint:

```bash
http POST http://localhost:3993/v1/syms/scan path=./iPhone15_2.ipsw

```

The daemon processes the file using the same logic as the local `ipsw syms scan` command, returning JSON data containing discovered kernels, build numbers, and firmware keys.

### Unix Socket Communication

For local inter-process communication without TCP overhead, configure a Unix socket in [`config.yml`](https://github.com/blacktop/ipsw/blob/main/config.yml):

```yaml
daemon:
  socket: /tmp/ipsw.sock
  debug: true

```

After restarting the daemon, communicate through the socket using tools like `socat` or custom clients. The server detects the non-empty `socket` field and switches from TCP to Unix domain socket mode automatically.

### Programmatic API Example

Fetch version information programmatically using `curl` and `jq`:

```bash
curl -s http://localhost:3993/v1/version | jq .

```

Expected response:

```json
{
  "api_version": "v1.0",
  "os_type": "linux",
  "builder_version": "0.5.2"
}

```

## Summary

- The **ipswd** daemon exposes `ipsw` CLI functionality through HTTP endpoints defined in `api/server/routes/`
- Configuration resides in `~/.config/ipsw/config.yml` and supports both TCP and Unix socket listeners
- The daemon supports SQLite, PostgreSQL, and in-memory databases via `setupDB()` in [`internal/daemon/daemon.go`](https://github.com/blacktop/ipsw/blob/main/internal/daemon/daemon.go)
- Default service address is `127.0.0.1:3993`, with all routes prefixed by `/v1`
- Remote operations mirror local commands, enabling CI pipelines to execute firmware analysis without local tool installation

## Frequently Asked Questions

### What is the default listening address for ipswd?

By default, the daemon binds to `127.0.0.1:3993` as defined in the server configuration struct within [`api/server/server.go`](https://github.com/blacktop/ipsw/blob/main/api/server/server.go). You can override this by specifying `host` and `port` values in your [`config.yml`](https://github.com/blacktop/ipsw/blob/main/config.yml) or by setting the `socket` parameter to use Unix domain sockets instead.

### How do I run ipswd with a Unix socket instead of TCP?

Set the `socket` field in your configuration file to a valid filesystem path, such as `/tmp/ipsw.sock`. When `daemon.Start()` detects a non-empty socket value, it creates a Unix domain socket listener rather than a TCP socket, eliminating network overhead for local clients.

### Which database backends does ipswd support?

The daemon supports three storage options through the `setupDB()` function: **SQLite** for file-based persistence, **PostgreSQL** for enterprise deployments requiring concurrent access, and **in-memory** storage for testing environments. Configure your preferred driver in the database section of [`config.yml`](https://github.com/blacktop/ipsw/blob/main/config.yml).

### How do I verify the daemon is running correctly?

Query the health check endpoint using `curl http://localhost:3993/v1/version` or execute `ipswd status` from the command line. A successful response returns JSON containing the API version and builder version, confirming that the daemon initialized correctly in [`internal/daemon/daemon.go`](https://github.com/blacktop/ipsw/blob/main/internal/daemon/daemon.go) and is actively serving requests.