APPUiO Control API: Organization Adapter and Identity Provider

At the core of APPUiO Cloud user management is an OIDC enabled Identity Provider (IdP) that stores the identity of every APPUiO Cloud user and provides OIDC tokens to authenticate users to APPUiO Zones and the APPUiO Control API. For the VSHN-managed APPUiO Cloud instance and throughout parts of this documentations this IdP is Keycloak, but in general this could be any IdP with OIDC integration.

Regardless of what IdP is being used the APPUiO Control API needs to be able to manage organizations, teams, as well as user preferences. The interaction between the state in the APPUiO Control API, represented by User, Team, and Organization resources, is managed by the Organization Adapter. First and foremost the adapter needs to make sure that the information on user preferences and organizations in the APPUiO Control API is available in every APPUiO Zone and that user data from the IdP is available to the APPUiO Control API.

This document should give a high level specification of what an APPUiO IdP and its adapter needs to be able to do. The implementation details and which part of these requirements are fulfilled by which system might vary.

The requirement level keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" used in this document are to be interpreted as described in RFC 2119.

In this document, such keywords are highlighted using bold font.

Identity Provider

For APPUiO Cloud the two main features of the IdP is that it provides the user identities for every APPUiO Cloud user and that it authenticates them to APPUiO Zones and the APPUiO Control API. That means the APPUiO Control API is not authoritative for users but get its user information from the IdP.

It is helpful if the IdP has some notion of groups and sub-groups which can be correlated to organizations and teams, but such a data model is not strictly required.
  • The IdP must hold the identities of APPUiO Cloud users.

  • The IdP must provide OIDC tokens authenticating APPUiO Cloud users to APPUiO Zones.

  • The IdP must provide OIDC tokens authenticating APPUiO Cloud users to the APPUiO Control API.

  • The IdP should have a notion of groups and sub-groups containing users which can be added as claims in the OIDC token.

  • The IdP should provide means to on-board new users to APPUiO Cloud.

Identity Provider at VSHN

The VSHN-managed APPUiO Cloud instance uses Keycloak as the identity provider.

User are brokered in through the existing LDAP userbase and assigned to Keycloak groups representing organizations and sub-groups of these groups represent teams. The group membership information is then present as a claim in the OIDC token provided to APPUiO Zones and the APPUiO Control API.

Organization Adapter

As long as the Identity Provider is not custom built, it is very unlikely to be able to interface with the APPUiO Control API. Providing this interface is the job of the Organization Adapter.

The adapter may be implemented as a Kubernetes aggregated API server that interfaces with the APPUiO Control API and the IdP. The adapter may be implemented as Kubernetes Operator that interfaces with the four APPUiO Control API resources related to user management: Organizations and OrganizationMembers, Teams, and Users.

Some of the following requirements may be implemented by or through the IdP itself or by a third system.

Organizations

For each Organization and the corresponding OrganizationMembers resource

  • The adapter must make sure that an equivalent OpenShift Group with the same name exists on every APPUiO Zone.

  • The adapter must make sure that the users referenced in the corresponding OrganizationMembers object are part of this Group.

  • The adapter must make sure that no other users are part of this Group.

  • The adapter should write the actual members of the corresponding IdP group to the status field of the OrganizationMembers object.

  • The adapter must make sure that the corresponding Group is removed on Organization deletion.

  • The organization name must also be in the groups claim of the OIDC token provided to the APPUiO Control API for all organization members.

The adapter should provide the option to import existing groups from the IdP. If this feature is provided

Imports might not be required if the resources are virtual and the IdP is the authoritative source.
  • The adapter must create Organization resources for groups in the IdP that represent organizations if a corresponding Organization does not exist.

  • The adapter must update the corresponding OrganizationMembers resource of a newly created Organization to represent the members of the group in the IdP.

  • The adapter must not edit existing Organization or OrganizationMembers resources as part of an import.

  • The adapter should provide means to set RBAC for imported organizations, so that one or more users can manage the Organization in the APPUiO Control API.

  • The adapter may mark imported organizations as externally managed.

