Skip to content

Repository files navigation

FileNest for macOS

FileNest for macOS is the first native client for FileNest Server, an open-source, self-hosted file storage system. It exposes files held by a FileNest Server in Finder using Apple's replicated File Provider architecture. Files begin as remote placeholders and are downloaded only when macOS asks to materialize them.

Experimental: This is an initial, read-only proof of concept. Keep independent backups. It is intended for development against a trusted local network and is not ready for secure Internet deployment.

Current status

This version can:

  • store a server URL in the shared app-group preferences and a bearer token in a shared Keychain access group;
  • test /api/v1/health and authenticated /api/v1/server responses;
  • register one stable File Provider domain with macOS;
  • enumerate root and nested folders from /api/v1/items?parent_id=...;
  • expose file names, types, sizes, dates, and revisions to Finder;
  • download a remote file from /api/v1/items/{id}/content into the File Provider temporary volume when Finder opens it; and
  • reject create, modify, move, rename, and delete requests as unsupported.

It implements FileNest protocol v0, whose numeric protocol_version is 1. The authoritative contract is FileNest Server's protocol-v0.md. No upload, delete, rename, sharing, account, or change-feed endpoints exist in that protocol.

Architecture

Finder
  │
File Provider (NSFileProviderReplicatedExtension)
  │
FileNest macOS client
  │ HTTPS/HTTP during development
FileNest Server
  │
SSD/HDD

The implementation has four layers:

  • FileNestApp is the small SwiftUI setup and diagnostics app.
  • FileNestCore owns typed protocol models, configuration, Keychain access, and URLSession networking.
  • FileNestProvider contains testable identifier, metadata, enumeration, and File Provider error mapping logic.
  • FileNestFileProvider is the thin replicated extension entry point that handles metadata requests, hydration, and read-only mutation failures.

macOS owns and manages materialized local copies. The extension never mounts a custom filesystem and does not use FUSE, a kernel extension, or Finder configuration hacks.

Requirements

  • macOS 14 Sonoma or newer for development with Xcode 16 (the app itself has a macOS 13 deployment target)
  • Xcode 16 or newer with the macOS SDK and Swift Testing installed
  • an Apple development team capable of signing a macOS app, File Provider extension, App Group, and shared Keychain group
  • a running FileNest Server built with Go 1.24 or newer

There are no third-party package dependencies. Package.swift exists so the shared production modules and unit tests can also be built independently of the app project.

Run FileNest Server

From the filenest/server repository, choose a data directory and generate a token of at least 32 random bytes:

export FILENEST_DATA_DIR="$HOME/FileNestData"
export FILENEST_LISTEN_ADDR="127.0.0.1:8080"
export FILENEST_TOKEN="$(openssl rand -hex 32)"

go run ./cmd/filenest

For a different Mac on the trusted LAN to connect, bind the server to a reachable LAN interface, for example 0.0.0.0:8080, and allow the port through the host firewall. This exposes the plain HTTP token and content to anyone able to observe that network. Do not expose this prototype directly to the Internet.

Verify the server locally:

curl http://127.0.0.1:8080/api/v1/health
curl -H "Authorization: Bearer $FILENEST_TOKEN" \
  http://127.0.0.1:8080/api/v1/server

Required Xcode and signing setup

The checked-in identifiers are development defaults:

Target/resource Identifier
App bundle uk.filenest.macos
Extension bundle uk.filenest.macos.FileProvider
File Provider domain uk.filenest.primary
App Group group.uk.filenest.shared
Shared Keychain group suffix uk.filenest.shared

Before running:

  1. Open FileNest.xcodeproj.
  2. Select your development team for the FileNest and FileNestFileProvider targets and leave automatic signing enabled.
  3. If the checked-in bundle IDs are unavailable to your team, replace both bundle identifiers with unique values.
  4. Register an App Group for your team. If you replace group.uk.filenest.shared, change it consistently in:
    • FileNestApp/FileNestApp.entitlements
    • FileNestFileProvider/FileNestFileProvider.entitlements
    • FileNestFileProvider/Info.plist
    • ConfigurationStore.appGroupIdentifier
  5. Enable App Groups for both signable targets with the same group.
  6. Enable Keychain Sharing for both signable targets with the same uk.filenest.shared suffix. Xcode expands $(AppIdentifierPrefix) to the signing team prefix.
  7. Keep App Sandbox and outgoing network connections enabled for both targets.

The committed entitlements declare these capabilities, but the matching identifiers and provisioning profiles must exist in the selected Apple developer team. A free Personal Team may not provision every required capability. The app does not claim that domain registration succeeded when signing or entitlements are missing.

