Easy to use SMJobBless, along with a full Swift implementation of the Authorization Services and Service Management frameworks

Overview

Leverage SMJobBless functionality with just one function call:

let message = "Example App needs your permission to do thingamajig."
let icon = Bundle.main.url(forResource: "bless", withExtension: "png")
try LaunchdManager.authorizeAndBless(message: message, icon: icon)

Both the message and icon parameters are optional. Defaults will be provided by macOS if they are not specified.

Overview

Beyond making it easy to bless an executable, Blessed provides a complete Swift implementation of the non-deprecated portions of macOS's Authorization Services and Service Management frameworks. At a high level this framework exposes three closely related capabilities:

  1. Requesting a user grant permission for one or more rights via macOS's Security Server
  2. Defining custom rights in the Policy Database
  3. Using launchd to install executables which will run with root privileges

For completeness the Service Management capability to enable and disable login items via launchd is also included; see LaunchdManager.enableLoginItem(forBundleIdentifier:) and LaunchdManager.disableLoginItem(forBundleIdentifier:).

Authorization

In some more advanced circumstances you may to want directly interact with macOS's Security Server via the Authorization class.

If you only need to check if a user can perform an operation, use checkRights(_:environment:options:) without needing to create an Authorization instance.

Otherwise you'll typically want to initialize an instance via init() and then subsequently request rights with requestRights(_:environment:options:) or requestRightsAsync(_:environment:options:callback:).

Defining Custom Rights

macOS's authorization system is built around the concept of rights. The Policy Database contains definitions for all of the rights on the system and your application can add its own.

If an application defines its own rights it can then use these to self-restrict functionality. For details on why you might want to do see, consider reading Apple's Technical Note TN2095: Authorization for Everyone although keep in mind the code samples shown are not applicable if you are using this Swift implementation.

To define a custom right:

let myCustomRight = AuthorizationRight(name: "com.example.MyApp.special-action")
let description = "MyApp would like to perform a special action."
let rules: Set<AuthorizationRightRule> = [CannedAuthorizationRightRules.authenticateAsAdmin]
try myCustomRight.createOrUpdateDefinition(rules: rules, descriptionKey: description)

The above example creates a right called "com.example.MyApp.special-action" which requires that the user authenticate as an admin. How exactly the user does so is up to macOS; your application does not concern itself with this. (At the time of this documentation being written this means the user needing to type in a password, but in the future Apple could for example update their implementation of the authenticateAsAdmin rule to use Touch ID.) When the user is asked to authenticate they will see the message "MyApp would like to perform a special action."

There are several optional parameters not used in this example, see the documentation for details.

If you need to create a rule which is not solely composed of already existing rules, you must create an authorization plug-in, which is not covered by this framework. See Using Authorization Plug-ins for more information.

Sandboxing

Most of this framework is not available to sandboxed apps because of privilege escalation.

The exceptions to this are:

  • reading or existence checking a right definition in the Policy Database
  • enabling or disabling a login item

If you need to determine at run time if your app is sandboxed, this framework exposes an extension on NSApplication:

let sandboxed = try NSApplication.shared.isSandboxed()
Comments
  • Always throwing Blessed.LaunchdError error 3 - authorizationFailed

    Always throwing Blessed.LaunchdError error 3 - authorizationFailed

    Hello!

    I'm attempting to use this as a part of an application running a privileged helper, and am using SwiftAuthorizationSample as a jumping off point. I've been having issues getting this to function in my own app, so here is a short summary:

    I started off by running the SwiftAuthorizationSample project, just changing the Signing ID to my developer ID. When running the project, it worked flawlessly, installed the helper tool, and I could see it located in /Library/PrivilegedHelperTools. Success!

    So, I started initially by going through the code in that project to create my own version which accomplishes running a privileged command in a different communication method. This is when I first ran into the problem of it not installing. It threw a Blessed.LaunchdError error 3. This would come to haunt me.

    My initial thought was that something in my implementation had been wrong. So, out of curiousity, I began by recreating the helper tool, and the shared resources in my project, knowing that if I can get those to work, it's my implementation, and not my project files. I dragged and dropped, verified that my Info.plists were correct, run scripts, even scrolling through Build Settings side by side to make sure they matched.

    No such luck. Ouch.

    So then I tried to back trace where this error could be from. When I followed where it was running, I figured that it had to be an error thrown at line 81 in LaunchdManager.swift in the Blessed package. I couldn't find anywhere explicitly throwing an authorizationError, soooooo.

    I then figured I'd take a look at the errors in both this project, as well as SwiftAuthorizationSample, and the closest issues I could find are #8 and #6 both of which seem like they should have been resolved by this solution. The root of the problem seemed to be addressed, which was that the Signing ID's needed to be in quotes. As my code pull was after this change, I'm not sure what could be the issue.

    When I ran the install code, it showed a dialogue, I entered my password, and without a doubt, every time, it would throw that error. I double verified everything again. After all, it has to be me. The only issue that it could be is that the app may not have permissions to write to /Library, but the .xcconfig states that it should not be sandboxed, and I was unable to get the NSApplication.isSandboxed() check to return anything, as it always just threw an error when running.

    I've done my best to ensure that all of the settings are true to what they should be, the project is indeed using the correct .xcconfig files, and all information is true. It does in fact copy the helper tool to DerivedData/Build/Products/Debug/Maple/Contents/Library/LaunchServices/dev.halz.Maple.helper. This is the output of DiagnosticSigningInfo.printDiagnosticInfo():

    ==============This App=============
    2022-05-10 09:41:30.260574-0400 Maple[5475:141871] [logging-persist] cannot open file at line 45530 of [9ff244ce07]
    2022-05-10 09:41:30.260631-0400 Maple[5475:141871] [logging-persist] os_unix.c:45530: (0) open(/var/db/DetachedSignatures) - Undefined error: 0
    CFBundleIdentifier: dev.halz.Maple
    CFBundleVersion: 1
    Common Name: Apple Development: My Name (CT44P6LGD8)
    Organizational Unit: 5RD23JCCKU
    
    ========Bundled Helper Tool========
    CFBundleIdentifier: dev.halz.Maple.helper
    CFBundleVersion: 1.0.1
    Common Name: Apple Development: My Name (CT44P6LGD8)
    Organizational Unit: 5RD23JCCKU
    
    =======Installed Helper Tool=======
    Helper tool is not installed
    

    I appreciate any input you have in this issue! It's much appreciated.

    opened by ha1lie 6
  • Failed to resolve dependencies

    Failed to resolve dependencies

    First off, sorry if this is user error rather than specifically a Blessed/SecureXPC question:

    I'm attempting to debug my app in Catalina as my helper is crashing both there and in Big Sur (it runs fine in Monterey). To this end I've installed macOS Catalina 10.15.4 on a partition and set up Xcode 12.4, which is the latest available for 10.15. I've also installed and selected the Swift 5.6.1 toolchain.

    Despite selecting the 5.6.1 toolchain, I get "Failed to resolve dependencies": "because every version of Blessed contains incompatible tools version and root depends on Blessed 0.3.0..<1.0.0, version solving failed."

    Am I missing something? Has anyone else successfully used Blessed/SecureXPC in Xcode running on Catalina?

    opened by jeff-h 2
  • Introduces `BlessError` to provide detailed error explanation

    Introduces `BlessError` to provide detailed error explanation

    Instead of just passing through Apple's (lackluster) CFError value, BlessedError actually runs through each requirement and provides a detailed explanation for each one that fails to be met. This is done in part by adding dependencies on the EmbeddedPropertyList and Required packages.

    opened by jakaplan 1
  • Refactors to only be bless functionality

    Refactors to only be bless functionality

    • Factors out all Authorization related functionality into its own package - https://github.com/trilemma-dev/Authorized
    • Removes login item related functionality
    • Removes LaunchdError
    opened by jakaplan 0
  • Removes usage of `kAuthorizationExternalFormLength`

    Removes usage of `kAuthorizationExternalFormLength`

    This causes issues on Xcode 13.3 because its type has changed from Int to Int32. It'd be easy enough to explicitly convert it to an Int, but this isn't actually necessary as the serialized form knows its own length.

    opened by jakaplan 0
Releases(0.6.0)
  • 0.6.0(Jun 21, 2022)

    With this release, the purpose of Blessed has narrowed to exclusively be about providing an excellent Swift wrapper around SMJobBless.

    Breaking changes

    This is a significantly breaking release, if you do not want to update your app at this time consider using 0.5.0 instead.

    • All authorization related functionality has been removed from this package and now lives in the Authorized package which has become a dependency of this package. All functionality has been fully preserved and no changes have been made to the public API.
    • Login item functionality (SMLoginItemSetEnabled) has been removed. There was minimal benefit to using this package's Swift wrapper for it, so you're recommend to use Apple's API directly.
    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Jun 20, 2022)

    This release has significantly improved error generation for bless(...).

    New functionality

    • When calling bless(...) or either of the authorizeAndBless(...) functions, if blessing fails then a new BlessError will be thrown. This error's description contains detailed explanations of exactly why the bless failed. This functionality is made possible by adding two new dependencies:
      • EmbeddedPropertyList to read the property lists embedded in the helper tool's binary file.
      • Required to parse and evaluate the code signing requirements the app and helper tool have for each other.

    Breaking changes

    • Most of the cases in LaunchdError have been removed. This same functionality and more is now available via BlessError.
    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(May 13, 2022)

    This release changes both the external sandbox check API as well as its internal implementation.

    Breaking changes

    • The function NSApplication.shared.isSandboxed() has been removed and replaced with the ProcessInfo.processInfo.isSandboxed property.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Apr 11, 2022)

    This release adds async variants for two potentially long running functions requestRights and authorizeAndBless. This functionality is available on macOS 10.15 and later.

    New functionality

    • There is now an async version of requestRights(_:environment:options:). This function can take an indeterminate time to complete as depending on the rights requested it can require user input. This new function does not block while waiting on user input, instead it can be awaited.
    • There is also now an async version of authorizeAndBless(message:icon:). Internally it uses the above mentioned requestRights function to asynchronously request rights without blocking on user input.

    Breaking changes

    • requestRightsAsync(_:environment:options:callback:) was renamed to requestRights(_:environment:options:callback:). There is no change in functionality.
    Source code(tar.gz)
    Source code(zip)
  • 0.2.1(Mar 22, 2022)

  • 0.2.0(Nov 7, 2021)

    • Includes breaking changes
    • Removes unnecessary initializer in Authorization, same functionality available in a more comprehensible way via requestRights function
    • Improves documentation
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Oct 21, 2021)

Owner
null
Approov-service-ios-swift-grpc - Approov service layer for iOS clients using GRPC

Approov Service for GRPC A wrapper for the Approov SDK to enable easy integratio

Approov Integration Examples 0 Jan 21, 2022
Publish and discover services using Bonjour

Ciao Lib to publish and find services using mDNS Requirements Installation Usage License Requirements iOS 8.0+ / Mac OS X 10.10+ / tvOS 9.0+ Xcode 9.0

Alexandre Mantovani Tavares 55 Dec 14, 2022
This generic SOAP client allows you to access web services using a your iOS app, Mac OS X app and AppleTV app.

This generic SOAP client allows you to access web services using a your iOS app, Mac OS X app and Apple TV app. With this Framework you can create iPh

Prioregroup.com 479 Nov 22, 2022
SkyWite is an open-source and highly versatile multi-purpose frameworks.

