Archon icon indicating copy to clipboard operation
Archon copied to clipboard

Self hosted Supabase - support self signed certification connection

Open Brightones opened this issue 3 months ago • 9 comments

Archon Version

v0.1.0

Bug Severity

🔴 Critical - App unusable

Bug Description

I cant get anchor-server to connect to self hosted supabase with self signed certificate.

Steps to Reproduce

Self hosted supabase on docker with self signed certificate

Update .env with supabase URL and API

Run docker compose up -d from anchor git folder

Expected Behavior

anchor-server container to start successfully

Actual Behavior

anchor-server fail to start - log attached

docker-log.txt

Error Details (if any)

2025-09-05 21:35:02.553 | INFO:     Will watch for changes in these directories: ['/app']
2025-09-05 21:35:02.553 | INFO:     Uvicorn running on http://0.0.0.0:8181 (Press CTRL+C to quit)
2025-09-05 21:35:02.553 | INFO:     Started reloader process [1] using WatchFiles
2025-09-05 21:35:13.397 | INFO:     Started server process [8]
2025-09-05 21:35:13.397 | INFO:     Waiting for application startup.
2025-09-05 21:35:13.519 | Error loading credentials: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1010)
2025-09-05 21:35:13.519 | ❌ Failed to start backend: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1010)
2025-09-05 21:35:13.523 | ERROR:    Traceback (most recent call last):
2025-09-05 21:35:13.523 |   File "/venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 101, in map_httpcore_exceptions
2025-09-05 21:35:13.523 |     yield
2025-09-05 21:35:13.523 |   File "/venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 250, in handle_request
2025-09-05 21:35:13.524 |     resp = self._pool.handle_request(req)
2025-09-05 21:35:13.524 |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpcore/_sync/connection_pool.py", line 256, in handle_request
2025-09-05 21:35:13.524 |     raise exc from None
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpcore/_sync/connection_pool.py", line 236, in handle_request
2025-09-05 21:35:13.524 |     response = connection.handle_request(
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpcore/_sync/connection.py", line 101, in handle_request
2025-09-05 21:35:13.524 |     raise exc
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpcore/_sync/connection.py", line 78, in handle_request
2025-09-05 21:35:13.524 |     stream = self._connect(request)
2025-09-05 21:35:13.524 |              ^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpcore/_sync/connection.py", line 156, in _connect
2025-09-05 21:35:13.524 |     stream = stream.start_tls(**kwargs)
2025-09-05 21:35:13.524 |              ^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpcore/_backends/sync.py", line 154, in start_tls
2025-09-05 21:35:13.524 |     with map_exceptions(exc_map):
2025-09-05 21:35:13.524 |          ^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/usr/local/lib/python3.12/contextlib.py", line 158, in __exit__
2025-09-05 21:35:13.524 |     self.gen.throw(value)
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpcore/_exceptions.py", line 14, in map_exceptions
2025-09-05 21:35:13.524 |     raise to_exc(exc) from exc
2025-09-05 21:35:13.524 | httpcore.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1010)
2025-09-05 21:35:13.524 | 
2025-09-05 21:35:13.524 | The above exception was the direct cause of the following exception:
2025-09-05 21:35:13.524 | 
2025-09-05 21:35:13.524 | Traceback (most recent call last):
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/starlette/routing.py", line 694, in lifespan
2025-09-05 21:35:13.524 |     async with self.lifespan_context(app) as maybe_state:
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
2025-09-05 21:35:13.524 |     return await anext(self.gen)
2025-09-05 21:35:13.524 |            ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/fastapi/routing.py", line 134, in merged_lifespan
2025-09-05 21:35:13.524 |     async with original_context(app) as maybe_original_state:
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
2025-09-05 21:35:13.524 |     return await anext(self.gen)
2025-09-05 21:35:13.524 |            ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/fastapi/routing.py", line 134, in merged_lifespan
2025-09-05 21:35:13.524 |     async with original_context(app) as maybe_original_state:
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
2025-09-05 21:35:13.524 |     return await anext(self.gen)
2025-09-05 21:35:13.524 |            ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/fastapi/routing.py", line 134, in merged_lifespan
2025-09-05 21:35:13.524 |     async with original_context(app) as maybe_original_state:
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
2025-09-05 21:35:13.524 |     return await anext(self.gen)
2025-09-05 21:35:13.524 |            ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/fastapi/routing.py", line 134, in merged_lifespan
2025-09-05 21:35:13.524 |     async with original_context(app) as maybe_original_state:
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
2025-09-05 21:35:13.524 |     return await anext(self.gen)
2025-09-05 21:35:13.524 |            ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/fastapi/routing.py", line 134, in merged_lifespan
2025-09-05 21:35:13.524 |     async with original_context(app) as maybe_original_state:
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
2025-09-05 21:35:13.524 |     return await anext(self.gen)
2025-09-05 21:35:13.524 |            ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/fastapi/routing.py", line 134, in merged_lifespan
2025-09-05 21:35:13.524 |     async with original_context(app) as maybe_original_state:
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
2025-09-05 21:35:13.524 |     return await anext(self.gen)
2025-09-05 21:35:13.524 |            ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/fastapi/routing.py", line 134, in merged_lifespan
2025-09-05 21:35:13.524 |     async with original_context(app) as maybe_original_state:
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
2025-09-05 21:35:13.524 |     return await anext(self.gen)
2025-09-05 21:35:13.524 |            ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/fastapi/routing.py", line 134, in merged_lifespan
2025-09-05 21:35:13.524 |     async with original_context(app) as maybe_original_state:
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/usr/local/lib/python3.12/contextlib.py", line 210, in __aenter__
2025-09-05 21:35:13.524 |     return await anext(self.gen)
2025-09-05 21:35:13.524 |            ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/app/src/server/main.py", line 80, in lifespan
2025-09-05 21:35:13.524 |     await initialize_credentials()
2025-09-05 21:35:13.524 |   File "/app/src/server/services/credential_service.py", line 496, in initialize_credentials
2025-09-05 21:35:13.524 |     await credential_service.load_all_credentials()
2025-09-05 21:35:13.524 |   File "/app/src/server/services/credential_service.py", line 130, in load_all_credentials
2025-09-05 21:35:13.524 |     result = supabase.table("archon_settings").select("*").execute()
2025-09-05 21:35:13.524 |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/postgrest/_sync/request_builder.py", line 57, in execute
2025-09-05 21:35:13.524 |     r = self.session.request(
2025-09-05 21:35:13.524 |         ^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpx/_client.py", line 825, in request
2025-09-05 21:35:13.524 |     return self.send(request, auth=auth, follow_redirects=follow_redirects)
2025-09-05 21:35:13.524 |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpx/_client.py", line 914, in send
2025-09-05 21:35:13.524 |     response = self._send_handling_auth(
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpx/_client.py", line 942, in _send_handling_auth
2025-09-05 21:35:13.524 |     response = self._send_handling_redirects(
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpx/_client.py", line 979, in _send_handling_redirects
2025-09-05 21:35:13.524 |     response = self._send_single_request(request)
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpx/_client.py", line 1014, in _send_single_request
2025-09-05 21:35:13.524 |     response = transport.handle_request(request)
2025-09-05 21:35:13.524 |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 249, in handle_request
2025-09-05 21:35:13.524 |     with map_httpcore_exceptions():
2025-09-05 21:35:13.524 |          ^^^^^^^^^^^^^^^^^^^^^^^^^
2025-09-05 21:35:13.524 |   File "/usr/local/lib/python3.12/contextlib.py", line 158, in __exit__
2025-09-05 21:35:13.524 |     self.gen.throw(value)
2025-09-05 21:35:13.524 |   File "/venv/lib/python3.12/site-packages/httpx/_transports/default.py", line 118, in map_httpcore_exceptions
2025-09-05 21:35:13.524 |     raise mapped_exc(message) from exc
2025-09-05 21:35:13.524 | httpx.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1010)
2025-09-05 21:35:13.524 | 
2025-09-05 21:35:13.524 | ERROR:    Application startup failed. Exiting.

Affected Component

🐳 Docker / Infrastructure

Browser & OS

Windows 11 / Docker

Additional Context

No response

Service Status (check all that are working)

  • [ ] 🖥️ Frontend UI (http://localhost:3737)
  • [ ] ⚙️ Main Server (http://localhost:8181)
  • [ ] 🔗 MCP Service (localhost:8051)
  • [ ] 🤖 Agents Service (http://localhost:8052)
  • [ ] 💾 Supabase Database (connected)

Brightones avatar Sep 05 '25 13:09 Brightones

Hi, self-signed SSL certs / HTTPS is not supported at the moment but will come in the future, so this is not a BUG. Its a missing feature.

Here some more details (attachments). @coleam00 leave it on you to create a proper feature request if you like :)

cloud-vs-selfhosted-ssl-analysis.md ssl-certificate-issue-analysis.md

leex279 avatar Sep 06 '25 11:09 leex279

I'll update this and turn it into a feature request! @leex279

coleam00 avatar Sep 06 '25 18:09 coleam00

Thanks Leex279, top knot work. do we have any guideline how to join the team to work on issue or feature ?

Brightones avatar Sep 10 '25 01:09 Brightones

@Brightones you can find the contribution guidelines here: https://github.com/coleam00/Archon/blob/main/CONTRIBUTING.md

Feel free to create a PR to fix this.

leex279 avatar Sep 10 '25 05:09 leex279

hi @coleam00 @leex279 , do we have a workaround on this?

kennyth01 avatar Sep 17 '25 07:09 kennyth01

hi @coleam00 @leex279 , do we have a workaround on this?

Won't a cloudflared tunnel be a valid workaround? cloudflare CAs are trusted on all hosts, no?

leoric-crown avatar Sep 25 '25 20:09 leoric-crown

I think it must not be called a workaround to use cloudflare or also in your internal network just an reverse proxy like nginx, caddy etc. to manage the certs and connection. I think it is more best practice as building it into the webapp directly. At least in my view.

leex279 avatar Sep 25 '25 20:09 leex279

Ah I thought you were running supabase on an external host. Yes, Caddy would be a workaround in a local-only context.

And yes, it's a workaround, not a solution.

leoric-crown avatar Sep 25 '25 21:09 leoric-crown

hi @coleam00 i think i have this enhancement fixed,,

FIX for 2025-09-05 21:35:13.519 | Error loading credentials: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1010) 2025-09-05 21:35:13.519 | ❌ Failed to start backend: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1010)

##I have not tested if this messes with the cloud service, I am using coles local ai package with Archon.

Step 1: Connect Docker Networks

Archon and Supabase need to share a Docker network to communicate.

File: /archon/docker-compose.yml

Add the external network and connect all services:

services:
  archon-server:
    # ... existing config ...
    networks:
      - app-network
      - localai_default  # ADD THIS LINE

  archon-mcp:
    # ... existing config ...
    networks:
      - app-network
      - localai_default  # ADD THIS LINE

  archon-agents:
    # ... existing config ...
    networks:
      - app-network
      - localai_default  # ADD THIS LINE

  archon-frontend:
    # ... existing config ...
    networks:
      - app-network
      - localai_default  # ADD THIS LINE

# At the bottom of the file:
networks:
  app-network:
    driver: bridge
  localai_default:      # ADD THIS SECTION
    external: true

Step 2: Update Archon Supabase URL

Archon needs to connect to Supabase using the Docker service name, not host.docker.internal.

File: /archon/.env

Change:

SUPABASE_URL=http://host.docker.internal:8000

To:

SUPABASE_URL=http://kong:8000

Step 3: Allow HTTP for Kong Hostname

Archon's security config requires HTTPS for non-localhost URLs. We need to whitelist "kong".

File: /archon/python/src/server/config/config.py

Find line ~110 and modify:

# Check for exact localhost and Docker internal hosts (security: prevent subdomain bypass)
# Added 'kong' for local Supabase docker container
local_hosts = ["localhost", "127.0.0.1", "host.docker.internal", "kong"]  # ADD "kong" HERE
if hostname in local_hosts or hostname.endswith(".localhost"):
    return True

Step 4: Restart Services

Start Supabase first, then Archon:

# Start Supabase (from local-ai-packaged directory)
cd /path/to/local-ai-packaged
python start_services.py --profile cpu

# Wait for all services to be healthy (~30-60 seconds)
docker compose -p localai ps

# Start Archon (from archon directory)
cd /path/to/archon
docker compose up -d --build

Hidden-History avatar Nov 09 '25 15:11 Hidden-History