Skip to content

design-proposal: cozymarketplace supplementary — backend, private sources, publication validation#23

Open
IvanHunters wants to merge 3 commits into
cozystack:mainfrom
IvanHunters:feat/cozymarketplace-supplementary
Open

design-proposal: cozymarketplace supplementary — backend, private sources, publication validation#23
IvanHunters wants to merge 3 commits into
cozystack:mainfrom
IvanHunters:feat/cozymarketplace-supplementary

Conversation

@IvanHunters

@IvanHunters IvanHunters commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Supplementary, not competing, to #18 by Andrei Kvapil (@kvaps). Accepts the repository-centric model and the meta-index design as-is; fills in three concrete pieces that #18 lists as open questions or leaves implicit:

  1. In-cluster backend for the dashboard marketplace view — a small set of endpoints in cozystack-api, a TapIndex cache controller, and well-defined RBAC.
  2. SecretRef on PackageSourceRef — additive, nil-default CRD field so that one-command cozypkg tap works against private OCI/Git sources. Symmetric with the platform-source change already in flight in feat(operator): support private OCI registry credentials for platform source cozystack#2472.
  3. cozypkg validate + CI gate — offline linter for marketplace repositories, reused in a GitHub Actions workflow that validates submissions before they appear in the meta-index.

Per-package version pinning is explicitly out of scope, siding with #18.

Rendered: design-proposals/cozymarketplace-supplementary/README.md

Related: #18 (parent proposal), cozystack/cozystack#2472 (already-in-flight private platform source), cozystack/cozystack#2455 (motivation issue).

Opening as Draft for early feedback before #18 lands.

Summary by CodeRabbit

  • Documentation
    • Added a new marketplace design proposal outlining upcoming user-facing capabilities, including repository browsing, package search, and offline validation for marketplace content.
    • Describes support for tapping private repositories with stored credentials, plus validation and security checks for marketplace packages.
    • Includes guidance for rollout behavior, error handling, and planned testing coverage.

…rces, publication validation

Supplementary to cozystack#18 by @kvaps. Accepts the repository-centric
model and fills three concrete pieces that cozystack#18 lists as open
questions or leaves implicit: in-cluster backend for the dashboard
marketplace view, secretRef on PackageSourceRef for one-command
private taps, and a cozypkg validate subcommand plus CI gate for
publication validation. Per-package version pinning remains out of
scope, siding with cozystack#18.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@IvanHunters, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 17 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: adcf71fb-3655-451d-bddc-a62628734e66

📥 Commits

Reviewing files that changed from the base of the PR and between c958f39 and fe23310.

📒 Files selected for processing (1)
  • design-proposals/cozymarketplace-supplementary/README.md
📝 Walkthrough

Walkthrough

This pull request adds a new design proposal document for Cozymarketplace Phase 1, describing a server-side marketplace backend, a TapIndex cache controller, a secretRef field for private repositories, a cozypkg validate CLI, CI gating, and related security, testing, and rollout considerations.

Changes

Design Proposal Document

Layer / File(s) Summary
Proposal context and scope
design-proposals/cozymarketplace-supplementary/README.md
Adds header metadata and frames the proposal as supplementary, defining out-of-scope items and problem context around catalog aggregation, private repos, and publication validation.
Phase 1 design and user-facing behavior
design-proposals/cozymarketplace-supplementary/README.md
Specifies marketplace backend endpoints, TapIndex controller, new secretRef field on PackageSourceRef, cozypkg validate CLI, CI workflow gating, and documents user-facing/CRD changes with additive upgrade/rollback behavior.
Security, failure handling, testing, and open questions
design-proposals/cozymarketplace-supplementary/README.md
Documents security/credential handling, failure and edge-case behaviors, testing strategy, rollout sequencing, open questions, and alternatives considered.

Estimated code review effort: 1 (Trivial) | ~5 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the proposal’s main additions: backend support, private source handling, and validation gating.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a supplementary design proposal for Cozymarketplace, detailing the backend endpoints, private repository support, and publication validation. Feedback on the proposal highlights an inconsistency regarding the namespace of the referenced Secret, pointing out that the PackageSourceRef struct contains a Namespace field while the text states the Secret must reside in cozy-system.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +69 to +75
type PackageSourceRef struct {
Kind, Name, Namespace, Path string
SecretRef *corev1.LocalObjectReference // NEW; nil preserves current behaviour
}
```

The `packagesource-reconciler` sets `spec.secretRef` on the materialized Flux source when `SecretRef != nil`. Secret format depends on source kind, matching what Flux source-controller already documents: `kubernetes.io/dockerconfigjson` for OCI; Opaque with `username`+`password` or `bearerToken` for Git over HTTPS; Opaque with `identity` (PEM private key) and `known_hosts` for Git over SSH. The Secret must exist in `cozy-system` before the reconciler runs; otherwise Flux reports a failed condition until it appears. This is symmetric with the platform-source change already in flight in `cozystack/cozystack#2472` — that PR closed the gap for the bootstrap platform source; this CRD field closes the same gap for every user-tapped repository.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There is an inconsistency between the PackageSourceRef struct definition and the described namespace behavior for the referenced Secret:

  1. The PackageSourceRef struct (lines 69-72) contains a Namespace field, indicating that the referenced or materialized Flux source can reside in namespaces other than cozy-system.
  2. However, line 75 (and line 117) states that the Secret must exist in cozy-system.

