Skip to content

IBM Cloud IAM Kubernetes Operator provides a user-friendly Operator for IKS and OpenShift to automate scenarios for managing access to IBM Cloud Resources via Kubernetes CRD-Based APIs.

License

IBM/ibmcloud-iam-operator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status Go Report Card GoDoc

IBM Cloud's IAM Access Policy Management with Kubernetes Operators

Index:

  1. High-level problem statement
  2. Requirements
  3. Installing the IBM Cloud IAM operator
  4. Removing the IBM Cloud IAM operator
  5. Using the IBM Cloud IAM Operator
  6. For security reasons: Using a Management Namespace
  7. Managing Access Groups, Custom Roles or Access Policies
  8. Access Policy Reconciliation rules
  9. Tagging IAM Operator owned resources
  10. Examples
  11. Testing
  12. Impact Statement

High-level problem statement

On IBM Public Cloud, Identity and Access Management (IAM) is used to give access permissions so that entities can interact with resources. These access policies are set via the CLI or on the Console and typically require many gestures (retrieving API keys/tokens, creating user groups, adding users to group, obtaining subject and target IDs, copy and pasting, etc...). 

IBM Cloud IAM Kubernetes Operator provides a user-friendly Operator for IKS and OpenShift to automate scenarios for managing access to IBM Cloud Resources via Kubernetes CRD-Based APIs:

  1. For access groups & memberships,
  2. For custom roles,
  3. For access policies, and
  4. For authorization policies

This will give users few advantages:

  • The operator makes it easier to specify access groups, custom roles, access & authorization policies at a high level in a Kubernetes YAML declaratively,
  • The operator automates interactions with IAM APIs without requiring the user to know specifics,
  • The operator enforces access groups, custom roles, access & authorization policies via the operator's desired-state management. For example, if a user is moved out of a group accidentally, the operator would move them back and remediate the issue,
  • The operator integrates IBM Cloud IAM tightly with Kubernetes' built-in support for RBAC.

Requirements

The operator can be installed on any Kubernetes cluster with version >= 1.11.

You need an IBM Cloud account and the IBM Cloud CLI.

You need also to have the kubectl CLI already configured to access your cluster.

Before installing the operator, you need to login to your IBM cloud account with the IBM Cloud CLI:

ibmcloud login

and set a default target environment for your resources with the command:

ibmcloud target --cf -g default

This will use the IBM Cloud ResourceGroup default. To specify a different ResourceGroup, use the following command:

ibmcloud target -g <resource-group>

Notice that the org and space must be included, even if no Cloud Foundry services will be instantiated.

Installing the IBM Cloud IAM Operator

To install the latest release of the IAM operator, run the following script:

curl -sL https://raw.githubusercontent.com/IBM/ibmcloud-iam-operator/master/hack/install-operator.sh | bash  

The script above first creates an IBM Cloud API Key and stores it in a Kubernetes secret that can be accessed by the operator, then it sets defaults such as the default resource group and region used to provision IBM Cloud Services; finally, it deploys the operator in your cluster.

Removing the IBM Cloud IAM Operator

To remove the operator, run the following script:

curl -sL https://raw.githubusercontent.com/IBM/ibmcloud-iam-operator/master/hack/uninstall-operator.sh | bash 

Using the IBM Cloud IAM Operator

1. Access Group Yaml Elements [NEW!]

The Access Group yaml includes the following elements:

Spec Fields Is required Format/Type Comments
Name Yes string Specify the name of the new access group to be created
Description Yes string Specify a description for this new access group
UserEmails No []string Specify the email IDs of the IAM Users who will be members of this new group
ServiceIDs No []string Specify the IAM IDs of Services that will be members of this new group e.g "ServiceId-3b9f026a-eb6e-495f-b104-95232d0c4a59"

2. Custom Role Yaml Elements [NEW!]

The Custom Role yaml includes the following elements:

Spec Fields Is required Format/Type Comments
RoleName Yes string Specify the name of the new custom role to be created e.g "COSAdmin"
ServiceClass Yes string Specify the name of the IBM Cloud service that is linked to this new role e.g "cloud-object-storage"
DisplayName Yes string Specify the display name of the new custom role to be created e.g "COS Admin"
Description Yes string Specify a description for this new custom role
Actions Yes []string Specify a list of actions that this role can perform (IAM actions as well as actions available for the service specified in ServiceClass)

3. Access Policy Yaml Elements

The Access Policy yaml includes the following elements:

