Automated Unity personal license activation for headless and CI environments.
Drives the official Unity manual activation flow
with playwright-go and headless Chromium:
uploads your .alf license request, handles login and 2FA, and downloads the resulting .ulf license file.
- Fully unattended — email/password login, TOTP-based 2FA (RFC 6238), ToS acceptance, and session-expiry retry are all handled automatically
- Fast — ~34s cold start, ~18s with session reuse (
--data-dir) - CI-friendly — configurable via flags or environment variables; non-zero exit code on failure
- Debuggable — full-page screenshot and HTML dump on failure
- Small footprint — distroless Docker image with pre-installed Chromium, no Go toolchain required
docker run --rm -v ./Unity_v2022.3.31f1.alf:/data/license.alf:ro \
ghcr.io/whileloop99/unity-license-activator:latest \
--email=<your-email> \
--password=<your-password> \
--alf=/data/license.alf \
--totp=<your-base32-totp-secret>Requires Go 1.22+.
GOPROXY=direct go run github.com/whileloop99/unity-license-activator@latest \
--email=<your-email> \
--password=<your-password> \
--alf=<path-to.alf> \
--totp=<your-base32-totp-secret>Playwright downloads Chromium automatically on first run.
docker compose run --rm activator \
--email=<your-email> \
--password=<your-password> \
--alf=/data/Unity_v2022.3.31f1.alf \
--totp=<your-base32-totp-secret>Every flag has an environment variable equivalent. Flags take precedence over environment variables.
| Flag | Env Variable | Required | Default | Description |
|---|---|---|---|---|
--email |
UNITY_EMAIL |
yes | Unity ID email | |
--password |
UNITY_PASSWORD |
yes | Unity ID password | |
--alf |
UNITY_ALF |
yes | Path to .alf license request file |
|
--totp |
UNITY_TOTP |
if 2FA on | Base32 TOTP secret | |
--ulf-name |
UNITY_ULF_NAME |
no | unity.ulf |
ULF output filename |
--output |
UNITY_OUTPUT |
no | .output |
Output directory for ULF and error dumps |
--data-dir |
UNITY_DATA_DIR |
no | Persistent Chrome profile dir (enables session reuse) | |
--skip-install |
UNITY_SKIP_INSTALL |
no | false |
Skip browser download (browser pre-installed) |
--verbose |
UNITY_VERBOSE |
no | false |
Verbose debug logging |
Using environment variables (recommended for CI — keeps secrets out of the process list):
export UNITY_EMAIL="user@example.com"
export UNITY_PASSWORD="secret"
export UNITY_ALF="./Unity_v2022.3.31f1.alf"
export UNITY_TOTP="JBSWY3DPEHPK3PXP"
go run .Generate a license request file with the Unity editor in batch mode:
Unity -batchmode -createManualActivationFile -logfile -This writes Unity_v<version>.alf to the current directory.
If your Unity ID has two-factor authentication enabled, pass the base32 secret
(shown when setting up the authenticator app, e.g. JBSWY3DPEHPK3PXP) via --totp.
The tool computes the 6-digit code itself — no authenticator app needed at runtime.
First run (login + 2FA + download, ~34s):
GOPROXY=direct go run github.com/whileloop99/unity-license-activator@latest \
--email=user@example.com \
--password=secret \
--alf=./Unity_v2022.3.31f1.alf \
--totp=JBSWY3DPEHPK3PXPSubsequent runs (session reuse via persistent profile, ~18s):
GOPROXY=direct go run github.com/whileloop99/unity-license-activator@latest \
--email=user@example.com \
--password=secret \
--alf=./Unity_v2022.3.31f1.alf \
--totp=JBSWY3DPEHPK3PXP \
--data-dir=.chrome-dataAll generated files are written to the --output directory (default .output):
| File | Content |
|---|---|
{ulf-name} |
Downloaded license file (default: unity.ulf) |
error.png |
Full-page screenshot on failure |
error.html |
Page HTML on failure |
The process exits 0 on success and non-zero on any failure, so it can gate CI steps directly.
flowchart LR
nav[Open license page] --> login{Logged in?}
login -- no --> creds[Email + password] --> tfa{2FA?}
tfa -- yes --> totp[Compute TOTP, submit] --> tos
tfa -- no --> tos[Accept ToS if prompted]
login -- yes --> tos
tos --> upload[Upload .alf]
upload -- session expired --> creds
upload --> select[Select personal license] --> dl[Download .ulf]
- Navigate to
license.unity3d.com/manual; if redirected tologin.unity.com, perform the login flow - Fill email and password; if 2FA is prompted, compute the TOTP code (RFC 6238) and submit it
- Accept the Terms of Service if prompted
- Upload the
.alffile; if the server invalidates the session after submit, re-login and retry once - Select the personal license option, submit, and download the
.ulf
With --data-dir, the Chrome profile (including session cookies) persists between runs,
so subsequent runs skip the login flow entirely.
- Prefer environment variables over flags in shared environments — command-line arguments are visible in the process list and shell history.
- Treat the output directory as sensitive.
error.png/error.htmlare dumps of the live page at crash time and may contain your email address or session details. Do not share or commit it (.output/is git-ignored by default). - The TOTP code is never printed to logs.
go test ./... # unit tests (incl. RFC 6238 test vectors)
go vet ./... # static analysis
gofmt -l . # formatting check
go build . # build binary
docker build -t unity-license-activator . # build the image locallyCI runs formatting, vet, and tests on every push and pull request; images are
built, pushed to ghcr.io,
and signed with cosign on main and version tags.
This tool automates the Unity ID login and manual license activation flow. Use it only with your own account and at your own risk — automated access may be subject to the Unity Terms of Service. It is not affiliated with or endorsed by Unity Technologies.