···11+description: Add artifact_type column to manifests table for Helm chart support
22+query: |
33+ -- Add artifact_type column to track manifest types (container-image, helm-chart, unknown)
44+ -- Default to container-image for existing manifests
55+ ALTER TABLE manifests ADD COLUMN artifact_type TEXT NOT NULL DEFAULT 'container-image';
66+77+ -- Add index for filtering by artifact type
88+ CREATE INDEX IF NOT EXISTS idx_manifests_artifact_type ON manifests(artifact_type);
+8-6
pkg/hold/oci/xrpc.go
···254254 return
255255 }
256256257257- // Verify user DID matches token
258258- if req.UserDID != validatedUser.DID {
259259- RespondError(w, http.StatusForbidden, "user DID mismatch")
260260- return
261261- }
262262-263257 // Default operation to "push" for backward compatibility
264258 operation := req.Operation
265259 if operation == "" {
···269263 // Validate operation
270264 if operation != "push" && operation != "pull" {
271265 RespondError(w, http.StatusBadRequest, fmt.Sprintf("invalid operation: %s (must be 'push' or 'pull')", operation))
266266+ return
267267+ }
268268+269269+ // Verify user DID matches token - only for pushes
270270+ // For pulls: userDID is the repo owner (for stats), but the token belongs to the puller
271271+ // This allows anyone to pull from a public repo and have stats tracked under the owner
272272+ if operation == "push" && req.UserDID != validatedUser.DID {
273273+ RespondError(w, http.StatusForbidden, "user DID mismatch")
272274 return
273275 }
274276