Skip to content

fix(providers): allow plain-HTTP custom endpoints blocked by ATS (#499)#505

Open
devzahirul wants to merge 2 commits into
altic-dev:mainfrom
devzahirul:fix/499-custom-provider-http
Open

fix(providers): allow plain-HTTP custom endpoints blocked by ATS (#499)#505
devzahirul wants to merge 2 commits into
altic-dev:mainfrom
devzahirul:fix/499-custom-provider-http

Conversation

@devzahirul

Copy link
Copy Markdown

Summary

Fixes #499. Custom providers pointed at a plain-HTTP endpoint — e.g. the reporter's http://mars-main.box:8317/v1, or local LLM proxies like cliproxyapi/new-api that have no TLS cert — fail every request (model refresh, verification, enhancement) with:

Network error: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection. (Error code: -1022)

Root cause

The app bundle had no NSAppTransportSecurity configuration, so macOS applies the default ATS policy: cleartext HTTP is blocked at the CFNetwork layer for every host except loopback. The provider form itself accepts http:// URLs (saveNewProvider only checks for non-empty), so users could configure an endpoint that could never work, and the failure only surfaced later as error -1022.

Why NSAllowsArbitraryLoads

  • NSExceptionDomains requires the hosts to be known at build time; custom provider hosts are user-configured at runtime.
  • NSAllowsLocalNetworking only exempts local-network names (single-label, .local); it does not cover multi-label private DNS names like the reporter's mars-main.box, nor self-hosted proxies reached across networks.

So a global allowance is the only mechanism that actually covers the reported setups. Every endpoint the app itself ships with (model downloads, updater, analytics) remains HTTPS — this change only permits endpoints the user explicitly configures.

Keeping the choice informed

Both custom provider forms (add and edit) now show a warning under the Base URL field when it is plain HTTP to a non-loopback host:

⚠️ Unencrypted HTTP endpoint — prompts, transcripts, and the API key are sent as plain text. Use only on networks you trust.

Classification lives in ModelRepository.isInsecureRemoteEndpoint: loopback (localhost/127.x/::1) is exempt since that traffic never leaves the machine; other LAN hosts are not, since that traffic is observable on the network.

Out of scope

HTTPS endpoints with self-signed/invalid certificates still fail TLS validation — that is certificate trust, not ATS, and would need a separate opt-in trust override if wanted.

Changes

  • Info.plistNSAppTransportSecurityNSAllowsArbitraryLoads, with a comment documenting the rationale.
  • ModelRepositoryisInsecureRemoteEndpoint(_:) helper next to the existing isLocalEndpoint.
  • AISettingsView+AIConfiguration — shared warning row under the Base URL field in the add and edit provider forms.
  • Tests — InsecureEndpointTests covering remote-HTTP flagging (including the reporter's URL shape), loopback exemption, HTTPS, and invalid input.

Testing

  • swiftlint --strict — 0 violations.
  • Full xcodebuild test suite — 57/57 passing.
  • Verified the built app bundle's Info.plist contains the ATS key (plutil -p).

Closes #499

…ic-dev#499)

Custom providers pointed at plain-HTTP endpoints (local LLM proxies such
as cliproxyapi/new-api on LAN hosts) failed every request with
NSURLError -1022 because the app had no App Transport Security
configuration, so macOS blocked all cleartext connections beyond
loopback.

Since custom provider hosts are user-configured at runtime, they cannot
be enumerated as NSExceptionDomains, and NSAllowsLocalNetworking does
not cover multi-label LAN hostnames or remote proxies. Info.plist now
sets NSAllowsArbitraryLoads; all bundled endpoints remain HTTPS. To keep
the choice informed, both custom provider forms show a plaintext-traffic
warning for HTTP endpoints beyond loopback, classified by the new
ModelRepository.isInsecureRemoteEndpoint helper.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a4a3c4b23a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Sources/Fluid/UI/AISettingsView+AIConfiguration.swift
… form too

The editProviderSection shown after a custom provider is verified has
its own base URL field, which was missing the insecure-endpoint warning
added to the details and add forms. All three base URL entry points now
share the same warning row.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[✨ FEATURE] custom provider support http protocol

1 participant