SkyWite is an open-source and highly versatile multi-purpose frameworks. Clean code and sleek features make SkyWite an ideal choice. Powerful high-level networking abstractions built into Cocoa. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use.

SkyWite 24 Apr 22, 2022
OctopusKit is a simplicity but graceful solution for invoke RESTful web service APIs

OctopusKit OctopusKit is a simplicity but graceful solution for invoke RESTful web service APIs,it can help coder develop app based MVC pattern, it ca

i ⚒  kit 3 Jul 29, 2021
TheraForge's Client REST API framework to connect to TheraForge's secure CloudBox Backend-as-a-Service (BaaS)

OTFCloudClientAPI TheraForge's Client REST API Framework to Connect to TheraForg

TheraForge 0 Dec 23, 2021
WebSocket implementation for use by Client and Server

WebSocket ⚠️ This module contains no networking. To create a WebSocket Server, see WebSocketServer. To create a WebSocket Client, see WebSocketClient.

Zewo Graveyard 63 Jan 29, 2022
A modern download manager based on NSURLSession to deal with asynchronous downloading, management and persistence of multiple files.

TWRDownloadManager TWRDownloadManager A modern download manager for iOS (Objective C) based on NSURLSession to deal with asynchronous downloading, man

Michelangelo Chasseur 407 Nov 19, 2022
BP Passport is a mobile app to help patients with blood pressure management

BP Passport - Simple for Patients BP Passport is a native mobile application written in React Native - a JavaScript library that renders native, cross

Simple 4 Sep 18, 2022
APIProvider - API Provider Package for easier API management inspired by abstraction

APIProvider Using APIProvider you can easily communicate with all API endpoints

null 1 Apr 21, 2022
Easy to use CFNetwork wrapper for HTTP requests, Objective-C, Mac OS X and iPhone

ASIHTTPRequest is an easy to use wrapper around the CFNetwork API that makes some of the more tedious aspects of communicating with web servers easier

Ben Copsey 5.8k Dec 14, 2022
Easy-to-use ICMP Ping for iOS (and maybe OSX)

CDZPinger Easy-to-use ICMP ping for iOS - just create a CDZPinger and you delegate gets a callback every second with the average ping time. Installati

Chris Dzombak 48 Feb 2, 2022
Easy to use OAuth 2 library for iOS, written in Swift.

Heimdallr Heimdallr is an OAuth 2.0 client specifically designed for easy usage. It currently supports the resource owner password credentials grant f

trivago N.V. 628 Oct 17, 2022
The easy way to use sockets on Apple platforms

SwiftSocket SwiftSocket library provides as easy to use interface for socket based connections on server or client side. Supports both TCP and UDP soc

null 1.6k Dec 21, 2022
A slim implementation of a websocket server using Swift and Vapor 4.0.

Swift Websocket Server Example using Vapor 4.0 This project includes a minimum working example for a websocket server written in Swift. To interact wi

Adrian Hupka 5 Sep 22, 2022
Cross-platform JsonRPC client implementation with HTTP and WebSocket support

JsonRPC.swift Cross-platform JsonRPC client implementation with HTTP and WebSocket support Getting started Installation Package Manager Add the follow

Tesseract 5 Oct 19, 2022
Swift implementation of WalletConnect v.2 protocol for native iOS applications

Wallet Connect v.2 - Swift Swift implementation of WalletConnect v.2 protocol for native iOS applications. Requirements iOS 13 XCode 13 Swift 5 Usage

WalletConnect 142 Jan 4, 2023
DICOM implementation written in Swift

DcmSwift DcmSwift is a (partial, work in progress) DICOM implementation written

OPALE 6 Dec 1, 2022
Swift implementation of libp2p, a modular & extensible networking stack

Swift LibP2P The Swift implementation of the libp2p networking stack Table of Contents Overview Disclaimer Install Usage Example API Contributing Cred

null 19 Dec 18, 2022