Skip to main content

No client-side secrets

Grantiva does not require an API key in your app binary. Your app is identified by its Bundle ID and Team ID — both public, non-sensitive values already present in every iOS app — and authenticated by the App Attest attestation itself. That means there is no secret to extract from your IPA on a production build, and nothing to rotate after a leak.
The one exception is the simulator, where App Attest is unavailable and the SDK falls back to an API key. Those requests are unattested and should use a development-only key. See Simulator setup.

Cryptographic attestation

Device verification uses Apple’s App Attest framework:
  1. Grantiva issues a one-time cryptographic challenge
  2. The device creates an attestation with a Secure Enclave–backed key
  3. Grantiva validates the attestation against Apple’s certificate chain
  4. A signed JWT is returned only after successful validation
Challenges are single-use and expire after 5 minutes by default, which is what prevents replay.

Signed JWT tokens

Attestation tokens are RS256-signed JWTs. Depending on your plan they carry device integrity, risk score, jailbreak status, attestation history, and your custom claims, alongside the standard iss, aud, iat, and exp. Your backend verifies the signature against Grantiva’s JWKS and pins iss and aud — pinning both is what stops a token minted for a different organization from being accepted. Tokens default to a 1-hour lifetime. See JWT Claims for the full reference.

Webhook signatures

Webhook payloads are signed with HMAC-SHA256 using your endpoint’s secret. The signature is sent in the X-Grantiva-Signature header as sha256=<hex-digest> over the raw request body. The signing secret is returned once, when the endpoint is created. Always verify signatures before processing payloads — see Webhooks for implementation examples.

API keys

API keys are for backend integrations only — never embed them in a shipping client app. Each key carries a set of scopes that bound what it can do, granted per area: analytics:*, devices:*, claims:*, apps:*, flags:*, feedback:*, vrt:*, webhooks:*, org:*, keys:*, alerts:*, and release_notes:*. A key can only create another key with scopes it holds itself. The secret is shown once at creation and stored hashed; rotate or revoke it from API Keys in the dashboard.

Data handling

  • Attestation data is stored per-organization. No cross-organization data access is possible.
  • Device identity comes from the App Attest key id, not a hardware identifier. It is scoped to your app, so it cannot be used to track a user across apps.
  • Device fingerprint — the SDK sends a SHA-256 hash of identifierForVendor so a device that regenerates its App Attest key is still counted as one Monthly Active Device. The raw identifier is never transmitted.
  • Device properties sent by the SDK are device model, OS version, app version, and build number. The API additionally records the request IP address and User-Agent; both are exposed as JWT claims on Enterprise only.
  • Support ticket emails are optional and stored only for reply notifications.

Multi-tenancy isolation

All data is scoped to your organization at the database level, and every query filters by organization id.

Role-based access

Dashboard access is controlled by four roles, ordered viewer < member < admin < owner: A role is fixed at invite time and can’t be changed afterwards. Role and membership changes, key creation, webhook changes, and billing actions are all recorded in the audit log.

Transport security

All communication between the SDK and Grantiva uses HTTPS, and the SDK relies on the system URL loading stack for TLS and certificate validation. Grantiva does not ship certificate pinning today.

Responsible disclosure

If you discover a security vulnerability, email security@grantiva.io. We take all reports seriously and will respond promptly.