Skip to content

Commit b4057df

Browse files
1stvampTrigger.dev RepoOps
authored andcommitted
fix(observability-map): credit scoped API-key guards in auth-boundary
Fix an under-credit in the observability map's auth-boundary check: it now recognises `authenticateApiKeyWithScope` and its private and scoped siblings as guards. These authenticate the caller from a bearer key and return an `{ ok }` result like the request guards already on the list, so routes using them were being flagged as unguarded for want of the name. No route behaviour changes; only the scanner. Mono-RevId: 7b5a1562ff5aee1f578872216a34531f54736876
1 parent 4f36f61 commit b4057df

2 files changed

Lines changed: 32 additions & 0 deletions

File tree

‎internal-packages/observability-map/src/checks/authBoundary.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ export const GUARDS = new Set([
2828
"authenticateApiRequestWithPersonalAccessToken",
2929
"authenticateApiRequestWithOrganizationAccessToken",
3030
"authenticateApiKey",
31+
// Scoped and private API-key entry points in the same `apiAuth.server.ts`, each returning a
32+
// `{ ok }` result like `authenticateApiRequestWithFailure` above rather than throwing.
33+
"authenticateApiKeyWithScope",
34+
"authenticateApiKeyRequest",
35+
"authenticateRequestWithScopedApiKey",
3136
"authenticateAuthorizationHeader",
3237
"authenticateOrganizationAccessToken",
3338
"authenticatePersonalAccessToken",

‎internal-packages/observability-map/src/checks/index.test.ts‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,33 @@ describe("auth-boundary", () => {
10241024
expect(r.status).toBe("pass");
10251025
});
10261026

1027+
// All three scoped and private API-key helpers on the allowlist, so dropping any one of the names
1028+
// is caught here rather than only by the tree scan.
1029+
it.each([
1030+
[
1031+
"authenticateApiKeyWithScope",
1032+
'authenticateApiKeyWithScope(request, { action: "read", resource: { type: "envvars" } })',
1033+
],
1034+
["authenticateApiKeyRequest", "authenticateApiKeyRequest(request)"],
1035+
[
1036+
"authenticateRequestWithScopedApiKey",
1037+
"authenticateRequestWithScopedApiKey(request, { personalAccessToken: true, organizationAccessToken: true, apiKey })",
1038+
],
1039+
])("passes a sensitive route guarded by %s", (name, call) => {
1040+
const r = run(
1041+
"auth-boundary",
1042+
"api.v1.projects.$projectRef.envvars.ts",
1043+
`import { ${name} } from "~/services/apiAuth.server";
1044+
import { prisma } from "~/db.server";
1045+
export async function loader({ request }) {
1046+
const auth = await ${call};
1047+
if (!auth.ok) throw new Response(null, { status: 401 });
1048+
return prisma.environmentVariable.findMany();
1049+
}`
1050+
);
1051+
expect(r.status).toBe("pass");
1052+
});
1053+
10271054
it("fails a sensitive route with no guard", () => {
10281055
const r = run(
10291056
"auth-boundary",

0 commit comments

Comments
 (0)