Skip to Content
ReferenceMarketplace Sources

Marketplace Sources

Each namespace stores its marketplace catalogue in a single ConfigMap named marketplace-sources. The dashboard reads it through ark-api, so a namespace’s catalogue is shared by every user of that namespace.

For seeding catalogues, granting edit access, and multi-namespace operation, see the Marketplace operations guide.

ConfigMap shape

One ConfigMap per namespace, fixed name marketplace-sources. Each source is a separate data key (the source name); the value is a JSON-encoded object.

apiVersion: v1 kind: ConfigMap metadata: name: marketplace-sources namespace: team-a data: agents-at-scale-marketplace: | {"url":"https://raw.githubusercontent.com/mckinsey/agents-at-scale-marketplace/main/marketplace.json","displayName":"Ark Marketplace"} internal-mirror: | {"url":"https://internal.example.com/marketplace.json"}

One key per source lets server-side apply track ownership at the data-key level, so Helm-seeded entries and user edits can coexist.

Per-source value schema

FieldRequiredDescription
urlyesAbsolute https URL of a marketplace manifest. The filename is not constrained.
displayNamenoHuman label shown in the dashboard. Defaults to the source name.

Source names must match the Kubernetes ConfigMap key rules (alphanumeric, -, _, .). ark-api validates url on every write (HTTPS-only, parseable absolute URL) and returns HTTP 422 on failure.

RBAC

The dashboard chart ships a marketplace-source-editor ClusterRole granting get, update, and patch on the marketplace-sources ConfigMap (resourceNames: ["marketplace-sources"]). It is bound to no one by default — platform teams bind it per namespace:

kubectl apply -f samples/marketplace/marketplace-source-editor-binding.yaml

Read access to the catalogue is already granted to dashboard users by their tenant role, so every user sees the sources regardless of edit permission. The dashboard’s Manage Marketplace page renders add/edit/delete controls only when the permission probe (GET /api/v1/namespaces/{namespace}/marketplace-sources/permissions) reports canEdit: true.

Helm seeding

The dashboard chart accepts a marketplaceSources values key — a list of entries with name, url, optional displayName, and optional namespace (defaulting to the install namespace):

marketplaceSources: - name: agents-at-scale-marketplace url: https://raw.githubusercontent.com/mckinsey/agents-at-scale-marketplace/main/marketplace.json displayName: "Ark Marketplace" - name: internal url: https://internal.example.com/marketplace.json namespace: team-a

A post-install,post-upgrade Job applies each entry as a key in the target namespace’s marketplace-sources ConfigMap using server-side apply with the field manager helm-marketplace-seeder. Because ownership is tracked per key, a user edit to a seeded entry transfers that key’s ownership; a later helm upgrade reconciles the keys it still owns and leaves user-edited keys intact. Setting marketplaceSources: [] seeds nothing and skips the Job.

ark-api endpoints

All endpoints run under the requesting user’s identity via impersonation.

MethodPathPurpose
GET/api/v1/namespaces/{namespace}/marketplace-sourcesList sources (empty list if the ConfigMap is absent).
GET/api/v1/namespaces/{namespace}/marketplace-sources/{name}Get one source.
POST/api/v1/namespaces/{namespace}/marketplace-sourcesCreate a source (creates the ConfigMap if absent).
PATCH/api/v1/namespaces/{namespace}/marketplace-sources/{name}Update a source.
DELETE/api/v1/namespaces/{namespace}/marketplace-sources/{name}Delete a source.
GET/api/v1/namespaces/{namespace}/marketplace-sources/permissionsPermission probe ({canEdit}, fail-closed).
GET/api/v1/namespaces/{namespace}/marketplace-itemsAggregate items across all sources.

The items aggregator fetches each source’s manifest concurrently (per-source timeout 10s, aggregator total 30s), caches successful fetches for one hour per (namespace, source, url), and always returns HTTP 200 — per-source failures are reported inline with an error.code of fetch_timeout, aggregator_timeout, http_error, parse_error, or network_error.

Last updated on