A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go
81
fork

Configure Feed

Select the types of activity you want to include in your feed.

try and fix crew membership on push

+12 -2
+9
pkg/appview/middleware/registry.go
··· 170 170 } 171 171 ctx = context.WithValue(ctx, holdDIDKey, holdDID) 172 172 173 + // Auto-reconcile crew membership on first push/pull 174 + // This ensures users can push immediately after docker login without web sign-in 175 + // EnsureCrewMembership is best-effort and logs errors without failing the request 176 + if holdDID != "" && nr.refresher != nil { 177 + fmt.Printf("DEBUG [registry/middleware]: Auto-reconciling crew membership for DID=%s at hold=%s\n", did, holdDID) 178 + client := atproto.NewClient(pdsEndpoint, did, "") 179 + storage.EnsureCrewMembership(ctx, client, nr.refresher, holdDID) 180 + } 181 + 173 182 // Get service token for hold authentication 174 183 var serviceToken string 175 184 if nr.refresher != nil {
+3 -2
pkg/appview/storage/proxy_blob_store.go
··· 87 87 return fmt.Errorf("authorization check failed: %w", err) 88 88 } 89 89 if !allowed { 90 - return distribution.ErrBlobUnknown // Return same error as missing blob for security 90 + // Return 403 Forbidden instead of masquerading as missing blob 91 + return errcode.ErrorCodeDenied.WithMessage("read access denied") 91 92 } 92 93 return nil 93 94 } ··· 106 107 } 107 108 if !allowed { 108 109 fmt.Printf("[checkWriteAccess] Write access DENIED for userDID=%s to holdDID=%s\n", p.ctx.DID, p.ctx.HoldDID) 109 - return fmt.Errorf("write access denied to hold %s", p.ctx.HoldDID) 110 + return errcode.ErrorCodeDenied.WithMessage(fmt.Sprintf("write access denied to hold %s", p.ctx.HoldDID)) 110 111 } 111 112 fmt.Printf("[checkWriteAccess] Write access ALLOWED for userDID=%s to holdDID=%s\n", p.ctx.DID, p.ctx.HoldDID) 112 113 return nil