The adapter may provide the option to mark one or more Organizations as to be managed externally by the IdP. This means the Organization and OrganizationMembers resources are read-only and updated to the state in the external system. If this feature is provided

  • The adapter must handle all Organization marked with the annotation appuio.io/external: "true" as externally managed.

  • The spec fields of Organization and OrganizationMembers resources of externally managed organizations must be updated periodically to reflect the state in the IdP.

  • The spec fields of Organization and OrganizationMembers resources of externally managed organizations must be reverted when modified through the APPUiO Control API.

  • The adapter must prevent the deletion of externally managed organizations through the APPUiO Control API.

  • When the group is deleted through the IdP, the adapter should remove the corresponding Organization resource.

Users

For each IdP user that represents an APPUiO user

  • The adapter must make sure that there is a User resource in the APPUiO Control API.

  • The adapter must make sure that when deleting an IdP user the corresponding User resource is deleted.

  • The adapter should write user information from the IdP such as email or displayName to the status of the User resource.

For each User resource

  • The adapter must make sure that the users default organization name specified in the User resources spec is written to an annotation appuio.io/default-organization on the corresponding OpenShift User resource on every APPUiO Zone.

Teams

For each Team resource

  • The adapter must make sure that an equivalent OpenShift Group exists on every APPUiO Zone and that the Group is prefixed with name of the Organization containing the team.

  • The adapter must make sure that the users referenced in the Team object are part of this group.

  • The adapter must make sure that no other users are part of this group.

  • The adapter should write the actual members of the group to the status field of the Team object.

  • The adapter must make sure that the corresponding group is removed on Team deletion.

  • The prefixed team name must also be in the groups claim of the OIDC token provided to the APPUiO Control API for all team members.

The adapter should provide the option to import existing groups from the IdP. If this feature is provided

Imports might not be required if the resources are virtual and the IdP is the authoritative source.
  • The adapter must create Team resources for groups in the IdP that represent teams if a corresponding Team does not exist.

  • The created Team must reference all the members of the group in the IdP.

  • The created Team must be in the Namespace of the organization containing the team.

  • The adapter must not edit existing Team resources as part of an import.

  • The adapter may mark imported teams as externally managed.

The adapter may provide the option to mark one or more Teams as to be managed externally by the IdP. This means the Team resource is read-only and updated to the state in the external system. If this feature is provided

  • The adapter must handle all Teams marked by with the annotation appuio.io/external: "true" as externally managed.

  • The spec fields of externally managed Teams must be updated periodically to reflect the state in the IdP.

  • The spec fields of externally managed Teams must be reverted when modified through the APPUiO Control API.

  • The adapter must prevent the deletion externally managed teams through the APPUiO Control API.

  • When the group is deleted through the IdP, the adapter should remove the corresponding Team resource.

Organization Adapter at VSHN

VSHN started out with an operator but VSHN grew increasingly unhappy with the sync complexity of having two sources of truth.

We are now in the process of replacing the operator with a Kubernetes aggregated API server. This allows us to reduce sync complexity and to provide a more consistent user experience.

VSHN IDP integration

The new adapter will live in the control-api repository and will be a part of the control-api deployment. Different IDPs can be supported by implementing a Go interface like for the ERP integration.

The first resource that will be virtualized will be the User resource. We see the biggest sync skew there and it is the most important resource for the user experience.

The VSHN-managed APPUiO Cloud instance uses the APPUiO Keycloak Adapter.

We’re currently using Group Sync Operator to sync groups from Keycloak to OpenShift. With the implementation of UsageProfiles we now have good experience with multi event-source reconciliation and we’ll let the APPUiO Cloud Agent sync the groups from the control-api to the zone. The addition of watching changes should improve the user experience by making most portal operations instant.

The adapter also imports Keycloak users as User resources. Changes to the User resource’s spec is added to the Keycloak user’s attributes. These attributes are then synced to the APPUiO Zones by the Attribute Sync Controller.

We’re currently using Attribute Sync Controller to sync the default organization to the zones. We’ll let the APPUiO Cloud Agent sync the default organization to the zones and implement watching changes in the control API to improve the user experience.

The Keycloak adapter also supports periodic imports of new Keycloak groups as Organizations.