[object Object]

← back to Butlr

owner-auth: accept token via X-Butlr-Owner-Token header + Bearer

89f34408f5b278a4ae84d206d229ee93672c848b · 2026-05-14 08:46:53 -0700 · SteveStudio2

tokenFromReq() already accepted the cookie and ?owner_token= query.
The /butlr Claude Code skill needs to POST /api/quick-dial without
the token landing in URL/nginx logs. Adding two header transports:
  - X-Butlr-Owner-Token (explicit)
  - Authorization: Bearer <token> (standard)
Fallback chain stays: cookie → query → header → bearer.

Coupling: the /butlr skill prefers the header path now and falls
back to ?owner_token= only when the server returns 401 (pre-deploy
of this commit). Existing browser cookies + the legacy /login?t=
fast-path are unaffected.

Files touched

Diff

commit 89f34408f5b278a4ae84d206d229ee93672c848b
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Thu May 14 08:46:53 2026 -0700

    owner-auth: accept token via X-Butlr-Owner-Token header + Bearer
    
    tokenFromReq() already accepted the cookie and ?owner_token= query.
    The /butlr Claude Code skill needs to POST /api/quick-dial without
    the token landing in URL/nginx logs. Adding two header transports:
      - X-Butlr-Owner-Token (explicit)
      - Authorization: Bearer <token> (standard)
    Fallback chain stays: cookie → query → header → bearer.
    
    Coupling: the /butlr skill prefers the header path now and falls
    back to ?owner_token= only when the server returns 401 (pre-deploy
    of this commit). Existing browser cookies + the legacy /login?t=
    fast-path are unaffected.
---
 lib/owner-auth.js | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/lib/owner-auth.js b/lib/owner-auth.js
index fa8173d..7cd885f 100644
--- a/lib/owner-auth.js
+++ b/lib/owner-auth.js
@@ -29,7 +29,14 @@ function parseCookies(req) {
 function tokenFromReq(req) {
   const fromCookie = parseCookies(req)[COOKIE_NAME];
   const fromQuery  = req.query && req.query.owner_token;
-  return fromCookie || fromQuery || '';
+  // Header transport — used by the /butlr Claude Code skill so the token
+  // never lands in URL logs. Accepts either an explicit header or the
+  // standard `Authorization: Bearer <token>` form.
+  const hdrExplicit = (req.headers && (req.headers['x-butlr-owner-token'] || req.headers['x-owner-token'])) || '';
+  let hdrBearer = '';
+  const auth = (req.headers && req.headers.authorization) || '';
+  if (auth.toLowerCase().startsWith('bearer ')) hdrBearer = auth.slice(7).trim();
+  return fromCookie || fromQuery || hdrExplicit || hdrBearer || '';
 }
 
 function lookupUser(req) {

← 0c6e41e Permissions-Policy: allow geolocation=(self) on wizard /new  ·  back to Butlr  ·  Add /api/runtime-config — surfaces DRY_RUN state for the /bu 25f76be →