The module lifecycle stage: Preview
The module has requirements for installation
The module supports the following authentication and authorization methods:
- Recommended: Kubernetes tokens and RBAC via PayloadRepositoryAccess.
- Deprecated: Static user configuration (configuration via ModuleConfig in section
settings.users).
The permission to get the list of available repositories (catalog) is available to all authenticated users regardless of the authentication method.
Each root directory in the registry corresponds to a Kubernetes namespace name. If that namespace is deleted, all images in that directory and subdirectories will be deleted regardless of the authentication method.
Authentication with Kubernetes tokens
In this authentication mode, the following parameters are used:
- Username:
token - Password: Kubernetes bearer token (from a projected volume,
d8 k create token, or obtained via the kubeconfig generation interface (ID Token))
Access to repository paths is determined by Kubernetes RBAC rules for the PayloadRepositoryAccess resource.
RBAC and PayloadRepositoryAccess
When authenticating with a Kubernetes token, access to repository paths is controlled using Kubernetes RBAC applied to the virtual resource PayloadRepositoryAccess:
- API group:
payload-registry.deckhouse.io - Resource name:
payloadrepositoryaccesses(PayloadRepositoryAccess) - Purpose: A virtual resource used only for configuring access to the registry via Kubernetes RBAC.
PayloadRepositoryAccess objects are not created in Kubernetes; they are used to grant permissions through Role or ClusterRole on this resource, for the registry and Kubernetes API extension to check access to repository paths and tags.
The resourceNames field defines repository path patterns.
Possible pattern substitutions:
| Pattern | Description |
|---|---|
* |
Any sequence of characters except / (single path segment) |
/**/ |
Zero or more directories (recursive traversal) |
? |
Exactly one character (except /) in a path segment |
[class] |
One character from a set or range, e.g. [a-z0-9] |
{alt1,alt2,...} |
One of the comma-separated alternatives |
The double asterisk ** must be a separate path segment.
A pattern like /path** is invalid and is treated the same as /path*; use /path*/** for the intended effect.
The pattern /path/** matches all directories and files under path, while /path/**/ matches only directories.
Path matching is case-insensitive: the pattern and the requested path are lowercased before comparison.
If the requested path matches the allowed resourceNames (or when resourceNames is absent) and the access level (verb) matches, access is granted.
Access levels (verbs)
| Verb | Registry operation |
|---|---|
get |
Pull image and get tag info via Kubernetes API extension |
list |
Get list of tags in namespace repositories via Kubernetes API extension |
create |
Push image |
delete |
Delete image, including via Kubernetes API extension |
Example RBAC configuration
The following is an example of granting a ServiceAccount full access (including getting and deleting tags via the Kubernetes API extension) to repositories in namespace project-1:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: payload-registry-full
namespace: project-1
rules:
- apiGroups: ["payload-registry.deckhouse.io"]
resources: ["payloadrepositoryaccesses"]
resourceNames:
- "dist/*"
- "app/**"
verbs: ["get", "list", "create", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: payload-registry-read
namespace: project-1
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: payload-registry-full
subjects:
- kind: ServiceAccount
name: payload-registry-sa
namespace: project-1Authorizing with a token and pushing an image to the registry
To authorize in the container registry using a token, follow these steps:
-
Create a namespace to which registry images will be bound:
d8 k create namespace project-1 -
Authorization in registry using a ServiceAccount token:
-
Create a Role in that namespace defining access (see example above).
-
Create a ServiceAccount:
d8 k -n project-1 create serviceaccount payload-registry-sa -
Bind it to the Role with a RoleBinding (see example above).
-
Log in to
payload-registryfrom your machine:docker login payload-registry.${PUBLIC_DOMAIN} -u token --password $(d8 k -n project-1 create token payload-registry-sa)
-
-
Authorization in the registry using a token obtained through the kubeconfig generation interface (ID Token):
-
Bind the user to the Role or ClusterRole with a RoleBinding or ClusterRoleBinding respectively (see example above).
-
Copy the
ID Tokenfrom the kubeconfig page. -
Log in to the registry from your machine:
docker login payload-registry.${PUBLIC_DOMAIN} -u token -p <ID Token>
-
-
Create an image and assign it a tag:
docker tag ubuntu:latest payload-registry.${PUBLIC_DOMAIN}/project-1/dist/ubuntu:latest -
Push the image to the registry:
docker push payload-registry.${PUBLIC_DOMAIN}/project-1/dist/ubuntu:latest -
Verify the presence of the image in the registry. Example using the
cranecommand:crane catalog payload-registry.${PUBLIC_DOMAIN}
Static user configuration (deprecated)
This authentication method is deprecated. Use Kubernetes tokens for authentication.
Static configuration may be removed in future versions.
This method allows configuring static authorization and managing access by project. Each project is a root directory in the registry and corresponds to a Kubernetes namespace name. If that namespace is deleted, all images in that directory and subdirectories will be deleted.
Features:
- Users are configured via ModuleConfig in section
settings.users. - Password is not stored in plain text. Only the password hash is specified in the configuration (see Generation of passwordHash for details).
Projects and access levels
A project is a root path in the registry. The project name matches the Kubernetes namespace name.
Each user can have multiple project entries with the following fields:
name: Project (namespace) name.subPath: Path or wildcard pattern:*,path-*,path/*,*/*. Segment skip**is not supported.access: Access level.
The following access levels are supported:
| Access | Allowed operations | Condition |
|---|---|---|
| READ | pull only |
Always as configured |
| FULL | pull and push |
Only if a namespace with the same name as the project exists. Otherwise READ is effectively granted |
To allow push:
- Configure the user with
access: FULLfor the project and desiredsubPath. - Create the namespace (e.g.
d8 k create namespace <project-name>).
Example static user configuration
Example static user configuration:
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: payload-registry
spec:
version: 1
enabled: true
settings:
users:
deploy-user:
passwordHash: "$2y$10$..." # Bcrypt password hash.
projects:
- name: my-app
subPath: "*"
access: FULL
read-only-user:
passwordHash: "$2y$10$..."
projects:
- name: my-app
subPath: "*"
access: READSubPath patterns: The full path is projectName/subPath. Examples: * (whole project), path-*, path/*, */*. The pattern must not start or end with a slash.
Generation of passwordHash
To generate a bcrypt hash, use the htpasswd command:
echo -n '${PASSWORD}' | htpasswd -BinC 10 "" | cut -d: -f2 | tr -d '\n'; echoThe generated hash should be specified in the users.${USER_NAME}.passwordHash field. Example:
echo -n 'password123' | htpasswd -BinC 10 "" | cut -d: -f2 | tr -d '\n'; echo
$2y$10$CeP/hYvBJ05Ih2azafVyIuuMRpf60am4z6USm4jhHfUPsFDBAmn/uExample ModuleConfig with password hash specified in users.${USER_NAME}.passwordHash:
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: payload-registry
spec:
version: 1
enabled: true
settings:
users:
user-1:
# Bcrypt hash of password `password123`.
passwordHash: "$2y$10$CeP/hYvBJ05Ih2azafVyIuuMRpf60am4z6USm4jhHfUPsFDBAmn/u"
projects: []Adding an image to a project
To add an image to a project, follow these steps:
-
Configure a user with
FULLaccess to the project. Example:apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: payload-registry spec: version: 1 enabled: true settings: users: user-1: # Bcrypt hash of password `password123`. passwordHash: "$2y$10$CeP/hYvBJ05Ih2azafVyIuuMRpf60am4z6USm4jhHfUPsFDBAmn/u" projects: - name: "project-1" subPath: "*" access: FULL -
Create a namespace with the project name in the cluster:
d8 k create namespace project-1 -
Log in to the registry from your machine:
docker login payload-registry.${PUBLIC_DOMAIN} -u user-1 -p password123 -
Create an image and assign it a tag:
docker tag ubuntu:latest payload-registry.${PUBLIC_DOMAIN}/project-1/ubuntu:latest -
Push the image to the registry:
docker push payload-registry.${PUBLIC_DOMAIN}/project-1/ubuntu:latest -
Verify the presence of the image in the registry. Example check using the
cranecommand:crane catalog payload-registry.${PUBLIC_DOMAIN}