I have a bunch of Audio Unit v3 plugins that are approaching release, and I was considering using subscription-model pricing, as I have done in a soon to be released iOS app. However, whether this is possible or not is not at all obvious. Specifically:
- The plugin can, depending on the host app, be loaded in-process or out-of-process - yes, I know, Logic Pro and Garage Band will not load a plug-in in-process anymore, but I am not going to rule that out for other audio apps and force on them the overhead of IPC (I spent two solid weeks deciphering the process to actually make it possible for an AUv3 to run in-process - see this - https://github.com/timboudreau/audio_unit_rust_demo - example with notes)
- Depending on how it is loaded, the value of
Bundle.main.bundleIdentifierwill vary. If I use the StoreKit API, will that return product results for my bundle identifier when being called as a library from a foreign application? I would expect it would be a major security hole if random apps could query about purchases of other random apps, so I assume not. - Even if I restricted the plugins to running out-of-process, I have to set up the in-app purchases on the app store for the App container's ID, not the extension's ID, and the extension is what run - the outer app that is what you purchase is just a toy demo that exists solely to register the audio unit.
I have similar questions with regard to MetricKit, which I would similarly like to use, but which may be running inside some random app.
If there were some sort of signed token, or similar mechanism, that could be bundled or acquired by the running plugin extension that could be used to ensure both StoreKit and MetricKit operate under the assumption that purchases and metrics should be accessed as if called from the container app, that would be very helpful.
This is the difference between having a one-and-done sales model and something that provides ongoing revenue to maintain these products - I am a one-person shop - if I price these products where they would need to be to pay the bills assuming a single sale per customer ever, the price will be too high for anyone to want to try products from a small vendor they've never heard of. So, being able to do a free trial period and then subscription is the difference between this being a viable business or not.
If there were some sort of signed token, or similar mechanism, that could be bundled or acquired by the running plugin extension
You should feel free to file an enhancement request for that, but I want to set some expectations here [1]. Apple systems enforce security at process boundaries. If such an API existed:
- It’d be impossible for the OS to determine whether you’re plug-in made this call, as opposed to some other code in the host app process.
- Once you had such a token, it’d be impossible for you to prevent some other code in the host app process from ‘stealing’ it [2].
Keep in mind that this “other code” isn’t just the host app itself, but it also includes:
- Any other plug-in that the host app might load
- Any code ‘accidentally’ loaded by the host app or these plug-ins [3]
The long-term direction here is clear: To meet platform security goals plug-ins must run in a separate process. This is strictly enforced on iOS and it’s generally a good idea on macOS [4]. If you’re dealing with an host app that only supports in-process plug-ins, I recommend that you discuss this issue with them.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] If you do file an ER, please post your bug number, just for the record.
[2] You could apply various code obfuscation techniques to reduce the risk of that, but that’s essentially creating a DRM system. And as with all DRM systems, it puts you into an arms race with your attackers.
[3] Because the host app must necessarily have library validation disabled.
[4] I want to be clear that Apple has not announced any plans to enforce this strictly on macOS. There are obvious security benefits, but there are also equally obvious compatibility constraints.