Skip to content

TAK Update Server

MAGK hosts its own TAK Plugin Update Server so operators can push ATAK core upgrades and plugin APKs to every enrolled EUD directly from the MAGK server, without relying on the Play Store.

What it does

ATAK ships with a built-in "Plugin Update Server" client under Settings → Network Preferences → Plugin Update Server. When pointed at a compatible HTTPS endpoint, ATAK:

  1. HEADs {updateServerUrl}/product.infz on startup and when the user taps Check for updates.
  2. GETs the same URL and parses an XML manifest listing every APK the server is offering (package name, version, SHA-256 hash).
  3. Compares each manifest entry against what is already installed and downloads + installs any newer APKs over mTLS.

The MAGK TAK Update Server implements this protocol using the APKs already checked into the repo at tools/eud-test-harness/apks/.

URL and authentication

https://<DOMAIN>:8443/api/packages

The endpoint lives on port 8443 (mTLS) so only devices holding a valid TAK enrollment certificate can download APKs. There is no unauthenticated path — APK downloads fail with TLS alert 46 ("certificate unknown") if the client cert is missing.

Operators can find the exact URL for a given deployment on the admin UI at /admin/tak-update-server.

How the catalog is built

On each deploy, the GitHub Actions workflow (.github/workflows/magk-staging.yml and the equivalent production file) runs:

python3 scripts/build-tak-update-server.py --copy

This script:

  • Walks tools/eud-test-harness/apks/ for *.apk files.
  • Parses each APK's AndroidManifest via androguard to extract package name, versionName, versionCode, min SDK, and app label.
  • Computes SHA-256 of each APK (streaming; no memory blow-up for large files).
  • Classifies APKs as app (ATAK core, com.atakmap.app.*) or plugin (everything else).
  • Flags unusually large files that may be corrupted.
  • Writes four artifacts into config/tak-update-server/generated/:
    product.inf        — XML manifest (human-readable)
    product.infz       — ZIP archive of product.inf (served to ATAK)
    manifest.json      — JSON manifest (consumed by /admin/tak-update-server)
    apks/              — copies of each .apk served directly
    

Nginx mounts the generated directory read-only at /etc/nginx/tak-packages and serves it at /api/packages/* on port 8443, bypassing the Node backend for large-file transfers so ATAK can resume interrupted downloads via HTTP byte-range requests.

Adding or updating a plugin

  1. Drop the .apk into tools/eud-test-harness/apks/.
  2. Commit the APK (they are tracked in git so they sync to staging).
  3. Push to main. The deploy pipeline rebuilds the manifest and restarts nginx automatically.
  4. On any enrolled EUD, open ATAK → Check for updates. The new plugin appears in the list.

To retire a plugin, remove the APK from the directory and redeploy; the manifest will no longer list it and ATAK will stop offering updates for it.

Admin UI

/admin/tak-update-server shows:

  • Status badge (Ready / Not built) and generation timestamp.
  • Copy-pastable URL for the Plugin Update Server ATAK setting.
  • Build warnings (oversize/corrupted APKs).
  • Full catalog table with package, version, ATAK/Android requirements, file size, and truncated SHA-256.

Troubleshooting

ATAK shows "package search failed" Check nginx logs for 4xx/5xx on /api/packages/product.infz. If the catalog has not been built yet (first deploy), nginx falls back to an empty stub manifest — ATAK will report zero available plugins but will not error. Re-running the CI deploy should resolve this.

Downloads stall at 50–90% ATAK's HTTP client does not always tolerate chunked transfer encoding. Nginx is configured with chunked_transfer_encoding off on the :8443 virtual server; if this was altered, restore it.

Warning badge on a plugin in the admin UI The APK was flagged during the build (typically oversize). Open the row tooltip to see the warning. Replace the APK with a clean download and redeploy.