Accessing private image repositories
When the image repository visibility is set to private (the default), you need to authenticate before you can pull images. Konflux provides an RBAC image proxy that controls access based on your permissions.
Who can pull images and access scope
Access to pull images is controlled at the tenant level through Kubernetes RBAC:
-
Users or service accounts who have permission to
get,list, orwatchImageRepositoryresources in a tenant can pull images from all components in that tenant -
Image path format:
proxy_host/redhat-user-workloads(-stage)/tenant/component:tag -
Without the required RBAC permissions, image pulls will fail
To grant this access, a tenant maintainer creates a Role that permits reading ImageRepository resources, then binds that role to a subject with a RoleBinding:
-
Service account (recommended for automation): bind the role to a
ServiceAccountfor CI/CD pipelines and other external systems. See Granting pull access with a service account. -
User (for local development): bind the role to an individual
Userso a person can pull images with their own token. See Getting registry login credentials via the UI.
|
Tenant administrators cannot create new custom |
Token types and scope
-
User tokens:
-
Any Konflux user can obtain a user token through the proxy authentication flow
-
Issued by the proxy’s Dex (not SSO), so they can ONLY be used for pulling images through the proxy
-
Cannot be used for OpenShift API authentication
-
Expire after 24 hours
-
Best for local development and manual testing
-
-
Service account tokens:
-
Any Konflux user who has permission to create secrets in a namespace can create a service account token in that namespace
-
Can authenticate against both the proxy AND the OpenShift API (works like a regular OpenShift service account)
-
Do not expire (valid until the secret is deleted)
-
Best for automated systems and CI/CD pipelines
-
Finding your proxy URL
The examples on this page use image-rbac-proxy.apps.example.com as a placeholder. Replace it with the RBAC image proxy hostname for the cluster that hosts your tenant. The hostname follows this pattern:
image-rbac-proxy.apps.<cluster-domain>
For example, on the stone-prod-p02 cluster the proxy hostname is:
image-rbac-proxy.apps.stone-prod-p02.hjvn.p1.openshiftapps.com
The proxy hostname matches the domain of the Konflux instance you use, so the login command shown in the UI is always the authoritative source for your cluster. To find the exact hostname:
-
Open the Component details page for any of your components in the Konflux UI.
-
In the Registry login information section, read the
podman logincommand. The host in that command is the proxy hostname for your cluster. -
Copy the private image path shown for the component. It begins with the same proxy hostname.
Granting pull access with a service account
For automated access from external systems such as Testing Farm or CI/CD pipelines, grant a service account permission to pull images. Create the following objects in this order, because each object depends on the ones before it: the Secret and the RoleBinding both reference the ServiceAccount, so the service account must exist first.
-
Create a
Rolethat permits readingImageRepositoryresources:apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: repo-viewer namespace: <your-namespace> rules: - apiGroups: - appstudio.redhat.com resources: - imagerepositories verbs: - get - watch - list -
Create a
ServiceAccount:apiVersion: v1 kind: ServiceAccount metadata: name: external-puller namespace: <your-namespace> -
Create a
Secretthat holds a non-expiring token for the service account. Thekubernetes.io/service-account.nameannotation must reference the service account created in the previous step:apiVersion: v1 kind: Secret metadata: name: external-puller-token namespace: <your-namespace> annotations: kubernetes.io/service-account.name: external-puller type: kubernetes.io/service-account-token -
Create a
RoleBindingthat binds theRoleto theServiceAccount:apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: repo-viewer namespace: <your-namespace> roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: repo-viewer subjects: - kind: ServiceAccount name: external-puller namespace: <your-namespace> -
Get the service account token from the secret:
kubectl get secret external-puller-token -n <your-namespace> -o jsonpath='{.data.token}' | base64 -d -
Use the token to authenticate to the registry in your external system:
podman login -u external-puller image-rbac-proxy.apps.example.com # When prompted for password, paste the service account tokenThen pull images:
podman pull image-rbac-proxy.apps.example.com/redhat-user-workloads/my-tenant/my-app:b153d64
Replace image-rbac-proxy.apps.example.com with your cluster’s proxy hostname. See Finding your proxy URL.
|
| If a token is compromised, delete the secret to revoke the token, then create a new one. The username must match the service account name. |
Getting registry login credentials via the UI
To access private images locally with your own user token:
-
Ask a tenant maintainer to bind the pull
Roleto your user. This uses the sameRoleshown in Granting pull access with a service account, with aUsersubject instead of aServiceAccount:apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: repo-viewer-user namespace: <your-namespace> roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: repo-viewer subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: <your-username> -
Navigate to the Component details page for your component
-
In the Registry login information section, copy and run the
podman logincommand in your terminal:podman login -u unused image-rbac-proxy.apps.example.com -
Click the OAuth URL link to get your authentication token
-
Paste the token when prompted for password
-
Copy the private image path from the UI and pull the image:
podman pull image-rbac-proxy.apps.example.com/redhat-user-workloads/my-tenant/my-app:b153d64The image path includes the proxy host (e.g., image-rbac-proxy.apps.example.com) which enforces access control. You must use this proxy URL, not a direct registry URL. Replace it with your cluster’s proxy hostname; see Finding your proxy URL.