diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0a8830f..9cef5e8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,10 @@ on: pull_request: branches: [ main ] +# 🔐 Lock down GITHUB_TOKEN for this workflow +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest @@ -31,4 +35,3 @@ jobs: - name: Build TypeScript monorepo run: npm run build - diff --git a/.github/workflows/conformance.yml b/.github/workflows/conformance.yml index 4bfe993..ec1324a 100644 --- a/.github/workflows/conformance.yml +++ b/.github/workflows/conformance.yml @@ -1,5 +1,11 @@ name: Conformance + on: [push, pull_request] + +# 🔐 Restrict GITHUB_TOKEN permissions (least privilege) +permissions: + contents: read + jobs: test: runs-on: ubuntu-latest diff --git a/packages/proxyabl/src/tool-gateway.ts b/packages/proxyabl/src/tool-gateway.ts index 17be517..84cf1ae 100644 --- a/packages/proxyabl/src/tool-gateway.ts +++ b/packages/proxyabl/src/tool-gateway.ts @@ -117,18 +117,20 @@ const TOOL_SCOPES: Record = parseToolScopesEnv(); // Union of all tool scopes (what the client should actually request) const REQUIRED_SCOPES = Array.from(new Set(Object.values(TOOL_SCOPES).flat())); -// ---- Safe logging helpers (no secrets printed) ---- +// ---- Safe logging helpers (only state, no raw values) ---- function logCfg() { console.log("[cfg]", { - OAUTH_ISSUER, + OAUTH_ISSUER: OAUTH_ISSUER ? "[configured]" : "[default]", OAUTH_AUDIENCE: OAUTH_AUDIENCE ? "[set]" : null, JWKS_URI_FALLBACK: JWKS_URI_FALLBACK ? "[set]" : null, - FUNCTIONS_BASE, - APP_ORIGIN, + FUNCTIONS_BASE: FUNCTIONS_BASE ? "[set]" : null, + APP_ORIGIN: APP_ORIGIN === "*" ? "*" : "[set]", }); } logCfg(); +logCfg(); + function readAuth(req: Request) { const auth = req.header("authorization") || ""; const hasAuth = auth.startsWith("Bearer "); @@ -596,16 +598,21 @@ export async function wellKnownOauthProtectedResource(req: Request, res: Respons const xfHost = req.get("x-forwarded-host") || req.get("host") || ""; const fullUrl = `${xfProto}://${xfHost}${req.originalUrl || req.url}`; + const pathOnly = (req.originalUrl || req.url || "").split("?")[0]; + console.log("[wk] /.well-known/oauth-protected-resource served", { - url: fullUrl, method: req.method, ua, origin, referer, + path: pathOnly, + method: req.method, }); + console.log("[wk.cfg]", { - issuer: OAUTH_ISSUER, + issuer: OAUTH_ISSUER ? "[configured]" : "[default]", audience: OAUTH_AUDIENCE ? "[set]" : null, jwks_uri_fallback: JWKS_URI_FALLBACK ? "[set]" : null, - required_scopes: REQUIRED_SCOPES, + required_scopes_count: REQUIRED_SCOPES.length, }); + try { const d = await fetchJsonWithRetry(`${OAUTH_ISSUER}/.well-known/openid-configuration`); @@ -1323,4 +1330,3 @@ toolGatewayRouter.options("/mcp", mcpLimiter as any, toolGatewayImpl); // Auth0 Log Stream webhook (DCR auto-fix, rate limited too) toolGatewayRouter.post("/auth0/logs", webhookLimiter as any, auth0LogWebhook); -