Upload + scan + comment, end to end.
PCI-DSS, OWASP MASVS, HIPAA, GDPR mapping in every result.
Configurable severity gate — fail the build before merge.
Sign in at appaudix.com/Profile. Pick the Enterprise plan (API access is part of Enterprise — Free, Pro, and Team are dashboard-only). Click Generate API key, copy the sk_live_* value once — it's only shown then.
In GitHub: Settings → Secrets and variables → Actions → New repository secret. Name it APPAUDIX_API_KEY. Paste the key, save.
Add a file at .github/workflows/mobile-security.yml with the snippet below.
The workflow builds your app, posts it to the appaudix Scan API, polls for completion, and writes a single comment on the PR with the severity table. Subsequent runs update the same comment in place.
Copy, paste, replace the build step with your existing build.
name: Mobile Security
on:
pull_request:
paths: ['app/**', 'android/**']
permissions:
contents: read
pull-requests: write # so the action can post (or update) a PR comment
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build APK
run: ./gradlew assembleRelease
- name: appaudix Security Scan
uses: appaudix/scan-action@v2
with:
api_key: ${{ secrets.APPAUDIX_API_KEY }}
app_path: app/build/outputs/apk/release/app-release.apk
fail_on_severity: critical
name: iOS Security
on:
pull_request:
paths: ['ios/**']
permissions:
contents: read
pull-requests: write
jobs:
scan:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Build IPA
run: xcodebuild -workspace MyApp.xcworkspace -scheme MyApp \
-configuration Release -archivePath ./build/MyApp.xcarchive archive
- name: Export IPA
run: xcodebuild -exportArchive -archivePath ./build/MyApp.xcarchive \
-exportOptionsPlist ExportOptions.plist \
-exportPath ./build
- name: appaudix Security Scan
uses: appaudix/scan-action@v2
with:
api_key: ${{ secrets.APPAUDIX_API_KEY }}
app_path: ./build/MyApp.ipa
fail_on_severity: high
Every run exposes outputs you can wire into downstream steps — Slack notifications, Jira tickets, custom reporting, anything you build with GitHub Actions.
| Output | Description |
|---|---|
| scan_id | The scan ID returned by POST /v1/scans. |
| status | `completed`, `failed`, or `timeout`. |
| passed | `true` / `false` based on `fail_on_severity`. Use it to gate other steps. |
| risk_level | `low` / `medium` / `high` / `critical`. |
| compliance_score | Numeric (0–100). 0 = severe findings, 100 = clean. |
| critical_count / high_count / medium_count / low_count | Findings per severity bucket. |
| report_url | Full HTML report. Add `.pdf` or `.json` to the URL for other formats. |
- name: appaudix Security Scan
uses: appaudix/scan-action@v2
with:
api_key: ${{ secrets.APPAUDIX_API_KEY }}
app_path: app/build/outputs/apk/release/app-release.apk
fail_on_severity: critical
- name: Post to Slack on failure
if: steps.scan.outputs.passed == 'false'
run: |
curl -X POST ${{ secrets.SLACK_WEBHOOK }} -d @- <<EOF
{"text": "🚨 Mobile scan failed on ${{ github.head_ref }}",
"blocks": [{"type": "section", "text": {"type": "mrkdwn",
"text": "Risk: ${{ steps.scan.outputs.risk_level }}\nReport: ${{ steps.scan.outputs.report_url }}"}}]}
EOF
If you'd rather skip the GitHub Action and call the API directly from your own pipeline, pass a callback_url when you submit the scan. appaudix POSTs a signed JSON payload to that URL when the scan completes — no need to poll status.
curl -X POST https://api.appaudix.com/v1/scans \
-H "Authorization: Bearer $APPAUDIX_API_KEY" \
-F "file=@app.apk" \
-F "platform=android" \
-F "callback_url=https://your-ci.example.com/hooks/appaudix" \
-F "fail_on_severity=critical" \
-F 'metadata={"commit":"$GITHUB_SHA","pr":"$PR_NUMBER"}'Each callback includes an X-Appaudix-Signature HMAC-SHA256 header so you can verify it came from appaudix. Full API reference →
Yes — API access (and therefore the GitHub Action) is part of the Enterprise plan. Free, Pro, and Team customers can run scans from the dashboard. See pricing →
Typically 5–30 seconds wall-clock for a typical mobile app. The action polls every 10 seconds with exponential backoff up to timeout_minutes (default 30).
Set wait_for_results: false. The action submits the scan, sets the scan_id output, and returns immediately. Combine with callback_url for true async pipelines.
The report_url output is a permanent URL. Add .pdf or .json to fetch other formats. Reports also appear in your dashboard.
Yes. The outputs include each severity bucket. Add a step like if: steps.scan.outputs.high_count > 3 for custom policy.
We use necessary storage for security and login. With your permission, we also use analytics to understand page journeys and marketing pixels to measure ad campaigns.