Spec Fields Is required Format/Type Comments
Subject Yes Subject The type to specify the Subject of an access policy
Roles Yes Roles The type to specify a list of Roles of an access policy
Target Yes Target The type to specify the Target of an access policy
Subject Fields Is required Format/Type Comments
UserEmail No string Specify an email ID in this field if access policy is for one user only
ServiceID No string Specify a Service ID (ID from IAM) in this field if access policy is for one service only
AccessGroupID No string The type to specify an access group ID for an already existing access group
AccessGroupDef No AccessGroupDef The type to specify details for an operator managed access group

*You must specify only one of the above four fields as Subject per access policy yaml spec.

AccessGroupDef Fields Is required Format/Type Comments
AccessGroupName Yes string Specify the name of an access group custom resource running in the cluster
AccessGroupNamespace Yes string Specify the namespace of the access group custom resource running in the cluster
Roles Fields Is required Format/Type Comments
DefinedRoles No []string Specify a list of existing defined roles (platform and/or service) using their display names
CustomRolesDName No []string Specify a list of existing custom roles using their display names
CustomRolesDef No []CustomRolesDef The type to specify details for an operator managed custom role
CustomRolesDef Fields Is required Format/Type Comments
CustomRoleName Yes string Specify the name of a custom role custom resource running in the cluster
CustomRoleNamespace Yes string Specify the namespace of the custom role custom resource running in the cluster
Target Fields Is required Format/Type Comments
ResourceGroup No string Specify a Resource Group like, "Default"
ServiceClass No string Specify a name of IBM Cloud shared service like, "cloud-object-storage"
ServiceID No string Specify the ServiceID of an instance of the service in ServiceClass like "ServiceID-xyz"
ResourceName No string Specify the name of a resource in a shared service like, "bucket"
ResourceID No string Specify the ResourceID of the resource in ResourceName like, "my-cos-bucket" (Not an ID)
ResourceKey No string Specify the attribute of a resource as a key in a shared service like, "namespace"
ResourceValue No string Specify the value of the ResourceKey like, "dev" (Not an ID)

4. Authorization Policy Yaml Elements

The Authorization Policy yaml includes the following elements:

Spec Fields Is required Format/Type Comments
Source Yes Info The type to specify the Source of an authorization policy
Roles Yes []string The type to specify a list of Roles of an authorization policy
Target Yes Info The type to specify the Target of an authorization policy
Subject Fields Is required Format/Type Comments
ResourceGroup No string Specify a Resource Group like, "Default". Mutually exclusive with ServiceID
ServiceClass No string Specify a name of IBM Cloud shared service like, "cloud-object-storage"
ServiceID No string Specify the ServiceID of an instance of the service in ServiceClass like "ServiceID-xyz". Mutually exclusive with ResourceGroup
ResourceName No string Specify the name of a resource in a shared service like, "bucket"
ResourceID No string Specify the ResourceID of the resource in ResourceName like, "my-cos-bucket" (Not an ID)
ResourceKey No string Specify the attribute of a resource as a key in a shared service like, "namespace"
ResourceValue No string Specify the value of the ResourceKey like, "dev" (Not an ID)
Target Fields Is required Format/Type Comments
ResourceGroup No string Specify a Resource Group like, "Default". Mutually exclusive with ServiceID
ServiceClass No string Specify a name of IBM Cloud shared service like, "cloud-object-storage"
ServiceID No string Specify the ServiceID of an instance of the service in ServiceClass like "ServiceID-xyz". Mutually exclusive with ResourceGroup
ResourceName No string Specify the name of a resource in a shared service like, "bucket"
ResourceID No string Specify the ResourceID of the resource in ResourceName like, "my-cos-bucket" (Not an ID)
ResourceKey No string Specify the attribute of a resource as a key in a shared service like, "namespace"
ResourceValue No string Specify the value of the ResourceKey like, "dev" (Not an ID)

Each paramater is treated as a RawExtension by the Operator and parsed into JSON.

The IBM Cloud IAM Operator needs an account context, which indicates the api-key and the details of the IBM Public Cloud account to be used for service instantiation. The api-key is contained in a Secret called secret-ibmcloud-iam-operator that is created when the IBM Cloud IAM Operator is installed. Details of the account (such as organization, space, resource group) are held in a ConfigMap called config-ibmcloud-iam-operator. To find the secret and configmap the IBM Cloud Operator first looks at the namespace of the resource being created, and if not found, in a management namespace (see below for more details on management namespaces). If there is no management namespace, then the operator looks for the secret and configmap in the default namespace.

