Security Best Practices
Appilots gives an AI agent the ability to act inside your app. That power is governed by three layers you control: who holds a valid key, what the agent is permitted to do, and which actions require a human to confirm. Get all three right and a compromised or confused agent session has very little blast radius.
1. Treat API keys as revocable, scoped capabilities
A mobile app's API key ships inside the app binary, and app binaries can be unpacked. Assume the key is semi-public once shipped — your protection comes from scoping and revocability, not from secrecy of the key itself:
- Scope: each key is bound to exactly one project. Use separate projects (or at minimum separate keys) per environment so staging and production never share a credential — see Projects & API keys.
- Revocability: if a key is abused or leaked, revoke it in the dashboard and issue a new one. Plan for this: one key per distribution channel means revocation doesn't take down every build at once.
- Rotation: rotate keys periodically as hygiene, and immediately after any suspected exposure.
- Keep keys out of source control:
.appilotsrcholds the key in plain text —appilots initadds it to.gitignore, but verify before your first commit (CLI configuration). In CI, use theAPPILOTS_API_KEYsecret env var and no config file at all (CI integration). - Don't hardcode keys in app source either — inject them at build time
(the Metro plugin +
.appilotsrcflow does this) so the key never appears in your repository history.
2. Grant the minimum permissions the integration needs
The AgentPermissions model defaults to fully
open when unset. For production, set it deliberately:
- Turn off capabilities you don't use — a support-navigation assistant that
never fills forms should run with
canFillForms: falseandcanSubmitForms: false. - Use
blockedScreensfor areas the agent has no business in (admin panels, payment settings), orallowedScreensto whitelist when the surface is small. - Use
allowedActionsto restrict the action types available at all. - Set the project-wide baseline in the dashboard and tighten per-build with SDK-side permissions where a specific app variant warrants less.
3. Put risk metadata on every mutating action
Confirmation gating is only as good as your metadata. Any action that changes state — saves, payments, deletions, subscription changes — should declare what it does:
actions: [
{
id: 'deleteVehicle',
label: 'Delete vehicle',
type: 'button',
effect: 'destructive',
riskLevel: 'high',
destructive: true,
},
]
effect: 'write' | 'destructive'+riskLevellet the platform gate the action without guessing from button labels — critical in multilingual apps (Agent actions).- Destructive/high-risk actions get an explicit confirmation card the user
must tap — and
confirmsteps can never be auto-executed. - Enforce coverage mechanically:
appilots sync --strict-metadatafails the build when a mutating action is missing this metadata (Metadata quality). Make it a required CI check.
4. Operational hygiene
- Least-privilege team roles: default new teammates to
memberorviewer; reserveadmin/ownerfor people who manage keys, webhooks, and billing (Team management). - Verify webhook signatures: every webhook delivery is HMAC-signed — reject any delivery whose signature doesn't validate against your stored secret (Webhooks). Webhook secrets are shown once, like API keys; store them accordingly.
- Set a budget so abuse or a bug surfaces as a capped bill, not an open-ended one (Permissions, budget & personalization).
- Watch the dashboards: unusual usage patterns in usage & analytics are your early signal that a key is being used outside its intended app.
- Mind end-user data: the identify surface is write-only from the app and identifiers are never sent to the model — but only send the identifiers your support workflow actually needs.
Quick checklist
- Separate key per environment and distribution channel
- No keys in git history;
.appilotsrcignored; CI uses secret env vars - Rotation procedure documented; revocation tested
- Permissions explicitly configured (not left at default-open)
- Every mutating action carries
effect/riskLevel;--strict-metadataenforced in CI - Webhook signature verification implemented
- Team roles follow least privilege
- Budget configured