# SignTools: self-hosted iOS sideloading with a macOS builder

> SignTools splits signing into a Go web service and a macOS builder that drives Apple's own tooling, so an unsigned IPA goes in and an installable one comes back without a computer in the loop after setup. The catch is that you still need a Mac in the loop permanently.

**SignTools/SignTools** — ✒ A free, self-hosted platform to sideload iOS apps without a computer

- Repository: https://github.com/SignTools/SignTools
- Stars: 2,223 · Forks: 275
- Language: Go
- License: AGPL-3.0
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/signtools-signtools

## What SignTools actually removes from the sideloading loop

The problem SignTools targets is specific: signing an unsigned IPA normally means a Mac, Xcode or a signing utility, a cable, and repeated manual steps every time the app changes. SignTools moves that work to a server. The README describes a two-component design, a service and a builder, where the builder is a macOS machine that performs signing using official Apple software, and the service can be hosted anywhere and provides a web interface to upload, sign and download apps. The stated payoff is that nothing is installed on the phone and you can sideload without a computer.

The audience is narrower than the feature list suggests. This is for someone who already has a Mac available as infrastructure (a spare mini, a build machine, a VM on Apple hardware) and wants to hand signing to other people or to a CI job. It is not for a person who owns only an iPhone and a Windows laptop, because the builder requirement does not go away. The README is explicit that a computer is not required after an initial setup, which is a different claim from no computer required at all.

The feature list covers no jailbreak, iOS, iPadOS and macOS targets including native apps and IPAs, upload of unsigned apps and download of signed ones, tweak injection during signing, OTA install from the website to an iOS device, provisioning profiles and developer accounts, configurable entitlements, and a choice of signing profiles per app. Those last two are the parts that separate it from a one-shot signing script: profiles and entitlements are configuration you manage, not flags you retype.

## The service and builder split, and why it costs you a Mac

The architecture is a deliberate trade. Signing happens on macOS with Apple's own software, and the README justifies this as high reliability and compatibility. The service is the piece in this repository, written in Go, and it talks to the builder when signing is needed. Everything else (the upload UI, the OTA pages, profile management) lives in the service.

The dependency list backs that reading. The service is an HTTP application built on Echo, with tusd for resumable uploads, koanf for configuration, zerolog for logging, and go-pkcs12 for certificate handling. Two dependencies are replaced with forks from the SignTools organization: tusd and go-pkcs12. That is worth noticing if you plan to vendor or audit the build, because the fork pins are part of what you are shipping, not incidental.

The cost is operational. You are running two things, not one, and one of them is a Mac that has to stay reachable and signed in to whatever Apple account the profiles belong to. If the builder is asleep, offline, or its credentials expire, the service has nothing to sign with. The README does not describe a fallback path for that case, and it does not document what the service does when the builder is unreachable. Treat builder availability as a hard dependency you monitor yourself.

The Dockerfile builds a static Go binary in one stage and copies it into a minimal Alpine image, exposing port 8080. That covers the service only. There is no Dockerfile for the builder, which is consistent with the builder being a macOS machine rather than a container.

## Building the service image and reaching the web interface

The repository ships a Dockerfile, and the image entrypoint is the SignTools binary with port 8080 exposed. The build compiles with CGO disabled and stripped symbols, then copies the binary into alpine:3.24.1, so the resulting image is small and has no Go toolchain in it.

The Dockerfile itself is the build recipe, and this is the stage that compiles the service:

```dockerfile
FROM golang:1.26.5-alpine AS builder

WORKDIR /src
COPY . .

RUN apk add --no-cache git && \
    go mod download && \
    CGO_ENABLED=0 go build -ldflags="-s -w" -buildvcs=false -o "SignTools"
```

It downloads modules and compiles the service, so the build needs network access to the Go module proxy.

The runtime stage copies the binary into a minimal image and declares the port the service listens on:

```dockerfile
FROM alpine:3.24.1

WORKDIR /

COPY --from=builder "/src/SignTools" "/"

ENTRYPOINT ["/SignTools"]
EXPOSE 8080
```

So the service listens on port 8080, and the web interface is what you open in a browser. Configuration keys, volume mounts for uploaded and signed apps, and the builder connection settings are not in the README; they live in INSTALL.md, which the README links to as the installation guide. Read that file before running anything you intend to keep, because the image as shown here has no persistence configured and no builder attached, which means it can serve the UI but has nothing to sign with.

The intended first real use, per the README, is to upload an unsigned app in the web interface, sign it, download the signed result, and install it on an iOS device over the air from the website. Tweak injection and profile selection are configured as part of that signing step rather than as a separate command.

## Where SignTools is the wrong tool

The builder requirement is the first limitation, and it is structural rather than a missing feature. If you do not have macOS hardware you can leave running, SignTools cannot sign anything. A Linux server plus this image gets you an upload form and no signed output.

The second is that the service is self-hosted and, in the README's words, does not constitute a public service. It offers no catalog of applications and the disclaimer states it does not endorse or support piracy. If what you want is a signing service someone else operates, this is not that, and running it for strangers carries obligations the project explicitly declines to take on.