For security reasons: Using a Management Namespace

Different Kubernetes namespaces can contain different secrets secret-ibmcloud-iam-operator and configmap config-ibmcloud-iam-operator, corresponding to different IBM Public Cloud accounts. So each namespace can be set up for a different account.

In some scenarios, however, there is a need for hiding the api-keys from users. In this case, a management namespace can be set up that contains all the secrets and configmaps corresponding to each namespace, with a naming convention.

To configure a management namespace named safe, there must be a configmap named ibmcloud-iam-operator created in the same namespace as the IBM Cloud Operator itself. This configmap indicates the name of the management namespace, in a field namespace. To create such a config map, execute the following:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: ibmcloud-iam-operator
  namespace: <namespace where IBM Cloud IAM Operator has been installed>
  labels:
    app.kubernetes.io/name: ibmcloud-iam-operator
data:
  namespace: safe
EOF

This configmap indicates to the operator where to find the management namespace, in this case safe. Next the safe namespace needs to contain secrets and configmaps corresponding to each namespace that will contain access policies. The naming convention is as follows:

<namespace>-secret-ibmcloud-iam-operator
<namespace>-config-ibmcloud-iam-operator

These can be created similary to what is done in hack/configure-operator.sh.

If we create an access policy resource in a namespace XYZ, the IBM Cloud IAM Operator first looks in the XYZ namespace to find secret-ibmcloud-iam-operator and config-ibmcloud-iam-operator, for account context. If they are missing in XYZ, it looks for the ibmcloud-iam-operator configmap in the namespace where the operator is installed, to see if there is a management namespace. If there is, it looks in the management namespace for the secret and configmap with the naming convention: XYZ-secret-ibmcloud-iam-operator and XYZ-config-ibmcloud-iam-operator. If there is no management namespace, the operator looks in the default namespace for the secret and configmap (secret-ibmcloud-iam-operator and config-ibmcloud-iam-operator).

Managing Access Groups, Custom Roles, Access or Authorization Policies

Creating an Access Group, Custom Role, Access or Authorization Policy

You can create an access policy with name cosuserpolicy for user avarghese@us.ibm.com to access a Cloud Object Storage instance's bucket as an Administrator using the following custom resource written in an yaml file cosuserpolicy.yaml:

kind: AccessPolicy
metadata:
  name: cosuserpolicy
spec:
  subject:
    userEmail: avarghese@us.ibm.com
  roles:
    definedRoles:
      - Administrator
  target:
    resourceGroup: Default
    serviceClass: cloud-object-storage
    serviceID: 1cdd19ff-c033-4767-b6b7-4fe2fc58c6a1
    resourceName: bucket
    resourceID: cos-standard-ansu

and then run the command: kubectl create -f cosuserpolicy.yaml

To find the status of your access policy, you can run the command:

NAME                 STATUS   AGE
cosuserpolicy        Online   25s

You can create an authorization policy for cloud-object-storage services to be authorized to read key-protect instances using the following custom resource written in an yaml file coskmspolicy.yaml:

kind: AuthorizationPolicy
metadata:
  name: coskmsauthpolicy
spec:
  source:
    serviceClass: cloud-object-storage
  roles:
    - Reader
  target:
    serviceClass: kms

and then run the command: kubectl create -f coskmspolicy.yaml

To find the status of your authorization policy, you can run the command:

NAME                 STATUS   AGE
coskmspolicy        Online   25s

Here's another example to create all three custom resources: You can create an access policy with name demonewgrouppolicy for access group resource demonewgroup in namespace default to access an Event Stream instance's topic topic-ansu as a custom role ES Admin that is running in the cluster as a custom role resource democustomrole in namespace default using the following yaml file accesspolicy_example_EventStreams_demo.yaml :

kind: AccessGroup
metadata:
  name: demonewgroup
spec:
  name: demonewgroup
  description: A new access group to test access group controller
  userEmails:
      - avarghese@us.ibm.com
      - mvaziri@us.ibm.com
  serviceIDs:
    - ServiceId-3b9f026a-eb6e-495f-b104-95232d0c4a59
    - ServiceId-fa27c539-a6cf-41d2-8cb0-2916da5f8e8a   

---
apiVersion: ibmcloud.ibm.com/v1alpha1
kind: CustomRole
metadata:
  name: democustomrole
spec:
  roleName: ESAdmin
  serviceClass: messagehub
  displayName: ES Admin
  description: Event Streams admin is an admin that only has a subset of the privileges of an Admin role
  actions: 
    - iam.policy.create
    - iam.policy.update
    - messagehub.group.read

