KeychainAccess

repository·master·Indexed 27 days ago

https://github.com/kishikawakatsumi/keychainaccess

A Swift wrapper that simplifies interacting with the system Keychain on Apple platforms, including iOS, macOS, watchOS, tvOS, and Mac Catalyst. It provides a Swifty interface for managing secure credentials, supporting Access Groups, iCloud sharing, Touch ID/Face ID integration, and Shared Web Credentials.

Tokens
2.1K
Snippets
6
Records
17
Agent score
44%

What's inside KeychainAccess

  1. Key Features of KeychainAccess

    master

    KeychainAccess provides several high-level features for secure data management:

    • Simple interface for Keychain operations.
    • Support for Access Groups.
    • Support for Accessibility settings.
    • Support for iCloud sharing.
    • Integration with Touch ID and Face ID (iOS 8+).
    • Support for Shared Web Credentials (iOS 8+).
    • Compatibility with Swift 3, 4, and 5.
  2. Integrate Touch ID / Face ID authentication

    master

    To use biometric authentication, you must run operations on a background thread to avoid locking the UI thread when the system authentication dialog appears.

    Requirements:

    • Add NSFaceIDUsageDescription to your Info.plist for Face ID support.
    • Use .accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: [.biometryAny]) to protect items.
    • Use .authenticationPrompt("message") to provide a custom prompt.

    Warning: Updating or obtaining protected items requires authentication and must be handled asynchronously.

  3. Install KeychainAccess via Swift Package Manager

    master

    You can install KeychainAccess using Swift Package Manager (SPM) via Xcode or the CLI.

    Xcode: Select File > Add Packages... > Add Package Dependency... and provide the repository URL.

    CLI: Create a Package.swift file and include KeychainAccess in your dependencies.

    // swift-tools-version:5.0
    import PackageDescription
    
    let package = Package(
        name: "MyLibrary",
        products: [
            .library(name: "MyLibrary", targets: ["MyLibrary"]),
        ],
        dependencies: [
            .package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", from: "3.0.0"),
        ],
        targets: [
            .target(name: "MyLibrary", dependencies: ["KeychainAccess"]),
        ]
    )
  4. Instantiate Keychain for Application or Internet Passwords

    master

    You can create a Keychain instance for different types of credentials. Use service for application passwords and server/protocolType for internet passwords.

    Application Passwords

    Use a service identifier (e.g., a bundle ID).

    Internet Passwords

    Use a server URL and a protocolType (e.g., .https). You can also specify an authenticationType (e.g., .htmlForm).

    // Application Password
    let keychain = Keychain(service: "com.example.github-token")
    let keychain = Keychain(service: "com.example.github-token", accessGroup: "12ABCD3E4F.shared")
    
    // Internet Password
    let keychain = Keychain(server: "https://github.com", protocolType: .https)
    let keychain = Keychain(server: "https://github.com", protocolType: .https, authenticationType: .htmlForm)
  5. Use Shared Web Credentials

    master

    Shared web credentials allow native iOS apps to share credentials with their website counterparts (e.g., Safari).

    Setup Requirements:

    1. Add com.apple.developer.associated-domains entitlement to your app with your domains.
    2. Add an apple-app-site-association file to your website.

    Usage:

    Use getSharedPassword to check for credentials in the Shared Web Credentials store and setSharedPassword to save them there.

  6. Resolve Keychain sharing error [-34018]

    master
    If you encounter the error OSStatus error:[-34018] Internal error when a required entitlement isn't present, client has neither application-identifier nor keychain-access-groups entitlements., you must add a Keychain.entitlements file to your project to enable keychain sharing capabilities.
  7. Add and Remove items from Keychain

    master

    Items can be added using subscripting (for String or NSData) or the .set() method. To remove an item, set its subscript value to nil or use the .remove() method.

    Note: The .set() method can throw errors, so it should be wrapped in a do-catch block.

    // Adding via subscripting
    keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
    keychain[data: "secret"] = NSData(contentsOfFile: "secret.bin")
    
    // Adding via set method
    keychain.set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
    
    // Removing
    keychain["kishikawakatsumi"] = nil
    try keychain.remove("kishikawakatsumi")
  8. Configure Keychain attributes (Label, Comment, Accessibility, Sync)

    master

    KeychainAccess provides a fluent interface to configure item attributes during instantiation or just before a set operation.

    Common Configuration Methods:

    • .label(String): Sets the item label.
    • .comment(String): Sets a comment for the item.
    • .synchronizable(Bool): Enables/disables iCloud Keychain synchronization.
    • .accessibility(KeychainAccessibility): Sets the accessibility level (e.g., .afterFirstUnlock for background apps, .whenUnlocked for foreground apps).
    • .accessGroup(String): Enables sharing items across different apps via an access group.
    let keychain = Keychain(service: "com.example.github-token")
        .label("github.com (kishikawakatsumi)")
        .synchronizable(true)
        .accessibility(.afterFirstUnlock)