Skip to main content
Custom claims let you embed additional data in the JWT returned by attestation. Your backend reads these claims to make authorization decisions without extra API calls.

Claim types

TypeDescriptionExample
StaticFixed value for all devices"app_version": "2.0"
ConditionalValue based on device propertiesRisk score > 50 → "restricted": true
DynamicComputed from expressions"days_since_first_seen": 42
ExternalFetched from your API at attestation timeUser subscription status
External claims are available on Enterprise plans only.

Managing claims

Claims are managed from the dashboard or via the API.

Dashboard

Go to Settings > Custom Claims to create, edit, reorder, and test claims.

API

# Create a claim
curl -X POST https://grantiva.io/api/v1/claims \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "claimKey": "user_tier",
    "claimName": "User Tier",
    "claimType": "static",
    "dataType": "string",
    "staticValue": "premium"
  }'

Reading claims

Claims appear in the attestation result:
let result = try await grantiva.validateAttestation()

if let tier = result.customClaims["user_tier"] as? String {
    print("User tier: \(tier)")
}
And in the decoded JWT on your backend:
{
  "custom_claims": {
    "user_tier": "premium",
    "restricted": false
  }
}

Tier limits

TierMax claims
Free5
Pro10
Business15
Enterprise20

Testing claims

Use the claim test endpoint to preview how a claim evaluates without performing a real attestation:
curl -X POST https://grantiva.io/api/v1/claims/test \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "claimConfiguration": { "claimKey": "test", "claimType": "conditional", ... },
    "testContext": {
      "deviceProfile": { "riskScore": 75, "jailbreakDetected": true }
    }
  }'