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.


Virtual resource
kind: Organization
  name: acme-corp (1)
  displayName: Acme Corp. (2)

Field mapping from the represented Namespace resource:

2 metadata.annotations[]
Original resource
apiVersion: v1
kind: Namespace
  name: acme-corp
  labels: organization (1)
  annotations: 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



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


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:

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 and not for resources in API group 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 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 resources. In practice any user is allowed to perform any action on and access control is handled by the aggregate API server.

Generated RBAC

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


View (read only) access to an organization

kind: ClusterRole
  name: appuio-organization-viewer
- apiGroups: [""]
  resources: ["organizations"]
  verbs: ["get"]
# Get and list permission for other resources

Admin (read / write) access to an organization

kind: ClusterRole
  name: appuio-organization-admin
- apiGroups: [""]
  resources: ["organizations"]
  verbs: ["get", "patch", "edit"]
- apiGroups: [""]
  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
kind: OrganizationMembers
  name: members
  namespace: org-acme-corp
  userRefs: (1)
  - name: kate.demo
  - name: peter.muster
  resolvedUserRefs: (2)
  - name: kate.demo
  - name: peter.muster
1 References to one or more User resource. The name field must match 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.