Skip to content
Development
Skill

/device-integrity

Verify device legitimacy and app integrity using DeviceCheck (DCDevice per-device bits) and App Attest (DCAppAttestService key generation, attestation, and assertion flows). Use when implementing fraud prevention, detecting compromised devices, validating app authenticity with

From plugin
swift-ios-skills
98186 skills1 MCP
Install
$ npx -y skills add dpearson2699/swift-ios-skills --skill device-integrity --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/device-integrity

Context preview

The summary Claude sees to decide when to auto-load this skill.

Verify device legitimacy and app integrity using DeviceCheck (DCDevice per-device bits) and App Attest (DCAppAttestService key generation, attestation, and assertion flows). Use when implementing fraud prevention, detecting compromised devices, validating app authenticity with

SKILL.md

device-integrity.SKILL.md
name: device-integrity
description: "Verify device legitimacy and app integrity using DeviceCheck (DCDevice per-device bits) and App Attest (DCAppAttestService key generation, attestation, and assertion flows). Use when implementing fraud prevention, detecting compromised devices, validating app authenticity with Apple's servers, protecting sensitive API endpoints with attested requests, or adding device verification to a backend architecture."

Device Integrity

Verify that requests to your server come from a genuine Apple device running a legitimate instance of your app. DeviceCheck provides per-device bits for simple flags (e.g., "claimed promo offer"). App Attest uses Secure Enclave keys and Apple attestation to cryptographically prove app legitimacy on sensitive requests.

Contents

  • [DCDevice (DeviceCheck Tokens)](#dcdevice-devicecheck-tokens)
  • [DCAppAttestService (App Attest)](#dcappattestservice-app-attest)
  • [App Attest Key Generation](#app-attest-key-generation)
  • [App Attest Attestation Flow](#app-attest-attestation-flow)
  • [App Attest Assertion Flow](#app-attest-assertion-flow)
  • [Server Verification Guidance](#server-verification-guidance)
  • [Error Handling](#error-handling)
  • [Common Patterns](#common-patterns)
  • [Common Mistakes](#common-mistakes)
  • [Review Checklist](#review-checklist)
  • [References](#references)

DCDevice (DeviceCheck Tokens)

[`DCDevice`](https://sosumi.ai/documentation/devicecheck/dcdevice) generates a unique, ephemeral token that identifies a device. Treat each token as single-use: generate a new token for each server operation instead of caching or reusing one. The token is sent to your server, which then communicates with Apple's servers to read or set two per-device bits. Available on iOS 11+.

Token Generation

import DeviceCheck

func generateDeviceToken() async throws -> Data {
    guard DCDevice.current.isSupported else {
        throw DeviceIntegrityError.deviceCheckUnsupported
    }

    return try await DCDevice.current.generateToken()
}

Sending the Token to Your Server

func sendTokenToServer(_ token: Data) async throws {
    let tokenString = token.base64EncodedString()

    var request = URLRequest(url: serverURL.appending(path: "verify-device"))
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try JSONEncoder().encode(["device_token": tokenString])

    let (_, response) = try await URLSession.shared.data(for: request)
    guard let httpResponse = response as? HTTPURLResponse,
          httpResponse.statusCode == 200 else {
        throw DeviceIntegrityError.serverVerificationFailed
    }
}

Server-Side Overview

The server exchanges each fresh token with Apple's authenticated DeviceCheck API. Load [DeviceCheck Server Endpoints](references/device-integrity-patterns.md#devicecheck-server-endpoints) for endpoint and environment details.

What the Two Bits Are For

Apple stores two Boolean values per device per developer team. You decide what they mean. Common uses:

  • **Bit 0:** Device has claimed a promotional offer.
  • **Bit 1:** Device has been flagged for fraud.

Bits persist across app reinstall. You control when to reset them via the server API.

DCAppAttestService (App Attest)

[`DCAppAttestService`](https://sosumi.ai/documentation/devicecheck/dcappattestservice) validates that a specific instance of your app on a specific device is legitimate. It uses a hardware-backed key in the Secure Enclave to create cryptographic attestations and assertions. Available on iOS 14+.

The flow has three phases: 1. **Key generation** -- create a key pair in the Secure Enclave. 2. **Attestation** -- Apple certifies the key belongs to a genuine Apple device running your app. 3. **Assertion** -- sign server requests with the attested key to prove ongoing legitimacy.

Checking Support

import DeviceCheck

let attestService = DCAppAttestService.shared

guard attestService.isSupported else {
    // Fall back to DCDevice token or other risk assessment.
    // App Attest is not available on simulators or all device models.
    return
}

For app extensions, App Attest is supported only in Action, extensible SSO, and watchOS extensions. Treat other extension types as unsupported even if `isSupported` returns `true`.

App Attest Key Generation

Generate one cryptographic key pair per user account on each device. The private key stays in the Secure Enclave. The returned `keyId` is the only identifier your app can later use to access the key, so record and reuse the account/device-scoped `keyId`; do not share one key across users. Avoid unnecessary regeneration because each new key affects App Attest key-count risk metrics. Only treat the `keyId` as usable after your server verifies attestation. If server verification fails, discard the `keyId` and generate a new key before retrying.

import DeviceCheck

actor AppAttestManager {
    private let service = DCAppAttestService.shared
    private var keyId: String?

    /// Generate and record a key pair for App Attest.
    func generateKeyIfNeeded() async throws -> String {
        if let existingKeyId = loadKeyIdFromKeychain() {
            self.keyId = existingKeyId
            return existingKeyId
        }

        let newKeyId = try await service.generateKey()
        saveKeyIdToKeychain(newKeyId)
        self.keyId = newKeyId
        return newKeyId
    }

    // MARK: - Keychain helpers (simplified)

    private func saveKeyIdToKeychain(_ keyId: String) {
        let data = Data(keyId.utf8)
        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrAccount as String: "app-attest-key-id-\(currentAccountID)",
            kSecAttrService as String: Bundle.main.bundleIdentifier ?? "",
            kSecValueData as String: data,
            kSecAttrAccessible as String: kSecAttrAccessib
Read more
Ships withswift-ios-skills

86 agent skills optimized for iOS 26+ development with Swift 6.3 and modern Apple frameworks.

Get the whole plugin
Stats
981
Stars
50
Forks
Active
Maintenance
Python
Language
9d ago
Last commit
5mo ago
Created

Repo: dpearson2699/swift-ios-skills

Other skills on swift-ios-skills.