@appcompliance/cli
v2.2.1
Published
AppCompliance CLI for analyzing mobile apps against Apple App Store and Google Play guidelines, App Store Connect and Google Play Console requirements, security requirements, and privacy rules. Run deterministic binary and source code analysis directly fr
Maintainers
Readme
@appcompliance/cli
Command-line interface for AppCompliance — scan mobile app binaries (.apk, .ipa, .aab) for compliance, security, and privacy issues from your terminal or CI/CD pipeline.
Installation
npm install -g @appcompliance/cliAuthentication
The CLI authenticates with a Bearer API token. Create one in the dashboard under Settings → API Tokens.
Set it as an environment variable (recommended for CI/CD):
export APPCOMPLIANCE_API_TOKEN="your-api-token"
# optional: override the API origin (origin only — /api/v1 is appended automatically)
export APPCOMPLIANCE_API_URL="https://app.appcompliance.io"Or store it locally (validated against the API before saving, then written to a 0600 credentials file):
# pass the token explicitly…
appcompliance auth login --token your-api-token
# …or pipe it from stdin
echo "your-api-token" | appcompliance auth loginThere is no email/password or browser login.
Commands
Scan
Submit a binary for scanning. By default this blocks until the scan completes and exits with a gate-aware exit code. Pass --no-wait to submit only.
# submit, wait, and fail the build on any high-or-worse finding (default behavior)
appcompliance scan ./app-release.apk --fail-on high
# submit only; print the scan id and exit 0
appcompliance scan ./app-release.apk --no-wait
# scan_7kqpvn
# write a SARIF artifact for code scanning
appcompliance scan ./MyApp.ipa --format sarif --output results.sarifKey flags: --no-wait, --fail-on <critical|high|medium|low> (default high), --format <table|json|sarif>, --output <file>, --sarif <file>, --json <file>, --platform <ios|android>, --app-id <id>, --declared-toolchain <name>, --timeout <seconds>, --ignore-server-decision.
Declaring what a build is for
Every build you upload is recorded as a build artifact (identified by its
digest), and repeated uploads of the same file are one artifact with several
analyses. You can tell AppCompliance what a build was for. Nothing is guessed:
a branch called main, a workflow called release, a schedule trigger or a
release-signed binary never make a build a release candidate — only this does.
appcompliance scan ./MyApp.ipa --usage-intent release_candidate| Flag | Env var | Description |
|---|---|---|
| --usage-intent <intent> | APPCOMPLIANCE_USAGE_INTENT | development | testing | internal_distribution | release_candidate. Omitted → unknown, which is fully analysable and creates no release. |
| --source-provider <name> | APPCOMPLIANCE_SOURCE_PROVIDER | Declared CI provider, e.g. github-action. |
| --source-run-id <id> | APPCOMPLIANCE_SOURCE_RUN_ID | Declared CI run id. |
| --source-run-url <url> | APPCOMPLIANCE_SOURCE_RUN_URL | Declared CI run URL. |
| --source-workflow <name> | APPCOMPLIANCE_SOURCE_WORKFLOW | Declared workflow / pipeline name. |
| --source-branch <name> | APPCOMPLIANCE_SOURCE_BRANCH | Declared branch. |
| --source-commit <sha> | APPCOMPLIANCE_SOURCE_COMMIT | Declared commit. |
| --source-trigger <trigger> | APPCOMPLIANCE_SOURCE_TRIGGER | manual | pull_request | push | schedule | other. |
| --source-build-profile <name> | APPCOMPLIANCE_SOURCE_BUILD_PROFILE | Declared build profile (e.g. an EAS profile name). |
| --source-version-name <version> | APPCOMPLIANCE_SOURCE_VERSION_NAME | The version your pipeline thinks it built. Only ever compared to the binary. |
| --source-build <build> | APPCOMPLIANCE_SOURCE_BUILD | The build number your pipeline thinks it built. Same rule. |
The flag wins over the env var. The env vars exist so a CI template can export
them instead of interpolating values into a shell command that holds your token.
An unknown value for --usage-intent or --source-trigger is exit 4 rather
than a silently dropped declaration.
All of --source-* is recorded as your claim (origin: client_declared) and
shown that way — a provider name in a request is not a verified provider.
What a release candidate does, and does not do. With
--usage-intent release_candidate, the server creates or joins the release for
the (platform, version, build) it read out of the binary — provided you
hold the release permission and the token carries release:write. It never pins
the analysis a release stands on; that stays an explicit, audited action in the
dashboard or via the API. Anything else — no permission, an archived app, an
incomplete or contradicted identity — is refused, the refusal and its reason are
printed on stderr, and your analysis runs regardless. A refusal never costs
you the scan and never fails the build.
Scan status / wait
appcompliance scan status scan_7kqpvn
appcompliance scan wait scan_7kqpvn --timeout 900 --fail-on highCompare
Compare two scans (Starter plan or higher — a plan without scan comparison returns HTTP 402 → exit 5):
appcompliance compare --base scan_7kqpvn --head scan_9mxzlwUsage
Show your plan tier, quota limits, max upload size, and current usage (an unlimited quota renders as unlimited):
appcompliance usageWorks with any valid token. The Users, Retention and OTP credits rows also
need the workspace:read ability — without it the command still reports the tier,
quotas and max upload size, and notes on stderr which rows are hidden and why.
Auth
appcompliance auth login # store an API token (via --token or stdin)
appcompliance auth whoami # show the identity, token abilities, and expiryConfig
Only api_url is stored here (API tokens live in the separate 0600 credentials
file written by auth login). Setting any other key is rejected.
appcompliance config set api_url https://app.appcompliance.io
appcompliance config get api_url
appcompliance config list
appcompliance config unset api_urlGlobal options
These apply to every command:
| Flag | Env var | Description |
|---|---|---|
| --token <token> | APPCOMPLIANCE_API_TOKEN | API token (prefer the env var in CI). |
| --api-url <url> | APPCOMPLIANCE_API_URL | API origin (origin only; /api/v1 is appended). |
| --allow-host <host> | APPCOMPLIANCE_ALLOW_HOST | Allow sending credentials to a non-default host (comma-separated). Required for a self-hosted / non-app.appcompliance.io origin — otherwise the CLI refuses to send the token to it. |
| --http-timeout <seconds> | APPCOMPLIANCE_HTTP_TIMEOUT | Per-request HTTP timeout in seconds (default 300). Raise it for a large upload on a slow link. This is not --timeout, which caps how long --wait polls for the result. |
| -f, --format <format> | — | Output format: table | json | sarif. |
| -q, --quiet | — | Suppress progress output on stderr. |
Self-hosted / custom host. Point the CLI at your own origin and opt that host in so the token can be sent to it:
appcompliance config set api_url https://appcompliance.internal.example.com
appcompliance --allow-host appcompliance.internal.example.com usage
# or: export APPCOMPLIANCE_ALLOW_HOST=appcompliance.internal.example.comExit Codes
| Code | Meaning |
|---|---|
| 0 | Scan passed — no findings at or above --fail-on. |
| 1 | Scan completed with findings at or above --fail-on (or a server BLOCK). |
| 2 | Scan failed (upload error, analysis error, timeout, network/IO error). |
| 3 | Authentication error. |
| 4 | Invalid arguments, configuration, or local input. |
| 5 | Feature requires a higher plan (HTTP 402 upgrade_required). |
Environment Variables
| Variable | Required | Description |
|---|---|---|
| APPCOMPLIANCE_API_TOKEN | Yes | API authentication token. |
| APPCOMPLIANCE_TOKEN | No | Deprecated alias for APPCOMPLIANCE_API_TOKEN (accepted with a warning). |
| APPCOMPLIANCE_API_URL | No | API base URL — origin only; /api/v1 is appended automatically. Defaults to https://app.appcompliance.io. |
| APPCOMPLIANCE_ALLOW_HOST | No | Comma-separated hosts allowed to receive credentials besides the default host and localhost (same as --allow-host). Needed for a self-hosted origin. |
| APPCOMPLIANCE_HTTP_TIMEOUT | No | Per-request HTTP timeout in seconds (same as --http-timeout). Defaults to 300. |
| APPCOMPLIANCE_USAGE_INTENT | No | What the build is for (same as --usage-intent). See Declaring what a build is for. |
| APPCOMPLIANCE_SOURCE_* | No | The declared build context (PROVIDER, RUN_ID, RUN_URL, WORKFLOW, BRANCH, COMMIT, TRIGGER, BUILD_PROFILE, VERSION_NAME, BUILD) — same as the matching --source-* flags. |
License
MIT
