$npx -y skills add dpearson2699/swift-ios-skills --skill cryptotokenkitAccess security tokens and smart cards using CryptoTokenKit. Use when building TKTokenDriver or TKSmartCardTokenDriver extensions, communicating with smart cards via TKSmartCard/TKSmartCardSlotManager, using iOS 26+ NFC smart-card sessions, registering smart cards, querying token
| 1 | # CryptoTokenKit |
| 2 | |
| 3 | Use CryptoTokenKit for token driver extensions, smart-card communication, |
| 4 | token sessions, token-backed keychain integration, and certificate-based |
| 5 | authentication in Swift 6.3 apps. |
| 6 | |
| 7 | **Platform availability:** CryptoTokenKit classes are available across Apple |
| 8 | platforms, but capability depends on extension point, entitlement, hardware, and |
| 9 | OS version. The smart-card app extension flow for login/keychain unlock is macOS. |
| 10 | `TKSmartCardSlotManager.default` is optional and returns `nil` unless smart-card |
| 11 | access is enabled. iOS/iPadOS 26+ add NFC smart-card slots and registration. |
| 12 | |
| 13 | ## Contents |
| 14 | |
| 15 | - [Architecture Overview](#architecture-overview) |
| 16 | - [Token Extensions](#token-extensions) |
| 17 | - [Token Sessions](#token-sessions) |
| 18 | - [Smart Card Communication](#smart-card-communication) |
| 19 | - [Keychain Integration](#keychain-integration) |
| 20 | - [Certificate Authentication](#certificate-authentication) |
| 21 | - [Token Watching](#token-watching) |
| 22 | - [Error Handling](#error-handling) |
| 23 | - [Common Mistakes](#common-mistakes) |
| 24 | - [Review Checklist](#review-checklist) |
| 25 | - [References](#references) |
| 26 | |
| 27 | ## Architecture Overview |
| 28 | |
| 29 | CryptoTokenKit bridges hardware security tokens (smart cards, USB tokens) |
| 30 | with authentication and keychain services. The framework has three main usage |
| 31 | modes: |
| 32 | |
| 33 | **Smart-card token extensions** -- macOS app extensions that make a hardware |
| 34 | token's cryptographic items available to system login and keychain unlock. The |
| 35 | driver handles token lifecycle, session management, and cryptographic operations. |
| 36 | |
| 37 | **Client-side token access** -- Apps query the keychain for items backed by |
| 38 | tokens. CryptoTokenKit exposes token items as standard keychain entries when a |
| 39 | token is present. |
| 40 | |
| 41 | **NFC smart-card access** -- iOS/iPadOS 26+ apps create a temporary NFC smart |
| 42 | card slot and communicate with the presented contactless card through |
| 43 | `TKSmartCard`. |
| 44 | |
| 45 | **Boundary routing:** Own token/smart-card sessions, token-backed keychain |
| 46 | items, and certificate-based smart-card auth. Route passkeys/WebAuthn and |
| 47 | account sign-in to `authentication`; route Secure Enclave, CryptoKit primitives, |
| 48 | keychain architecture, certificate pinning, and trust policy to `swift-security`. |
| 49 | |
| 50 | ### Key Types |
| 51 | |
| 52 | | Type | Role | Platform | |
| 53 | |---|---|---| |
| 54 | | `TKTokenDriver` / `TKToken` / `TKTokenSession` | Token driver, token, and session primitives | iOS 10+, macOS 10.12+ | |
| 55 | | `TKSmartCardTokenDriver` | Entry point for smart card token extensions | iOS 10+, macOS 10.12+; macOS extension flow | |
| 56 | | `TKSmartCard` / `TKSmartCardSlotManager` | Low-level APDU communication and slot discovery | iOS 9+, macOS 10.10+; `default` is optional | |
| 57 | | `TKTokenWatcher` | Observes token insertion and removal | iOS 10+, macOS 10.12+ | |
| 58 | | `TKSmartCardSlotNFCSession` | NFC-backed smart card slot session | iOS/iPadOS 26+ | |
| 59 | | `TKSmartCardTokenRegistrationManager` | Registers NFC smart cards for later keychain use | iOS/iPadOS 26+ | |
| 60 | |
| 61 | ## Token Extensions |
| 62 | |
| 63 | For system login and keychain unlock on macOS, a token driver is an app |
| 64 | extension that makes a hardware token's cryptographic capabilities available to |
| 65 | the system. The host app exists only as a delivery mechanism for the extension. |
| 66 | |
| 67 | A smart card token extension has three core classes: |
| 68 | |
| 69 | 1. **TokenDriver** (subclass of `TKSmartCardTokenDriver`) -- entry point |
| 70 | 2. **Token** (subclass of `TKSmartCardToken`) -- represents the token |
| 71 | 3. **TokenSession** (subclass of `TKSmartCardTokenSession`) -- handles operations |
| 72 | |
| 73 | ### Driver Class |
| 74 | |
| 75 | ```swift |
| 76 | import CryptoTokenKit |
| 77 | |
| 78 | final class TokenDriver: TKSmartCardTokenDriver, TKSmartCardTokenDriverDelegate { |
| 79 | func tokenDriver( |
| 80 | _ driver: TKSmartCardTokenDriver, |
| 81 | createTokenFor smartCard: TKSmartCard, |
| 82 | aid: Data? |
| 83 | ) throws -> TKSmartCardToken { |
| 84 | return try Token( |
| 85 | smartCard: smartCard, |
| 86 | aid: aid, |
| 87 | instanceID: "com.example.token:\(smartCard.slot.name)", |
| 88 | tokenDriver: driver |
| 89 | ) |
| 90 | } |
| 91 | } |
| 92 | ``` |
| 93 | |
| 94 | ### Token Class |
| 95 | |
| 96 | The token reads certificates and keys from hardware and populates its |
| 97 | keychain contents: |
| 98 | |
| 99 | ```swift |
| 100 | final class Token: TKSmartCardToken, TKTokenDelegate { |
| 101 | init( |
| 102 | smartCard: TKSmartCard, aid: Data?, |
| 103 | instanceID: String, tokenDriver: TKSmartCardTokenDriver |
| 104 | ) throws { |
| 105 | try super.init( |
| 106 | smartCard: smartCard, aid: aid, |
| 107 | instanceID: instanceID, tokenDriver: tokenDriver |
| 108 | ) |
| 109 | self.delegate = self |
| 110 | |
| 111 | let certData = try readCertificate(from: smartCard) |
| 112 | guard let cert = SecCertificateCreateWithData(nil, certData as CFData) else { |