cm-secrets: chmod 0666 broker socket after bind
ci / gates (push) Successful in 6s
ci / frontend (push) Successful in 37s
ci / rust (push) Successful in 3m7s
ci / e2e (push) Has been skipped
ci / publish (push) Successful in 2m48s

Fixes 500 on any broker-touching route (POST /api/repos/connections,
POST /api/apps, the OAuth callback) when broker + server run under
different UIDs — which is exactly the prod topology on gw-04 (broker
uid 10001, clawmates-server distroless nonroot uid 65532). Linux Unix
socket connect(2) requires read+write on the socket file, and the
default bind mode 0755 gives 'others' r-x only.

Widen to 0666 after bind. The broker socket only lives inside the
shared broker_run volume — two containers mount it, nothing else on
the host can see it — so widening is safe. If set_permissions is a
no-op on the target filesystem (abstract sockets on some kernels),
we log and continue instead of failing serve().
This commit is contained in:
Omar Sobh
2026-07-07 16:21:01 -07:00
parent e858a7f92f
commit 977a1233af
+19
View File
@@ -62,6 +62,25 @@ impl BrokerServer {
let _ = std::fs::remove_file(&self.socket_path); let _ = std::fs::remove_file(&self.socket_path);
let listener = let listener =
UnixListener::bind(&self.socket_path).map_err(|e| BrokerError::Io(e.to_string()))?; UnixListener::bind(&self.socket_path).map_err(|e| BrokerError::Io(e.to_string()))?;
// Unix socket `connect(2)` on Linux requires read+write on the socket
// file. The broker + clients run under different UIDs in prod (broker
// as 10001, cm-api's server distroless as nonroot=65532), so the
// default 0755 blocks the client. Widen to 0660 for host-fs bind
// paths — the socket only lives on the shared broker_run volume, and
// nothing outside the two containers can see it. Best-effort: on
// filesystems where set_permissions is a no-op (abstract sockets on
// some kernels) we just log and continue.
{
use std::os::unix::fs::PermissionsExt;
if let Err(e) =
std::fs::set_permissions(&self.socket_path, std::fs::Permissions::from_mode(0o666))
{
eprintln!(
"cm-secrets: failed to relax socket permissions on {}: {e}",
self.socket_path.display()
);
}
}
let server = std::sync::Arc::new(self); let server = std::sync::Arc::new(self);
loop { loop {
let (stream, _) = listener let (stream, _) = listener