APPUiO Control API: Organization

This resource implements the "Manage Organizations" features.

List operations on Kubernetes resources can not be filtered by RBAC, it’s a binary operation: Resources can either be listed or not, there is no way to give access only to a sub-set. To circumvent this limitation, Organization is a virtual resource.

The Organization resource represents a filtered and formatted list of standard Kubernetes Namespace resources which have specific labels and annotations.

It is assumed that the Organization resource is used for all operations, the represented Namespace must not be directly manipulated.

Object

Virtual resource
apiVersion: organization.appuio.io/v1
kind: Organization
metadata:
  name: acme-corp (1)
spec:
  displayName: Acme Corp. (2)

Field mapping from the represented Namespace resource:

1 metadata.name
2 metadata.annotations[organization.appuio.io/display-name]
Original resource
apiVersion: v1
kind: Namespace
metadata:
  name: acme-corp
  labels:
    appuio.io/resource.type: organization (1)
  annotations:
    organization.appuio.io/display-name: Acme Corp. (2)
1 Identify resource type, used by the API server to filter for namespaces representing organizations
2 Reflected in the Organization object as spec.displayName
Table 1. Labels and Annotations
Name Type Resource Description

appuio.io/resource.type

label

v1/Namespace

Identifies the resource type in the scope of the APPUiO Control API

organization.appuio.io/display-name

annotation

appuio.io/v1/Organization

Display name of the organization

Resource filter

The virtual resource is a filtered view of Namespaces. The filter uses the following heuristic:

  • API version: v1

  • Kind: Namespace

  • Label: appuio.io/resource-type=organization

Access Control

We use standard Kubernetes role-based access control for Organizations with two distinct differences.

  1. Access needs to be granted for organizations resources in API group rbac.appuio.io and not for resources in API group organization.appuio.io. Permissions can be configured through both Roles and RoleBindings, as well as ClusterRoles and ClusterRoleBindings. Similarly to Namespaces, permissions configured by a Role in namespace foo only affects Organization foo.

  2. For list and watch verbs the API server will only return resources that the user also has permission to get

The rbac.appuio.io API group allows us to delegate access control to the aggregate API server. With the new API group we can still use the powerful RBAC engine of Kubernetes, while bypassing the Kubernetes API server’s access control. As a consequence, by introducing this logical RBAC group, no custom code needs to be written in order to implement the access control required for multi-tenancy. The Kubernetes API server will still perform classical access control for organizations.organization.appuio.io resources. In practice any user is allowed to perform any action on organizations.organization.appuio.io and access control is handled by the aggregate API server.

Generated RBAC

By default there are two ClusterRoles that configure access for organization members

appuio-organization-viewer

View (read only) access to an organization

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: appuio-organization-viewer
rules:
- apiGroups: ["rbac.appuio.io"]
  resources: ["organizations"]
  verbs: ["get"]
...
# Get and list permission for other resources
appuio-organization-admin

Admin (read / write) access to an organization

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: appuio-organization-admin
rules:
- apiGroups: ["rbac.appuio.io"]
  resources: ["organizations"]
  verbs: ["get", "patch", "edit"]
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["rolebindings"]
  verbs: ["get", "list", "watch", "patch", "edit", "delete"]
...
# Edit permission for other resources

Creating, listing, and watching organizations can be done by all authenticated users.

When creating an Organization, a RoleBinding in the created Namespace is generated. This RoleBinding assigns the appuio-organization-admin ClusterRole to the creating user. This allows the creator to manage the new Organization and assign permissions to new members.

Organization Membership

All members of an organization are configured in an OrganizationMembers resource.

CRD based
apiVersion: appuio.io/v1
kind: OrganizationMembers
metadata:
  name: members
  namespace: org-acme-corp
spec:
  userRefs: (1)
  - name: kate.demo
  - name: peter.muster
status:
  resolvedUserRefs: (2)
  - name: kate.demo
  - name: peter.muster
1 References to one or more User resource. The name field must match metadata.name of an existing User resource.
2 This is resolved by the adapter. May only contain a subset of users if the adapter is unable to add some users.