Swift Package Plugins - Network Access

I'd like to gauge community interest in adding an explicit permission for both Swift Package Manager command and build tool plugins to access the network outside their sandbox. I believe there are compelling reasons for both types of plugins to do so, and I'd like to collect those reasons to advance this to a pitch.

At a minimum, I believe that private plugins (ones that aren't published by the package) should be granted this permission.

If your plugins were granted network access, what kinds of plugins would you write? Alternatively, why should (or shouldn't) plugins be able to access the network?

13 Likes

My team distributes modular binary xcframeworks to clients. We keep their public interface clean and user-friendly, and for inter-module communication we use SPIs (System Programming Interfaces). The distributed xcframework only contains the regular swiftinterface files (without SPI declarations), while private swiftinterface files are stored separately, uploaded to an artifact storage.

In order to build modules which depend on other modules, we have to have access to the inter-module SPIs. So whenever we're building one of these, we need to download the .private.swiftinterface files of the dependent modules from a remote storage and put them next to the regular ones (inside the xcframework bundle) so these APIs become visible to the build system.

Without Swift Package Manager providing network access to the plugin sandbox, we can only fetch these artifacts outside of the realm of SPM.

1 Like

This has come up in the SSWG and we obviously need network access to be able to deploy Swift apps to AWS/GCP/Heroku etc with a Swift plugin. I believe there is a flag to enable network access, similar to how the file access works but someone in the know can correct me

Is this about app sandbox keys on macOS or something else?

I disagree with this. Forking and editing downloaded packages is very common, so there should be a specific permission. Now, yes, most IDEs ask the user to trust a downloaded directory, but there’s still a huge risk from automatically granting this permission. I think the same is true for storage permissions.

3 Likes

This is an excellent example.

If so, it hasn't been advertised and isn't available in as a PluginPermission.

2 Likes

This is something else.

Great points. I realize I made it sounds like my opinion was in favor of an implicit permission for private plugins — I should've specified an explicit permission.

1 Like

This seems to be a common workaround — pre-fetch the network resources and make them available before building with SPM. I'll make sure to include this motivation.

1 Like

Reopening this topic after a year, since I just ran into an issue with the sandbox for prebuild commands where apparently permissions have changed from Xcode 14 to Xcode 15.

I had just finished writing a prebuild command for compiling kotlin multiplatform projects as part of a swift package. The idea is that you can wrap a swift package around your kotlin multiplatform project to give it some native UI and a proper interface while still sharing business logic etc. with Android. The plugin will then run gradle on every build (which lengthens your build time by approx. 2 seconds for incremental builds), but allows you to change things in the kotlin files and rebuild everything right from Xcode. From a developer experience point of view this is in my opinion preferable than having to open the terminal to run gradle manually or working with Android Studio and Xcode at the same time.

Anyway, since the update to Xcode 15, gradle is unable to fetch its binaries from gradle.org.

Downloading https://services.gradle.org/distributions/gradle-8.0-bin.zip
Exception in thread "main" java.net.UnknownHostException: services.gradle.org

If we had an explicit permission for prebuild commands or even build commands to enable network, I could make this work again.

9 Likes

We also just run into this, wanting to download static resources for processing from the net as part of the build chain...

Dito. I would love to see SPM build tool plugins to be able to get network access for this reason.

Does anybody have hands-on experience in the Swift Evolution Pitch/Proposal process or can get me in touch with someone who does? I'd love to start the process for this topic, however it would be super helpful to have someone with experience as co author or at least sparring partner to reach out in case I have any questions since this is my first time contributing.

Thanks

2 Likes

A way to abstract other permissions would be nice as well - for example, we'd love for plugins to be able to update code outside of derived data.

To do something like 1) pull an OpenAPI spec, 2) generate swift types for all of it.

2 Likes

A colleague of mine found a workaround, which does seem to bypass the sandbox. He created a shortcut in the shortcuts app which is then able to access the network, file system, and run shell scripts. He then ran the shortcut from the swift build plugin.

However, this has two major limitations:

  • You cannot write a shell script to disk and have shortcuts use it as input, to be able to run any command. At least I could not get it to run like that, likely sandbox permissions interfering again.
  • You will need to manually approve privacy related alerts for file system and web access. It will therefore not work for a headless CI with temporary runners, but if you run a self-hosted CI with physical build infrastructure or only need to bypass restrictions on developer machines this may just work for you.

Still, explicit permissions for network and file system access would be a huge win for plugins in my opinion.

Definitely interested in this.

We use crashlytics in our codebase, automatically uploading dsyms via a swift package plugin would be great. Rather than having to run a bash script in a build phase.

I just started an evolution discussion on this. I'd love to get your feedback, so please feel encouraged to participate.

this sounds great @nholloh. I wonder if you've tried the other way around - having a Swift package built and linked to a Kotlin Multiplatform?

We are stuck on the same problem - building a KMP module from the SPM Plugin. However, are you sure that enabling the network access will be enough to make it work? I'm trying at least a CommandPlugin with both writeToPackageDirectory + allowNetworkConnections permissions and it successfully fetches binaries from gradle.org but then it fails with a following error:

org.gradle.api.UncheckedIOException: java.net.SocketException: Operation not permitted