Skip to content

Create cluster connection API Reference

POST
/tenants/{tenant}/registries/{name}/bindings
curl --request POST \
--url https://api.kupe.cloud/api/v1/tenants/acme/registries/registry/bindings \
--header 'Authorization: <Authorization>' \
--header 'Content-Type: application/json' \
--data '{ "cluster": "prod", "name": "prod", "pushNamespaces": [ "ci" ], "secretName": "kupe-registry-push" }'

Connect a cluster to the registry. Every pod of the cluster can then pull its images: the pull credential stays on the platform and never enters the cluster. Pods that were running before the connection get it when they restart. Each namespace in pushNamespaces (up to 10, none kube-* or argocd) also gets a push credential Secret named secretName (default kupe-registry-push). A push credential can pull from and push to every repository in your registry, including replacing existing tags.

tenant
required
string

Tenant name

name
required
string

Registry name: always registry

Cluster connection

Media type application/json
object
cluster

Cluster to connect. A connection is named after its cluster.

string
Example
prod
name

Must equal cluster when set; it is also the default.

string
Example
prod
pushNamespaces

Namespaces inside the cluster that receive a push credential Secret: up to 10, each listed once, none kube-* or argocd. A push credential can pull from and push to every repository in your registry, including replacing existing tags. Pull needs none: every pod of the cluster can pull.

Array<string>
Example
[
"ci"
]
secretName

Name of the push credential Secret in each push namespace. Default “kupe-registry-push”; it cannot be “kupe-registry-pull” and cannot change later.

string
Example
kupe-registry-push

Cluster connection created

Media type application/json
object
cluster
string
createdAt
string
name

Name is the cluster’s name.

string
pushNamespaces

PushNamespaces are the namespaces that hold a push credential (empty: pull only).

Array<string>
registry
string
resourceVersion
string
secretName

SecretName is the push credential Secret’s name in each push namespace.

string
status
object
conditions
Array<object>
object
key
additional properties
message

Message gives detail; once Ready it says that pods running before the connection need a restart to pull.

string
namespaces

Namespaces reports what was delivered into each push namespace. A namespace removed from pushNamespaces stays here until its Secret is withdrawn and the push credential is replaced; while the platform has the registry switched off or the tenant is suspended, the replacement, and with it the entry’s removal, waits until the registry is on and the tenant active again.

Array<object>
object
message

Message gives detail while the namespace is not Ready.

string
name
string
phase
string
Allowed values: Pending Ready Failed
phase

Phase is Ready only when pull works and every push namespace is Ready.

string
Allowed values: Pending Ready Failed
pullUsername

PullUsername is the registry username of the cluster’s pull credential.

string
pushUsername

PushUsername is the registry username of the push credential; empty without push namespaces.

string
rotation
object
appliedAt
string
pending

Pending is true while RequestedAt differs from AppliedAt.

boolean
requestedAt

RequestedAt is the token of the last rotation requested; empty if none ever was.

string
Example
{
"cluster": "prod",
"createdAt": "2026-10-21T10:05:00Z",
"name": "prod",
"pushNamespaces": [
"ci"
],
"registry": "registry",
"resourceVersion": "582020",
"secretName": "kupe-registry-push",
"status": {
"message": "",
"namespaces": [
{
"message": "",
"name": "ci",
"phase": "Pending"
}
],
"phase": "Pending",
"pullUsername": "kupe+acme+pull-prod",
"pushUsername": "kupe+acme+push-prod",
"rotation": {
"appliedAt": "2026-10-21T12:00:00.123456789Z",
"pending": false,
"requestedAt": "2026-10-21T12:00:00.123456789Z"
}
}
}
ETag
string

Resource version

Validation error, or too many push namespaces in this connection (code REGISTRY_PUSH_NAMESPACES_LIMIT) or in the registry (code REGISTRY_PUSH_NAMESPACES_SERVICE_LIMIT), both with field spec.pushNamespaces

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}

Missing or invalid authentication

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}

Admin access required

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}

Registry or cluster not found, or the registry is not enabled (code registries_unavailable)

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}

The cluster is already connected (code REGISTRY_BINDING_EXISTS), or the registry or cluster is being deleted (code terminating)

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}

Rate limit exceeded

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}