I have done the following
Steps to reproduce
Calling the Swift framework/API path ClientImage.config(for:) succeeds from
an unsandboxed SwiftPM executable, but fails from a sandboxed .app bundle
signed with the Apple Container service Mach lookup temporary exceptions.
The repro is a minimal SwiftPM executable. It:
- Calls
ClientImage.list().
- Selects
docker.io/library/alpine:latest from the returned local image list.
- Calls
ClientImage.config(for: Platform.current).
Relevant code:
import ArgumentParser
import ContainerAPIClient
import ContainerizationOCI
import Foundation
@main
struct ImageConfigSandboxRepro: AsyncParsableCommand {
@Option(help: "Local image reference to inspect.")
var image = "docker.io/library/alpine:latest"
func run() async throws {
let images = try await ClientImage.list()
guard let selectedImage = images.first(where: { $0.reference == image }) else {
Foundation.exit(2)
}
let imageConfig = try await selectedImage.config(for: Platform.current).config
print("User: \(imageConfig?.user ?? "<nil>")")
print("Working dir: \(imageConfig?.workingDir ?? "<nil>")")
}
}
Sandbox entitlements used for the .app bundle (ImageConfigSandboxRepro.entitlements):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.temporary-exception.mach-lookup.global-name</key>
<array>
<string>com.apple.container.apiserver</string>
<string>com.apple.container.core.container-core-images</string>
</array>
</dict>
</plist>
Info.plist used for the .app bundle:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>image-config-sandbox-repro</string>
<key>CFBundleIdentifier</key>
<string>com.example.ImageConfigSandboxRepro</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>ImageConfigSandboxRepro</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSBackgroundOnly</key>
<true/>
<key>LSMinimumSystemVersion</key>
<string>15.0</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
Pull the test image. This is the only container CLI step; the repro itself
uses the Swift framework/API packages:
container image pull alpine:latest
Run the unsandboxed control:
swift run image-config-sandbox-repro
Build, wrap, sign, and run the sandboxed app bundle:
swift build
rm -rf .build/debug/ImageConfigSandboxRepro.app
mkdir -p .build/debug/ImageConfigSandboxRepro.app/Contents/MacOS
cp .build/debug/image-config-sandbox-repro \
.build/debug/ImageConfigSandboxRepro.app/Contents/MacOS/image-config-sandbox-repro
cp Info.plist .build/debug/ImageConfigSandboxRepro.app/Contents/Info.plist
codesign --force --sign - --deep \
--entitlements ImageConfigSandboxRepro.entitlements \
.build/debug/ImageConfigSandboxRepro.app
.build/debug/ImageConfigSandboxRepro.app/Contents/MacOS/image-config-sandbox-repro
Current behavior
The unsandboxed run succeeds:
Listing local Apple Container images...
Found 38 image(s).
Selected image: docker.io/library/alpine:latest
About to call ClientImage.config(for: .current).
Config read succeeded.
User: <nil>
Working dir: /
Env:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
The sandboxed app-bundle run fails:
Listing local Apple Container images...
Found 38 image(s).
Selected image: docker.io/library/alpine:latest
About to call ClientImage.config(for: .current).
Error: You don’t have permission to save the file “5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11” in the folder “sha256”.
The failure happens after ClientImage.list() succeeds and after the local
image has been selected through the framework/API. The failing call appears to
attempt direct access from the sandboxed client process to Apple Container's
content blob store:
~/Library/Application Support/com.apple.container/content/blobs/sha256/<digest>
Expected behavior
A sandboxed app that has the Apple Container service Mach lookup exceptions
should be able to read local image config through the Swift framework/API
surface, or that API should expose a sandbox-safe way to retrieve image config
metadata without requiring the client process to directly open Apple Container
blob-store files.
Environment
- OS: 26.5 (25F71)
- Xcode: 26.4 (17E192)
- Swift: Apple Swift version 6.3 (swiftlang-6.3.0.123.5 clang-2100.0.123.102)
Relevant log output
Error Domain=NSCocoaErrorDomain Code=513
"You don't have permission to save the file "<digest>" in the folder "sha256"."
NSFilePath=/Users/<user>/Library/Application Support/com.apple.container/content/blobs/sha256/<digest>
NSUnderlyingError=... Code=1 "Operation not permitted"
Code of Conduct
I have done the following
Steps to reproduce
Calling the Swift framework/API path
ClientImage.config(for:)succeeds froman unsandboxed SwiftPM executable, but fails from a sandboxed
.appbundlesigned with the Apple Container service Mach lookup temporary exceptions.
The repro is a minimal SwiftPM executable. It:
ClientImage.list().docker.io/library/alpine:latestfrom the returned local image list.ClientImage.config(for: Platform.current).Relevant code:
Sandbox entitlements used for the
.appbundle (ImageConfigSandboxRepro.entitlements):Info.plist used for the
.appbundle:Pull the test image. This is the only
containerCLI step; the repro itselfuses the Swift framework/API packages:
Run the unsandboxed control:
Build, wrap, sign, and run the sandboxed app bundle:
Current behavior
The unsandboxed run succeeds:
The sandboxed app-bundle run fails:
The failure happens after
ClientImage.list()succeeds and after the localimage has been selected through the framework/API. The failing call appears to
attempt direct access from the sandboxed client process to Apple Container's
content blob store:
Expected behavior
A sandboxed app that has the Apple Container service Mach lookup exceptions
should be able to read local image config through the Swift framework/API
surface, or that API should expose a sandbox-safe way to retrieve image config
metadata without requiring the client process to directly open Apple Container
blob-store files.
Environment
Relevant log output
Code of Conduct