Run the macOS client

  1. Select the shared FileNest scheme and the My Mac destination.
  2. Build and run the app.
  3. Enter the server origin, such as http://127.0.0.1:8080 or http://192.168.1.10:8080. A reverse-proxy base path is also preserved if supplied.
  4. Enter the value of FILENEST_TOKEN.
  5. Choose Test Connection. The app checks health, authentication, protocol version, and the required read capability.
  6. Choose Enable FileNest in Finder. The app tests the connection again before registering the stable domain.
  7. Open Finder and select FileNest under Locations. Browse a folder, then open a file to trigger its download and local materialization.

The token is stored as a generic password in Keychain and is never written to UserDefaults or application logs. The URL is stored in the shared App Group preferences so the host app and extension use the same configuration.

Testing

In Xcode, select Product → Test or run:

xcodebuild test \
  -project FileNest.xcodeproj \
  -scheme FileNest \
  -destination 'platform=macOS'

With a complete command-line Swift/Swift Testing installation, the shared suite can also run with:

swift test

Tests use a custom URLProtocol; they do not require a Raspberry Pi or a live FileNest Server. Coverage includes JSON decoding, RFC 3339 dates, URL and opaque-ID encoding, authentication headers, streamed download placement, structured API errors, configuration separation, Apple root identifier mapping, File Provider metadata, read-only capabilities, and File Provider error translation.

Security

The initial server supports plain HTTP for local development, so the app allows user-configured HTTP origins. Plain HTTP provides no confidentiality for bearer tokens or file contents. Use it only on a trusted network. TLS certificates continue to receive normal system validation; the client does not install a permissive trust delegate or bypass certificate checks.

Secure remote Internet access, device pairing, scoped credentials, and certificate management are not provided by this prototype.

Known limitations

  • Protocol v0 and this client are read-only. Finder mutations are denied and never reported as successful.
  • The server advertises changes: false; there is no change feed, background polling, or push notification. The working set is intentionally empty and exposes a stable no-change anchor. Finder refreshes directory listings when it enumerates them, but remote changes may not appear immediately in already cached views.
  • A server-side move or rename changes the item's ID in protocol v0.
  • Downloads fetch the whole file. The server's Range support is not yet used for partial File Provider materialization.
  • There is one fixed domain, one server, and one bearer token.
  • Offline metadata caching, uploads, conflicts, thumbnails, sharing, version history, installers, and auto-update are out of scope.
  • Finder integration cannot be exercised without a correctly signed extension and registered App Group.
  • HTTP is permitted for development; secure production deployment is not supported.

Troubleshooting

“Authentication failed”

Confirm the token exactly matches FILENEST_TOKEN. Tokens never belong in the server URL. If the app and extension behave differently, verify that both targets have the identical Keychain Sharing group and signing team.

“Server unreachable”

Open /api/v1/health from the same Mac. For LAN use, ensure the server is not bound only to 127.0.0.1, check the firewall, and use the server's reachable IP address.

“Protocol unsupported”

This client accepts only numeric protocol version 1 and requires capabilities.read == true. Update either component instead of adding undocumented endpoints or compatibility guesses.

The Enable button fails or FileNest is absent from Finder

Check signing for both app and extension, confirm the extension is embedded in FileNest.app/Contents/PlugIns, and verify that the App Group exists for the selected team. You can inspect registered extensions without changing system state:

pluginkit -m -A -D | grep uk.filenest.macos

After changing bundle IDs or entitlements, clean the Xcode build folder, delete the old development app, rebuild, and register the domain again. macOS may retain a domain associated with the old extension identity until that development app is removed.

A remote change is not visible

Navigate away and reopen the folder. Protocol v0 has no server change feed, so immediate invalidation of cached Finder metadata is not possible without extending the shared server protocol first.

Repository tree

.
├── FileNest.xcodeproj/            # app, extension, libraries, tests, shared scheme
├── FileNestApp/                   # SwiftUI configuration application
├── FileNestCore/                  # protocol models, API client, Keychain/configuration
├── FileNestFileProvider/          # replicated extension and provider support
├── FileNestTests/                 # mocked-network and mapping unit tests
├── Package.swift                  # standalone shared-module/test build
├── README.md
└── LICENSE

Next commit

  • Add a server change-feed contract before implementing File Provider change enumeration and cache invalidation.
  • Add partial-content hydration using the protocol's Range support.
  • Design authenticated create/modify/delete server APIs, then implement bidirectional sync and conflict handling.
  • Add a domain removal/reconfiguration flow and richer diagnostics.
  • Add app and Finder sidebar artwork.

License

FileNest for macOS is licensed under the GNU General Public License v3.0. See LICENSE.

About

Native FileNest client for macOS with Finder integration using Apple File Provider.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages