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
| Field | Required | Description |
|---|---|---|
url | yes | Absolute https URL of a marketplace manifest. The filename is not constrained. |
displayName | no | Human 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.yamlRead 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-aA 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.
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/namespaces/{namespace}/marketplace-sources | List 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-sources | Create 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/permissions | Permission probe ({canEdit}, fail-closed). |
GET | /api/v1/namespaces/{namespace}/marketplace-items | Aggregate 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.