Have less be More
Have Less, Be More

Overview

Scaling IAM (Identity and Access Management) policies for Independent Software Vendor (ISV) customers is a strategic challenge, especially when managing access permissions at scale across multiple client environments in one OCI tenancy. I recently helped many such customers streamline and minimize IAM policies using resource tags. The goal is to minimize IAM policies by writing broad attribute-based (tag-based) access-control policies that compare attributes assigned to the principal and the target resources. Have fewer/lesser policies that do more or precisely what they are designed to do. However, we do not compromise on the least privileged model. An entity or a resource should only be permitted to perform the smallest set of actions necessary to fulfill a specific task.

In this blog, I talk about two use cases that I implemented using tag based IAM policies.

Pre-requisites for using tags based IAM policies

  1. Only security Administrator should be able to manage tag namespaces.
  2. Only terraform runner or Infrastructure-as-a-code script principal should be able to use tag namespaces used in IAM policies.
  3. Do not use ‘manage all-resources’ policies for any target. Otherwise, the principal group can manipulate tags on the target resources and gain access.
  4. As much as possible, use compartment level default tags to eliminate human and configuration errors in infrastructure-as-a-code script.

Note: For this blog, I will refer to OCI customer’s customer environment as tenant.

Use case – 1

Requirements

  1. All instances for a specific tenant/customer can read buckets for that specific tenant/customer in shared storage compartment.
  2. All instances for a specific tenant can read secrets for that specific tenant.

 

Design

  1. Create a compartment for every tenant and create resources for that tenant inside tenant compartment.
  2. Create Enterprise tag namespace with Tenant tag key to capture tenant name for every resource.
  3. For tenant compartments, create compartment default tags to capture tenant name in Enterprise.Tenant tag.
  4. For every target resource like bucket and secret, tag target them with tenant name in Enterprise.Tenant tag.

Policies

  1. Assuming InfoSec group is the security administrator group. Only that group should have access to manage tags.

Allow group InfoSec to manage tag-namespaces in tenancy

Allow group InfoSec to manage policies in tenancy

Allow group InfoSec to use users in tenancy

Allow group InfoSec to manage groups in tenancy where all {target.group.name != ‘Administrators’, target.group.name != ‘InfoSec’}

  1. Assuming terraform-runner is a group used for user principals or service users to execute infrastructure-as-a-code terraform scripts, write below policies.

Allow group terraform-runner to use tag-namespaces in tenancy

Allow group terraform-runner to manage instance-family in compartment Tenants

Allow group terraform-runner to manage virtual-network-family in compartment Tenants

Allow group terraform-runner to manage volume-family in compartment Tenants

Allow group terraform-runner to manage object-family in compartment Storage

Allow group terraform-runner to manage secret-family in compartment Tenants

Allow group terraform-runner to manage key-family in compartment Tenants

  1. Now for tenant resources to be able to use secrets and read objects, write below policies.

Allow any-user to use object-family in compartment Storage where request.principal.compartment.tag.Enterprise.Tenant = target.resource.tag.Enterprise.Tenant

Allow any-user to use secret-family in compartment Tenants where request.principal.compartment.tag.Enterprise.Tenant = target.resource.tag.Enterprise.Tenant

Use Case – 2

Second use case is little more complicated. There are a few types of services for every tenant. Each service can only read buckets and secrets of that service for the given tenant.

Requirements

  1. All instances of Admin service for a specific tenant can read Admin buckets for that specific tenant in shared storage compartment.
  2. All instances of Sales service for a specific tenant can read Sales buckets for that specific tenant in shared storage compartment.
  3. All instances of Supply service for a specific tenant can read Supply buckets for that specific tenant in shared storage compartment.
  4. All instances for a specific tenant can read shared services buckets for that specific tenant in shared storage compartment.
  5. All instances for a specific tenant can read secrets for that specific tenant in the tenant compartment.

 

 

Design

  1. Create a compartment for every tenant and create resources for that tenant inside tenant compartment.
  2. Create Enterprise tag namespace with Tenant and Service tag keys to capture tenant name and service name for every resource.
  3. For tenant compartments, create compartment default tags to capture tenant name in Enterprise.Tenant tag.
  4. For every resource in tenant compartment, tag resources with the service type Enterprise.Service tag.
  5. For every target resource like bucket and secret, tag them with tenant name in Enterprise.Tenant tag.
  6. For every target resource that is specific to a service type, tag them with service type in Enterprise.Service tag.
  7. For shared bucket resources tag Enterprise.Service tag key with ‘Shared’ value.

Dynamic Groups

Create three dynamic groups for instances of three service types.

 

  1. Dynamic group AdminInstances

All {tag.Enterprise.Service.value=’Admin’}

  1. Dynamic group SalesInstances

All {tag.Enterprise.Service.value=’Sales’}

  1. Dynamic group SupplyInstances

All {tag.Enterprise.Service.value=’Supply’}

Policies

  1. Assuming InfoSec group is the security administrator group. Only that group should have access to manage tags.

Allow group InfoSec to manage tag-namespaces in tenancy

Allow group InfoSec to manage policies in tenancy

Allow group InfoSec to use users in tenancy

Allow group InfoSec to manage groups in tenancy where all {target.group.name != ‘Administrators’, target.group.name != ‘InfoSec’}

  1. Assuming terraform-runner is a group used for user principals or service users to execute infrastructure-as-a-code terraform scripts, write below policies.

Allow group terraform-runner to use tag-namespaces in tenancy

Allow group terraform-runner to manage instance-family in compartment Tenants

Allow group terraform-runner to manage virtual-network-family in compartment Tenants

Allow group terraform-runner to manage object-family in compartment Storage

Allow group terraform-runner to manage secret-family in compartment Tenants

Allow group terraform-runner to manage key-family in compartment Tenants

  1. Now for tenant resources to be able to use secrets and read objects, write below policies.

Allow dynamic-group AdminInstances to use object-family in compartment Storage where all {request.principal.compartment.tag.Enterprise.Tenant=target.resource.tag.Enterprise.Tenant, target.resource.tag.Enterprise.Service=’Admin’}

Allow dynamic-group SalesInstances to use object-family in compartment Storage where all {request.principal.compartment.tag.Enterprise.Tenant=target.resource.tag.Enterprise.Tenant, target.resource.tag.Enterprise.Service=’Sales’}

Allow dynamic-group SupplyInstances to use object-family in compartment Storage where all {request.principal.compartment.tag.Enterprise.Tenant=target.resource.tag.Enterprise.Tenant, target.resource.tag.Enterprise.Service=’Supply’}

Allow any-user to use object-family in compartment Storage where all {request.principal.compartment.tag.Enterprise.Tenant=target.resource.tag.Enterprise.Tenant, target.resource.tag.Enterprise.Service=’Shared’}

Allow dynamic-group AdminInstances to use secret-family in compartment Tenants where all {request.principal.compartment.tag.Enterprise.Tenant=target.resource.tag.Enterprise.Tenant, target.resource.tag.Enterprise.Service=’Admin’}

Allow dynamic-group SalesInstances to use secret-family in compartment Tenants where all {request.principal.compartment.tag.Enterprise.Tenant=target.resource.tag.Enterprise.Tenant, target.resource.tag.Enterprise.Service=’Sales’}

Allow dynamic-group SupplyInstances to use secret-family in compartment Tenants where all {request.principal.compartment.tag.Enterprise.Tenant=target.resource.tag.Enterprise.Tenant, target.resource.tag.Enterprise.Service=’Supply’}

Resources

  1. OCI IAM Policies
  2. Tag based access control
  3. Tagging Security
  4. Tagging best practices
  5. Scaling IAM policies for IAM groups