Skip to content

Repository files navigation

Unity License Activator

CI Go Version Container

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.

Features

  • 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

Quick Start

Docker (recommended)

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>

Go

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

docker compose run --rm activator \
  --email=<your-email> \
  --password=<your-password> \
  --alf=/data/Unity_v2022.3.31f1.alf \
  --totp=<your-base32-totp-secret>

Configuration

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 .

Getting the .alf file

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.

Getting the TOTP secret

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.

Examples

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=JBSWY3DPEHPK3PXP

Subsequent 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-data

Output

All 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.

How It Works

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]
Loading
  1. Navigate to license.unity3d.com/manual; if redirected to login.unity.com, perform the login flow
  2. Fill email and password; if 2FA is prompted, compute the TOTP code (RFC 6238) and submit it
  3. Accept the Terms of Service if prompted
  4. Upload the .alf file; if the server invalidates the session after submit, re-login and retry once
  5. 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.

Security Notes

  • 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.html are 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.

Development

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 locally

CI 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.

Disclaimer

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.

About

Automated Unity personal license activation

Resources

Stars

102 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages