Deckhouse Code users send requests to the cluster through the Kubernetes API proxy of the agent for Kubernetes. The agent can forward each of these requests to the cluster on behalf of the user who sent it. The cluster receives the user’s name and groups in the request. The groups match the user’s roles in the projects and groups of Deckhouse Code. Kubernetes RBAC bindings on these names decide what the user may do in the cluster.

A member of the agent’s configuration project with the Developer role or higher configures access on behalf of a user in the agent configuration file. The cluster administrator grants the permissions in the cluster.

Configuring access

Prerequisites:

  • Relay (KAS) is enabled on the instance;
  • the agent for Kubernetes is deployed in the cluster as described in Agents for Kubernetes;
  • you have the Developer role or higher in the agent’s configuration project.

Add the user_access keyword to the agent configuration file .gitlab/agents/<AGENT_NAME>/config.yaml, where <AGENT_NAME> is the name of the agent. Specify the following parameters under user_access:

  • access_as: the access mode (user: {} sets access on behalf of a user);
  • projects: the full paths of the projects whose members get access (up to 500 entries);
  • groups: the full paths of the groups whose members get access (up to 500 entries).

An example of the user_access keyword that gives access to the members of the group-1/project-1 project and the group-2 group:

user_access:
  access_as:
    user: {}
  projects:
    - id: group-1/project-1
  groups:
    - id: group-2

The agent reads the configuration file from the default branch of the configuration project. A change in the file takes effect when it reaches the default branch.

The following restrictions apply if the “Enable instance level authorization” setting is off on the instance. List under projects and groups only projects and groups from the same top-level group as the agent’s configuration project. Deckhouse Code ignores entries from other groups. If, in addition, the configuration project is in a personal namespace, Deckhouse Code ignores groups. In this case, only the projects of that namespace take effect under projects.

Specify exactly one key under access_as. If you specify agent: {} instead of user: {}, the agent forwards requests under its service account.

What the cluster receives

The Kubernetes API server receives a user’s request with the following data:

  • username gitlab:user:<USERNAME>;
  • group gitlab:user, common to all users;
  • group gitlab:project_role:<PROJECT_ID>:<ROLE> for each role of the user in each project under projects;
  • group gitlab:group_role:<GROUP_ID>:<ROLE> for each role of the user in each group under groups;
  • extra fields agent.gitlab.com/id, agent.gitlab.com/username, agent.gitlab.com/access_type and agent.gitlab.com/config_project_id.

<PROJECT_ID> and <GROUP_ID> are the numeric IDs of the projects and groups from the configuration file. A user gets the gitlab:project_role and gitlab:group_role groups only for the projects and groups in which they have the Developer role or higher.

Deckhouse Code counts a user’s role in a project under projects in the following cases:

  • the user is a member of the project;
  • the user is a member of one of the project’s parent groups;
  • the project is shared with a group the user is a member of.

Deckhouse Code counts a user’s role in a group under groups only for direct membership. The user must be a direct member of that group or of one of its parent groups. Deckhouse Code does not count membership in a group that the group under groups is shared with. Deckhouse Code does not count membership only in a subgroup of the group under groups either.

The proxy refuses all requests from a user without the Developer role or higher in at least one project or group from the configuration file.

A user gets their own role and all lower roles. The order of roles from lowest to highest is guest, planner, reporter, security_manager, developer, maintainer, owner. The security_manager role is in this list only if the Security Manager role is enabled on the instance. A binding for gitlab:project_role:<PROJECT_ID>:developer therefore also applies to the project’s members with the Maintainer and Owner roles.

For example, a member of project 11 with the Developer role gets the following groups:

  • gitlab:user;
  • gitlab:project_role:11:guest;
  • gitlab:project_role:11:planner;
  • gitlab:project_role:11:reporter;
  • gitlab:project_role:11:developer;
  • gitlab:project_role:11:security_manager, if the Security Manager role is enabled on the instance.

The agent server for Kubernetes caches the authorization result of a request. The default cache time is one minute. If the user’s membership or role in a project or group changes, the cluster receives the user’s new groups with a delay.

Granting permissions in the cluster

Until a RoleBinding or ClusterRoleBinding names the user’s group, the user has no permissions in the cluster.

For example, to let the members of project 123 with the Maintainer and Owner roles read most objects in the cluster, apply the following manifest. The manifest binds the gitlab:project_role:123:maintainer group to the built-in ClusterRole view:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: project-123-maintainers-view
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: Group
    name: gitlab:project_role:123:maintainer

To grant permissions in one namespace only, create a RoleBinding in that namespace. The Kubernetes documentation page Using RBAC Authorization describes the rules of RBAC bindings.

Connecting to the cluster

  1. Open the agent’s configuration project and go to “Operate” → “Kubernetes clusters”. Note the numeric ID of the agent.

  2. Create a personal access token with the k8s_proxy and read_user scopes.

  3. Request the instance metadata:

    curl --header "PRIVATE-TOKEN: <TOKEN>" "https://<HOSTNAME>/api/v4/metadata"

    Note the address of the Kubernetes API proxy in the kas.externalK8sProxyUrl field of the response. If the kas.enabled field is false, the agent server for Kubernetes is disabled on the instance. The Metadata page describes all fields of the response.

  4. Add a cluster with the address of the Kubernetes API proxy to kubeconfig:

    d8 k config set-cluster <CLUSTER_NAME> --server "<K8S_PROXY_URL>"
  5. Add credentials to kubeconfig. The token in them consists of the pat: prefix, the agent ID and the personal access token:

    d8 k config set-credentials <USER_NAME> --token "pat:<AGENT_ID>:<TOKEN>"
  6. Create a context and switch to it:

    d8 k config set-context <CONTEXT_NAME> --cluster <CLUSTER_NAME> --user <USER_NAME>
    d8 k config use-context <CONTEXT_NAME>
  7. Check the username and groups the cluster receives:

    d8 k auth whoami

    The command prints the username gitlab:user:<USERNAME> and the groups from the “What the cluster receives” section.

Placeholders:

  • <HOSTNAME>: the address of the Deckhouse Code instance;
  • <K8S_PROXY_URL>: the address of the Kubernetes API proxy from the kas.externalK8sProxyUrl field;
  • <AGENT_ID>: the agent ID from the first step;
  • <TOKEN>: the personal access token;
  • <CLUSTER_NAME>, <USER_NAME>, <CONTEXT_NAME>: the names of the cluster, the credentials and the context in kubeconfig, which you choose yourself.

Additional resources