Semua artikel
// Artikel

Checklist Review iOS Keychain dan Data Protection

Dipublikasikan 10 Juli 2026

iOS memakai kontrol terpisah untuk secret dan file. Keychain Services menyimpan credential, key, dan certificate kecil dengan accessibility item serta access group berbasis entitlement. Data Protection menetapkan kelas proteksi file yang ketersediaannya berubah mengikuti state kunci perangkat. Enkripsi platform bukan satu kebijakan storage. Review setiap secret dan file terhadap kebutuhan availability, perilaku migrasi, batas sharing, dan alur pemulihan.

Klasifikasikan data sebelum memilih API

Inventaris refresh token, private key, secret dengan gerbang biometrik, dokumen cache, database, export, log, dan pekerjaan background tertunda. Catat alasan data ada, exposure maksimum bila bocor, kebutuhan availability saat terkunci, periode retensi, kebutuhan backup/migrasi, serta seluruh target yang dapat membaca. Hapus data yang tidak diperlukan fitur; enkripsi tidak memperbaiki retensi berlebihan.

Pakai Keychain untuk secret kecil, bukan UserDefaults atau file aplikasi. Pilih kSecAttrAccessibleWhenUnlocked jika item harus tidak tersedia saat perangkat terkunci. kSecAttrAccessibleAfterFirstUnlock mengizinkan akses setelah first unlock pasca-boot, termasuk state terkunci berikutnya, sehingga dapat dibutuhkan pekerjaan background. Varian ThisDeviceOnly tidak bermigrasi melalui backup restore atau transfer perangkat. kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly memerlukan passcode dan item hilang ketika passcode dihapus. Kelas Always yang deprecated bukan fallback aman.

let query: [String: Any] = [
  kSecClass as String: kSecClassGenericPassword,
  kSecAttrAccount as String: "refresh-token",
  kSecValueData as String: tokenData,
  kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
let status = SecItemAdd(query as CFDictionary, nil)

Jangan menyebut semua secret “tidak tersedia saat terkunci.” Pernyataan itu hanya benar untuk kelas accessibility yang dipilih. Tangani error Keychain yang diharapkan tanpa memindahkan secret ke storage lebih lemah.

Periksa batas access group

Setiap item Keychain milik satu access group. Grup default berasal dari entitlement aplikasi yang ditandatangani; Keychain Sharing mengizinkan target dari development team sama memakai grup bersama yang dikonfigurasi. Review .entitlements untuk keychain-access-groups, setiap aplikasi, extension, atau helper yang berhak atas grup, serta pemakaian kSecAttrAccessGroup nyata. Aplikasi tanpa entitlement grup terpilih menerima errSecMissingEntitlement.

App Groups dan Keychain Access Groups menyelesaikan masalah berbeda. App Groups membagikan container dan IPC tertentu; fitur ini bukan pengganti review Keychain sharing sempit. Simpan secret di grup default privat kecuali target terdokumentasi memerlukannya. Grup credential bersama memperluas blast radius ke seluruh target signed yang dipercaya.

Uji proteksi file secara terpisah

Data Protection berlaku pada file biasa. NSFileProtectionComplete membuat file tidak tersedia segera setelah terkunci. NSFileProtectionCompleteUnlessOpen mengizinkan file yang sudah terbuka setelah kunci, tetapi memblokir akses baru. NSFileProtectionCompleteUntilFirstUserAuthentication tetap dapat dipakai setelah first unlock hingga reboot. NSFileProtectionNone masih mendapat enkripsi hardware, tetapi tersedia saat perangkat menyala. Pilih kelas menurut workflow nyata, bukan label umum “paling kuat”.

try data.write(to: url, options: .atomic)
try FileManager.default.setAttributes(
  [.protectionKey: FileProtectionType.complete], ofItemAtPath: url.path
)

Uji fresh boot sebelum first unlock, state unlocked, state locked, background task, ekspektasi backup/restore, akses extension, dan update aplikasi. Jangan menyatakan perilaku reinstall sebagai jaminan universal; validasi OS serta jalur deployment yang didukung.

Catatan review

ArtefakBuktiPemilikHasilPengecualianRemediasi
Item Keychainattributes dan uji lock statepemilik iOSlulus/gagaltoken background diperlukankelas eksplisit
Access groupentitlement signedpemilik releaselulus/gagalextension disetujuihapus target berlebih
File terlindungikelas dan uji state perangkatpemilik datalulus/gagalupload tertundaubah kelas file
Migrasiuji restore dan kebutuhanpemilik produklulus/gagalrecovery terdokumentasipakai ThisDeviceOnly

Aturan keputusan: pilih Keychain accessibility dan kelas file dari kebutuhan availability terdokumentasi; pilih sharing hanya untuk target entitlement terverifikasi; perlakukan migrasi sebagai kebutuhan terpisah.

Remediasi dan uji ulang

Pindahkan secret keluar dari preferences dan log, hapus entry usang, buat accessibility eksplisit, sempitkan access group, lalu tetapkan proteksi file sebelum data sensitif tersimpan. Uji ulang pada perangkat fisik melewati batas lock dan reboot. Pengujian mobile dapat mereview entitlement, storage runtime, dan perilaku perangkat nyata.

Retensi bukti

Simpan bukti review yang dianonimkan: nama target, nomor build, extract entitlement, kelas item, access group, kategori path file, state perangkat, command atau langkah uji, hasil yang diamati, pemilik, dan tanggal retest. Catat lulus hanya setelah perilaku lock state yang diharapkan terlihat pada perangkat fisik didukung. Catat pengecualian hanya dengan persetujuan pemilik data, alasan, tanggal kedaluwarsa, dan kontrol alternatif. Kebutuhan migrasi bukan alasan memperluas availability tanpa risiko recovery terdokumentasi.

Perilaku Keychain dan penutupan

Simpan item sesi sintetis dengan service, namespace account, kelas accessibility, dan access-control eksplisit. Kunci perangkat, restart aplikasi, lalu coba baca sebelum first unlock, sesudah unlock, dan sesudah kebijakan biometrik berubah. Perilaku harus sesuai kelas: kSecAttrAccessibleWhenUnlockedThisDeviceOnly menolak akses saat perangkat terkunci dan tidak bermigrasi lewat backup. Catat hasil OSStatus, bukan isi secret, karena platform memberi error yang berguna untuk diagnosis.

Kasus tepi: uninstall tidak selalu menghapus item Keychain. Aplikasi yang dipasang ulang dapat melihat item lama kecuali produk membersihkan atau memberi namespace state saat onboarding. Uji account switch dan restore agar material pengguna lama tidak menempel ke akun berbeda. Proteksi Keychain bersifat lokal; validasi, expiry, dan pencabutan token backend tetap perlu.

Tutup dengan build, extract entitlement, atribut item tanpa data nilai, hasil lock-state, hasil uninstall/reinstall, keputusan pemulihan, dan pemilik. Buka ulang setelah entitlement berubah, access group sharing, desain autentikasi, atau format token berubah.

Sources

Punya sistem yang perlu diuji?