Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions src/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ export class RegistryTokens implements Authenticator {
return token;
}

static checkIfV2OnlyPath(request: Request): boolean {
return request.url.endsWith("/v2/");
static checkIfRegistryBasePath(request: Request): boolean {
const pathname = new URL(request.url).pathname;
return pathname === "/" || pathname === "/v2/";
}

static checkIfGarbageCollectionPath(request: Request): boolean {
Expand Down Expand Up @@ -139,20 +140,19 @@ export class RegistryTokens implements Authenticator {
}
break;
// PULL method
case "GET":
if (RegistryTokens.checkIfV2OnlyPath(request)) {
return { verified: true, payload };
case "GET": {
const isRegistryBasePath = RegistryTokens.checkIfRegistryBasePath(request);
if (isRegistryBasePath && payload.capabilities.length === 0) {
console.warn(
"verifyToken: failed jwt verification: missing any capabilities for GET request to registry base path",
);
return { verified: false, payload: null };
}

if (request.url == "https://registry.runpod.net/" || request.url == "https://registry.runpod.net") {
if (isRegistryBasePath) {
return { verified: true, payload };
}

if (RegistryTokens.checkIfV2OnlyPath(request) && payload.capabilities.length === 0) {
console.warn("verifyToken: failed jwt verification: missing any capabilities for GET request in /v2/");
return { verified: false, payload: null };
}

if (!payload.capabilities.includes("pull")) {
console.warn(
`verifyToken: failed jwt verification: missing "pull" capability for ${request.method} HTTP method in ${request.url}`,
Expand All @@ -166,6 +166,7 @@ export class RegistryTokens implements Authenticator {
return { verified: false, payload: null };
}
break;
}

// PUSH methods
case "POST":
Expand Down
24 changes: 24 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,30 @@ describe("tokens", async () => {
expect(verified).toBeTruthy();
});

test("auth payload without capabilities cannot GET registry base paths", async () => {
for (const url of ["https://registry.runpod.net/", "https://registry.com/v2/"]) {
const { verified } = RegistryTokens.verifyPayload(new Request(url), {
username: "test",
capabilities: [],
exp: Math.floor(Date.now() / 1000) + 60,
aud: url,
});
expect(verified).toBeFalsy();
}
});

test("auth payload push can GET the registry root on any host", async () => {
for (const url of ["https://registry.runpod.net/", "https://registry.example/?check=1"]) {
const { verified } = RegistryTokens.verifyPayload(new Request(url), {
username: "test",
capabilities: ["push"],
exp: Math.floor(Date.now() / 1000) + 60,
aud: url,
});
expect(verified).toBeTruthy();
}
});

test("auth payload push on /v2/whatever with HEAD", async () => {
const { verified } = RegistryTokens.verifyPayload(createRequest("HEAD", "/v2/whatever", null), {
capabilities: ["push"],
Expand Down