The third is exposure. OTA install means an iOS device fetches the signed app from your server over HTTP, which means the device has to be able to reach that server, with a certificate that iOS will accept for the install to proceed. A service on localhost or behind a VPN that phones cannot join is useless for the OTA flow even though upload and signing still work.

Finally, the release cadence is uneven. The three most recent releases are v3.0.12 on 2026-07-16, v3.0.11 on 2026-01-07 and v3.0.10 on 2025-06-30. Gaps of roughly six and seven months between releases mean you should not expect fixes to land quickly, and you should pin a version rather than track master. The last push to the repository was on 2026-09-09, so work is happening between releases, but the tagged artifacts are what you can reason about.

## How this differs from script-based signers

The closest alternative in practice is a signing script or CLI that wraps Apple's tools directly on a Mac, run by hand or from CI. The difference is where the state and the interface live. A script takes a path to an IPA and a path to a profile and produces an output file; there is no web interface, no per-app profile selection stored anywhere, and no OTA install page. SignTools keeps profiles, entitlements and apps as service-side state and exposes them through a browser, which is what makes the no-computer workflow possible for the person doing the signing.

That also means the script approach is easier to put in CI and easier to audit, because there is no long-running service and no HTTP surface. The repository does carry a CI topic and a GoReleaser config, so releases are automated, but the README does not document a supported CI signing workflow for your own apps.

A second alternative is a hosted signing service. The trade is the reverse of SignTools in every dimension: no Mac to run, no server to secure, but your IPA and your signing credentials go to someone else's infrastructure, and you depend on their uptime and their terms. SignTools exists precisely because some people will not make that trade.

## Licence, upgrades and what maintenance costs you

SignTools and the unlicensed dependencies under the SignTools organization are licensed under AGPL-3.0, and the README points at the LICENSE file for the copy. The AGPL matters more than usual here because this is a network service: if you run a modified SignTools and let other people interact with it over a network, the licence's source-availability condition is the thing to look at. That is a question for your own counsel, not something to settle from a README, but it is the reason the project notes that you can raise an issue if you are interested in exclusive licensing.

Upgrade cost is low if you stay on tagged releases and rebuild the image, since the service is a single static binary with no database in the dependency list. The real upgrade cost is on the builder side and is not described in the README: Apple tooling, provisioning profiles and developer account state change on their own schedule, independently of SignTools releases. A version bump on the service does not fix an expired profile.

The dependency replaces for tusd and go-pkcs12 mean your build pulls forks maintained by the same organization. That is not a defect, but it does mean an audit of what you deploy has to include those two repositories, and a supply-chain policy that only allows upstream modules will reject this build.

## What to check before you commit to running it

Start with INSTALL.md and FAQ.md. The README delegates installation entirely to INSTALL.md and links a separate FAQ, and neither is reproduced in the README itself, so any statement about configuration keys, builder setup or persistence has to come from those files. The README does not document rollback, backup of uploaded apps, or what happens to in-flight uploads when the service restarts, despite tusd being in the dependency list.

Then decide where the builder lives. It has to be macOS, it has to run Apple's signing software, and it has to be reachable from the service. If you cannot commit to keeping that machine up, the rest of the stack is decoration.

Finally, check the release you intend to run. v3.0.12 is the newest tag, dated 2026-07-16, and it is the version to pin. Building from master gives you whatever landed up to the last push on 2026-09-09, which is untagged and therefore not the thing the project has chosen to ship.

## Conclusion

Adopt SignTools if you already run a macOS machine you can dedicate to signing and you want a browser-based flow for unsigned IPAs, including OTA install straight to a device, without a per-seat service. Do not adopt it if you have no Mac, if you want a hosted service rather than something you operate, or if your users cannot reach your HTTP server. Before committing, read INSTALL.md for the current service and builder steps, confirm the AGPL-3.0 obligations against how you intend to expose the service, and verify that your builder can reach Apple's signing endpoints from wherever you host it.

## FAQ

### How do I install SignTools on Windows 11?

The README points to INSTALL.md for installation and does not describe a Windows path. Signing is performed by a macOS builder, so a Windows machine can host the service but cannot replace the builder.

### Is SignTools free to use?

The README describes it as a free, self-hosted platform, and the project plus its unlicensed dependencies under the SignTools organization are licensed under AGPL-3.0. It is not a public service, so you host it yourself.

### Can SignTools sign an IPA without a Mac?

No. The README states the builder is a macOS machine that performs signing using official Apple software. A computer is not required after the initial setup, but the builder itself is macOS.

### Does SignTools install apps to an iPhone over the air?

Yes, the feature list includes installing signed apps from the website straight to an iOS device via OTA. The device still has to be able to reach your service over the network for that to work.

### What is code signing used for?

The README does not explain code signing in general. It describes SignTools as signing unsigned iOS apps so they can be installed, using provisioning profiles, developer accounts, entitlements and configurable signing profiles.

## Sources

- [Issues](https://github.com/SignTools/SignTools/issues)
- [License: AGPL-3.0](https://github.com/SignTools/SignTools/blob/master/LICENSE)
- [README](https://github.com/SignTools/SignTools/blob/master/README.md)
- [Releases](https://github.com/SignTools/SignTools/releases)
- [SignTools/SignTools on GitHub](https://github.com/SignTools/SignTools)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/signtools-signtools
