{"id":22325474,"url":"https://github.com/jamf/haversack","last_synced_at":"2025-07-29T16:33:00.447Z","repository":{"id":205867612,"uuid":"690227707","full_name":"jamf/Haversack","owner":"jamf","description":"A Swift library for keychain access on Apple devices","archived":false,"fork":false,"pushed_at":"2024-02-12T14:09:17.000Z","size":118,"stargazers_count":5,"open_issues_count":2,"forks_count":3,"subscribers_count":10,"default_branch":"main","last_synced_at":"2024-11-30T19:03:27.963Z","etag":null,"topics":["ios","keychain","macos","swift","tvos","visionos","watchos"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jamf.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-09-11T19:32:11.000Z","updated_at":"2024-10-09T08:20:12.000Z","dependencies_parsed_at":"2024-02-12T15:57:35.943Z","dependency_job_id":null,"html_url":"https://github.com/jamf/Haversack","commit_stats":null,"previous_names":["jamf/haversack"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamf%2FHaversack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamf%2FHaversack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamf%2FHaversack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamf%2FHaversack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jamf","download_url":"https://codeload.github.com/jamf/Haversack/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228030029,"owners_count":17858432,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ios","keychain","macos","swift","tvos","visionos","watchos"],"created_at":"2024-12-04T02:12:08.531Z","updated_at":"2024-12-04T02:12:09.062Z","avatar_url":"https://github.com/jamf.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://github.com/jamf/Haversack/actions/workflows/swift.yml/badge.svg)](https://github.com/jamf/Haversack/actions/workflows/swift.yml)\n![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)\n\n# Haversack: Swift library for keychain access\n\nA Swift library for interacting with the Keychain on all Apple devices.  Supports macOS, iOS/iPadOS, tvOS, visionOS, and watchOS.\n\n## Goal\n\nSimplify keychain usage for all Swift code running natively on Apple devices.\n\n- App code should not have to touch any of the `kSec...` constants related to keychain item access.\n- Keychain code should look similar/identical across all Apple operating systems.\n\n### Features\n\n- Supports typesafe storage and retrieval of internet passwords, generic passwords, keys/key pairs,\ncertificates, and identities.\n- Uses a fluent interface for constructing queries to find existing keychain items.\n- Provides simple keychain item access controls and security, with support for different operating system specifics.\n- Is easily mockable for unit testing app code without performing actual keychain access.\n- Has great unit tests and OS integration tests for confidence in this library.\n- Has good documentation so all developers can easily adopt this library.\n\n## Getting Started\n\n### Swift Package Manager\n\nInstall with [Swift Package Manager](https://github.com/apple/swift-package-manager) by adding the following to your `Package.swift` file:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/jamf/Haversack\")\n],\n```\n\n## Learn more\n\nHaversack includes documentation suitable for building with DocC.  After integrating Haversack into\na project, use Xcode's **Product \u003e Build Documentation** menu command to compile the documentation\nfor local viewing in the Developer Documentation window.\n\n## Usage\n\n### Basic\n\nThis provides its own serial queue for thread safety and logging with\n[os_log](https://developer.apple.com/documentation/os/os_log).  On macOS, this accesses\nthe user's login keychain.\n\n```swift\n    let myHaversack = Haversack()\n```\n\n#### Configuration\n\nWhen initializing a `Haversack` instance a `HaversackConfiguration` struct can be given which\nincludes settings for how to access the keychain. There are settings for a serial queue, a\nstrategy to use, and which keychain file to use on macOS. If the default values are suitable,\nno configuration is required when instantiating a `Haversack` instance.\n\n```swift\n    // Access the system keychain on macOS\n    let useSystemKeychain = HaversackConfiguration(keychain: .system)\n    let systemHaversack = Haversack(configuration: useSystemKeychain)\n```\n\n### Example code\n\nSave a password for a website:\n\n```swift\n    let myHaversack = Haversack()\n    let newPassword = InternetPasswordEntity()\n    newPassword.protocol = .HTTPS\n    newPassword.server = \"test.example.com\"\n    newPassword.account = \"mine\"\n    newPassword.passwordData = \"top secret\".data(using: .utf8)\n    let savedPassword = try myHaversack.save(newPassword, itemSecurity: .standard, updateExisting: true)\n```\n\nRead the password for a website:\n\n```swift\n    let myHaversack = Haversack()\n    let pwQuery = InternetPasswordQuery(server: \"test.example.com\")\n                        .matching(account: \"mine\")\n    let passwordObj = try myHaversack.first(where: pwQuery)\n\n    // This is the actual password info\n    _ = passwordObj.passwordData\n```\n\nDelete the password for a website without first loading it:\n\n```swift\n    let myHaversack = Haversack()\n    let pwQuery = InternetPasswordQuery(server: \"test.example.com\")\n                        .matching(account: \"mine\")\n    try myHaversack.delete(where: pwQuery)\n```\n\nDelete the password for a website after loading it and using it:\n\n```swift\n    let myHaversack = Haversack()\n    let pwQuery = InternetPasswordQuery(server: \"test.example.com\")\n                        .matching(account: \"mine\")\n                        .returning([.data, .reference])\n    let passwordObj = try myHaversack.first(where: pwQuery)\n\n    // Use the password here\n    _ = passwordObj.passwordData\n\n    // Then delete the password from the keychain\n    try myHaversack.delete(passwordObj)\n```\n\n## Contributing\n\nTo set up for local development, make a fork of this repo, make a branch on your fork named after\nthe issue or workflow you are improving, checkout your branch, then open the folder in Xcode.\n\nThis repository requires verified signed commits.  You can find out more about\n[signing commits on GitHub Docs](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits).\n\n### Pull requests\n\nBefore submitting your pull request, please do the following:\n\n- If you are adding new commands or features, they should include unit tests.  If you are changing functionality, update the tests or add new tests as needed.\n- Verify all unit tests pass on all four supported operating systems.  There are two ways to do this:\n\t1. In Xcode you can switch destinations to each of the following: \"My Mac\", any iOS Simulator, any tvOS Simulator, any visionOS Simulator, and any watchOS Simulator.  Run the unit tests for each of the destinations.\n\t2. Five command line invocations:\n\t\t- `swift test` to verify macOS functionality.\n\t\t- `xcodebuild test -scheme Haversack-Package -destination 'platform=iOS Simulator,name=iPhone 14'` to verify iOS functionality.\n\t\t- `xcodebuild test -scheme Haversack-Package -destination 'platform=tvOS Simulator,name=Apple TV 4K (3rd generation)'` to verify tvOS functionality.\n\t\t- `xcodebuild test -scheme Haversack-Package -destination 'platform=watchOS Simulator,name=Apple Watch Series 9 (41mm)'` to verify watchOS functionality.\n        - `xcodebuild test -scheme Haversack-Package -destination 'platform=visionOS Simulator,name=Apple Vision Pro'` to verify visionOS functionality.\n- Run [SwiftLint](https://github.com/realm/SwiftLint) on the code.  Fix any warnings or errors that appear.\n- Add a note to the CHANGELOG describing what you changed.\n- If your pull request is related to an issue, add a link to the issue in the description.\n\n## Contributors\n\n- Kyle Hammond\n- Jacob Hearst\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamf%2Fhaversack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjamf%2Fhaversack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamf%2Fhaversack/lists"}