---
apiVersion: ibmcloud.ibm.com/v1alpha1
kind: AccessPolicy
metadata:
  name: demonewgrouppolicy
spec:
  subject:
    accessGroupDef: 
      accessGroupName: demonewgroup
      accessGroupNamespace: default
  roles: 
    definedRoles:
      - Viewer
    customRolesDef:
      - customRoleName: democustomrole
        customRoleNamespace: default
  target: 
    resourceGroup: Default    
    serviceClass: messagehub
    serviceID: 9f9d6641-d5ad-4fb2-8d49-c1e97bcfb631
    resourceName: topic
    resourceID: topic-ansu    

and then run the command: kubectl create -f accesspolicy_example_EventStreams_demo.yaml

To find the status of your custom resources, you can run the command:

NAME                 STATUS   AGE
demonewgroup        Online   25s

kubectl get customroles.ibmcloud 
NAME                 STATUS   AGE
democustomrole        Online   25s

kubectl get accesspolicies.ibmcloud 
NAME                 STATUS   AGE
demonewgrouppolicy        Online   25s

Updating an Access Group, Custom Role, Access or Authorization Policy

You can update an existing access policy custom resource, say, if you'd like to change an existing subject or role or resource target in an existing IAM access policy. You can either edit the yaml specification, and then run the command: kubectl apply -f cosuserpolicy.yaml

Or you can run the kubectl edit command directly to update the resource: kubectl edit accesspolicies.ibmcloud cosuserpolicy

And similarly, for access groups, custom roles and authorization policies.

Deleting an Access Group, Custom Role, Access or Authorization Policy

Deleting an access policy custom resource, deletes the access policy instance in IBM Cloud's IAM.

To delete an access policy with name cosuserpolicy, run:

kubectl delete accesspolicies.ibmcloud cosuserpolicy

The operator uses finalizers to remove the custom resource only after the access policy is deleted from IAM.

And similarly, for access groups, custom roles and authorization policies.

Access Policy Reconciliation rules

Deleting a IBM Cloud entity that is part of an access policy managed by an IAM Operator behaves as below:

  1. Deleting a IBM Cloud User (access policy subject) causes the access policy status to change to FAILED during the next reconciliation cycle. The IAM Operator does not control the creation of deleted IAM user entities.
  2. Deleting a IBM Cloud Service ID (access policy subject) - same as #1 above.
  3. Deleting a IBM Cloud existing Access Group ID (access policy subject) that was not created by the operator - same as #1 above
  4. Deleting a IBM Cloud Access Group (access policy subject) also managed by the operator leads to IAM operator recreating the access group during the next reconciliation cycle. The group's members and policy will also be fixed.
  5. Deleting a IBM Cloud Custom Role also managed by the operator leads to IAM operator recreating the custom role during the next reconciliation cycle.
  6. Deleting the IBM Cloud Access Policy itself managed by this operator leads to recreating the access policy during the next reconciliation cycle.

Tagging IAM Operator owned resources

In order to differentiate IBM Cloud IAM Operator managed resources from user controlled resources created via IBM Clous console UIs, REST APIs, IBM Cloud CLIs etc, the operator adds a prefix string "OPERATOR OWNED: " to the Description fields in both Custom Resource and Access Groups. Access Policies do not have a Description field provided by IAM today. Also, as of this operator's writing, IAM does not support a tag feature for its resources. Hence, why we have used free text field Description for defining the source of truth for operator managed resources.

Examples

You can find additional samples here.

Examples of creating access policies for various IBM Cloud Resources

  1. Mongodb,
  2. Redis,
  3. Postgres,
  4. Elastic Search,
  5. Cloudant,
  6. KeyProtect,
  7. Cloud Object Storage,
  8. COS buckets,
  9. Event Streams,
  10. Event-stream topics

Testing

How to run Unit Tests

make unittest

How to run End-to-end Tests

make e2etest

Learn more about how to contribute

Impact Statement

Operators are a cornerstone of OpenShift v4, and a key element of the OpenShift developer catalog and DevX. By advancing Operators technology, we expect to further reduce friction for developers and increase IBM Cloud Adoption, therefore having a direct impact on the IBM / Red Hat synergy.

About

IBM Cloud IAM Kubernetes Operator provides a user-friendly Operator for IKS and OpenShift to automate scenarios for managing access to IBM Cloud Resources via Kubernetes CRD-Based APIs.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published