feat: make metadata/manifest API endpoint publicly accessible without auth #676

Closed
opened 2026-06-21 14:55:17 +00:00 by jmiller · 1 comment
Owner

Summary

The /repos/{owner}/{repo}/metadata (and /manifest) GET endpoint currently requires reqRepoReader authentication. It should be accessible anonymously for public repos, similar to how badges work.

Motivation

  • CI workflows need to read platform type without a token (for platform-conditional logic in pre-release.yml)
  • Package registries need to discover version info
  • Public tooling (MCP servers, CLI) should read metadata without auth
  • Metadata doesn't contain sensitive info — just version, platform, element name, etc.

Current Behavior

m.Combo("/metadata", reqRepoReader(unit.TypeCode)).
    Get(repo.GetRepoMetadata).
    Put(reqToken(), reqAdmin(), repo.UpdateRepoMetadata)

Anonymous GET to /api/v1/repos/{owner}/{repo}/metadata returns 403 even for public repos.

Desired Behavior

  • GET /metadata and /manifest: No auth required for public repos (anonymous access)
  • PUT /metadata and /manifest: Still requires token + admin (unchanged)

Implementation

In routers/api/v1/api.go ~line 1483, change from Combo to separate routes:

m.Get("/metadata", repo.GetRepoMetadata)
m.Put("/metadata", reqToken(), reqAdmin(), repo.UpdateRepoMetadata)
m.Get("/manifest", repo.GetRepoMetadata) // backward compat
m.Put("/manifest", reqToken(), reqAdmin(), repo.UpdateRepoMetadata)

This removes reqRepoReader from the GET path. The repo context resolution middleware still handles private vs public repo visibility at a higher level.

## Summary The `/repos/{owner}/{repo}/metadata` (and `/manifest`) GET endpoint currently requires `reqRepoReader` authentication. It should be accessible anonymously for public repos, similar to how badges work. ## Motivation - CI workflows need to read platform type without a token (for platform-conditional logic in pre-release.yml) - Package registries need to discover version info - Public tooling (MCP servers, CLI) should read metadata without auth - Metadata doesn't contain sensitive info — just version, platform, element name, etc. ## Current Behavior ```go m.Combo("/metadata", reqRepoReader(unit.TypeCode)). Get(repo.GetRepoMetadata). Put(reqToken(), reqAdmin(), repo.UpdateRepoMetadata) ``` Anonymous GET to `/api/v1/repos/{owner}/{repo}/metadata` returns 403 even for public repos. ## Desired Behavior - **GET** `/metadata` and `/manifest`: No auth required for public repos (anonymous access) - **PUT** `/metadata` and `/manifest`: Still requires token + admin (unchanged) ## Implementation In `routers/api/v1/api.go` ~line 1483, change from `Combo` to separate routes: ```go m.Get("/metadata", repo.GetRepoMetadata) m.Put("/metadata", reqToken(), reqAdmin(), repo.UpdateRepoMetadata) m.Get("/manifest", repo.GetRepoMetadata) // backward compat m.Put("/manifest", reqToken(), reqAdmin(), repo.UpdateRepoMetadata) ``` This removes `reqRepoReader` from the GET path. The repo context resolution middleware still handles private vs public repo visibility at a higher level.
Author
Owner

Testing Checklist

Automated (PASS)

  • GET /metadata no auth — returns JSON
  • /manifest backward compat — returns JSON
  • Private repo metadata returns 404 for unauth
  • PUT without token returns 401

Manual UI

  • Visit any repo → Settings → Metadata → page loads without 500 error
  • Version input field is gone (was causing the crash)
  • All other metadata fields (name, org, platform, license) editable
  • Save metadata → changes persist
## Testing Checklist ### Automated (PASS) - [x] `GET /metadata` no auth — returns JSON - [x] `/manifest` backward compat — returns JSON - [x] Private repo metadata returns 404 for unauth - [x] PUT without token returns 401 ### Manual UI - [ ] Visit any repo → Settings → Metadata → page loads without 500 error - [ ] Version input field is gone (was causing the crash) - [ ] All other metadata fields (name, org, platform, license) editable - [ ] Save metadata → changes persist
Sign in to join this conversation.