Since Flux's spec.secretRef is namespace-scoped and cannot reference secrets across namespaces, the Secret must reside in the same namespace as the materialized Flux source (i.e., the namespace specified by PackageSourceRef.Namespace). If all materialized Flux sources are strictly created in cozy-system, the Namespace field in PackageSourceRef might be redundant or misleading.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@design-proposals/cozymarketplace-supplementary/README.md`:
- Around line 52-63: The marketplace read endpoints are currently described as
open to any authenticated user, which leaks tap/package metadata across tenants
when private taps exist. Update the access model in the `cozystack-api`
marketplace handlers so `GET /marketplace/taps`, `GET
/marketplace/taps/{name}/packages`, and `GET /marketplace/search` only return
taps the caller is authorized to view; add tap-level visibility checks or filter
by the caller’s allowed taps in the `TapIndex`-backed response path.
- Around line 79-81: The GitHub Actions validator flow currently trusts
PR-supplied `source.url`, creating an arbitrary outbound fetch path; tighten the
`cozypkg validate` workflow by adding an allowlist for permitted schemes/hosts
or by running the validator in a network-restricted sandbox before it is used on
PRs. Update the README/workflow description around the `validate` subcommand and
the PR-triggered meta-index job so the `source.url` and `source.tag` inputs are
explicitly constrained before any fetch occurs.
- Around line 115-117: Clarify the tap-removal retention flow by adding an
explicit finalizer/orphaning path in the tap and package lifecycle logic, since
helm.sh/resource-policy: keep alone does not protect controller-owned Package
CRs. Update the tap-removal handling referenced by the OrphanedSource behavior
so installed Package resources remain intact and are marked orphaned until
re-tapped or deleted via cozypkg del, rather than relying only on Helm
retention.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe5e6b3d-7a1f-4ba0-8e9b-3f8894270d9a

📥 Commits

Reviewing files that changed from the base of the PR and between fbfc6ba and c958f39.

📒 Files selected for processing (1)
  • design-proposals/cozymarketplace-supplementary/README.md

Comment on lines +52 to +63
The dashboard reads marketplace state through a small set of endpoints layered into `cozystack-api`, which already mediates dashboard access to platform CRs and existing auth/RBAC. No new component, no new CRDs — the marketplace state is fully derived from `PackageSource` plus the parsed artifact contents.

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/marketplace/taps` | List connected taps with metadata. |
| `GET` | `/marketplace/taps/{name}/packages` | Packages exposed by one tap. |
| `GET` | `/marketplace/search?q=<query>` | Search across all taps by name, tag, description. |
| `POST` | `/marketplace/taps` | Connect a tap; creates `PackageSource` and, when given, the `Secret`. |
| `DELETE` | `/marketplace/taps/{name}` | Disconnect a tap. Lifecycle of installed `Package` CRs is an open question (see below). |

A `TapIndex` cache controller in the same binary watches `OCIRepository.status.artifact.revision`, pulls the parsed `marketplace.yaml` on each revision change, and serves the GET endpoints from memory. Without it, every search would hit OCI per request. Cluster-admin is required for `POST` and `DELETE`, matching the existing `Package` cluster-scoped model. `GET` is open to any authenticated user so tenant-admins can browse.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='design-proposals/cozymarketplace-supplementary/README.md'

echo '--- around lines 1-140 ---'
nl -ba "$file" | sed -n '1,140p'

echo
echo '--- search for auth / private / visibility terms ---'
rg -n -i 'auth|authorization|private|tenant|rbac|cluster-admin|search|browse|visibility|secretref|secret ref|tap' "$file"

Repository: cozystack/community

Length of output: 224


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='design-proposals/cozymarketplace-supplementary/README.md'

echo '--- around lines 1-140 ---'
cat -n "$file" | sed -n '1,140p'

echo
echo '--- search for auth / private / visibility terms ---'
rg -n -i 'auth|authorization|private|tenant|rbac|cluster-admin|search|browse|visibility|secretref|secret ref|tap' "$file"

Repository: cozystack/community

Length of output: 24411


Scope marketplace browse/search to authorized taps.

GET /marketplace/taps, /marketplace/taps/{name}/packages, and /marketplace/search should not be open to every authenticated user if private taps are supported; otherwise tap names, packages, tags, and descriptions leak across tenants. Scope these endpoints to the caller’s allowed taps or add tap-level visibility checks.

🧰 Tools
🪛 LanguageTool

[grammar] ~58-~58: Ensure spelling is correct
Context: ...e/search?q=| Search across all taps by name, tag, description. | |POST` |...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@design-proposals/cozymarketplace-supplementary/README.md` around lines 52 -
63, The marketplace read endpoints are currently described as open to any
authenticated user, which leaks tap/package metadata across tenants when private
taps exist. Update the access model in the `cozystack-api` marketplace handlers
so `GET /marketplace/taps`, `GET /marketplace/taps/{name}/packages`, and `GET
/marketplace/search` only return taps the caller is authorized to view; add
tap-level visibility checks or filter by the caller’s allowed taps in the
`TapIndex`-backed response path.

Comment thread design-proposals/cozymarketplace-supplementary/README.md Outdated
Comment thread design-proposals/cozymarketplace-supplementary/README.md Outdated
Move private-repository credential handling off a proposed
PackageSourceRef.secretRef field and onto the Flux source created at
tap time, matching the merged cozystack/cozystack#2472 pattern: the
PackageSource reconciler only reads SourceRef to build the
ArtifactGenerator and never creates the source, so the field would have
had no reconcile path. Derive marketplace state from PackageSource plus
ApplicationDefinition rather than a new marketplace.yaml, and align tap
and untap semantics, the community index, and the validation reuse with
community#12. No CRD change and no migration.

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
…s to cozymarketplace supplementary

Add two mermaid diagrams (backend/tap architecture and the
author/push/validate CI-gate flow) and scannable bold lead-ins on the
Goals section, matching the visual structure of the sibling proposals

Signed-off-by: IvanHunters <xorokhotnikov@gmail.com>
cozystack#18 and cozystack#12.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant