Fix channel gateway Docker networking and console proxy approval scope

Two runtime bugs:

1. Channel gateway advertised http://127.0.0.1:8091 which is
   unreachable from other Docker containers. Add
   TURNSTONE_CHANNEL_ADVERTISE_URL env var override for Docker/K8s
   environments, set to http://channel:8091 in compose.yaml, and
   pass --http-host=0.0.0.0 so the gateway listens on all interfaces.

2. Console proxy service JWT had only "write" scope but the approval
   endpoint requires "approve". Tool approval buttons in the server
   web UI silently failed when accessed through the console proxy.
   Changed proxy token scopes to read+write+approve.
This commit is contained in:
Patrick Buckley
2026-03-05 18:01:47 -08:00
parent fc8ceb4c72
commit d5db817391
3 changed files with 13 additions and 7 deletions
+2
View File
@@ -213,6 +213,7 @@ services:
turnstone-channel
--redis-host=redis
--redis-port=6379
--http-host=0.0.0.0
$${TURNSTONE_DISCORD_GUILD:+--discord-guild $$TURNSTONE_DISCORD_GUILD}
environment:
- TURNSTONE_DISCORD_TOKEN=${TURNSTONE_DISCORD_TOKEN:-}
@@ -221,6 +222,7 @@ services:
- TURNSTONE_JWT_SECRET=${TURNSTONE_JWT_SECRET:-}
- TURNSTONE_DB_BACKEND=${DB_BACKEND:-sqlite}
- TURNSTONE_DB_URL=${DATABASE_URL:-}
- TURNSTONE_CHANNEL_ADVERTISE_URL=http://channel:8091
networks:
- turnstone-net
depends_on:
+10 -6
View File
@@ -181,12 +181,16 @@ def main() -> None:
service_id = _get_service_id()
# Resolve advertise address — 0.0.0.0/:: are not routable
if args.http_host in ("0.0.0.0", "::"):
advertise_host = socket.gethostname()
else:
advertise_host = args.http_host
service_url = f"http://{advertise_host}:{args.http_port}"
# Resolve advertise URL — env override for Docker/K8s,
# otherwise derive from bind address.
advertise_url = os.environ.get("TURNSTONE_CHANNEL_ADVERTISE_URL", "").strip()
if not advertise_url:
if args.http_host in ("0.0.0.0", "::"):
advertise_host = socket.gethostname()
else:
advertise_host = args.http_host
advertise_url = f"http://{advertise_host}:{args.http_port}"
service_url = advertise_url
# Register in service registry
storage.register_service("channel", service_id, service_url)
+1 -1
View File
@@ -1401,7 +1401,7 @@ def main() -> None:
proxy_token_mgr = ServiceTokenManager(
user_id="console-proxy",
scopes=frozenset({"write"}),
scopes=frozenset({"read", "write", "approve"}),
source="console",
secret=jwt_secret,
audience=JWT_AUD_SERVER,