Skip to content

Instantly share code, notes, and snippets.

@cbodley
Created February 21, 2024 14:54
Show Gist options
  • Save cbodley/b8730ffd5140805aee83b31ad8c3ea97 to your computer and use it in GitHub Desktop.
Save cbodley/b8730ffd5140805aee83b31ad8c3ea97 to your computer and use it in GitHub Desktop.
IAM accounts in Ceph

iam accounts

what is IAM? from https://docs.aws.amazon.com/IAM/latest/APIReference/welcome.html:

AWS Identity and Access Management (IAM) is a web service for securely controlling access to AWS services. With IAM, you can centrally manage users, security credentials such as access keys, and permissions that control which AWS resources users and applications can access.

each aws account has its own set of users and policies. when you log into the aws website, there's an iam dashboard where you can view/manage all of the account's resources and policies. aws also provides a rest api with all of the same functionality

it's that iam rest api that we implement here for ceph. someday the ceph dashboard might expose this stuff too

$ aws iam create-user --user-name Alice
{
    "User": {
        "Path": "/",
        "UserName": "Alice",
        "UserId": "b580aa8e-14c7-4b6a-9dac-a30c640244b6",
        "Arn": "arn:aws:iam::RGW63136524507535818:user/Alice",
        "CreateDate": "2024-02-07T00:15:45.162786+00:00"
    }
}
$ aws iam create-access-key --user-name Alice
{
    "AccessKey": {
        "UserName": "Alice",
        "AccessKeyId": "JBNLYD5BDNRVV64J02E8",
        "Status": "Active",
        "SecretAccessKey": "SnHoE700kdNuT22K8Bhy2iL3DwZU0sUSDI1gUXHr",
        "CreateDate": "2024-02-07T00:16:34.679316+00:00"
    }
}
$ aws iam attach-user-policy --user-name Alice --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

accounts in ceph

without accounts, the cluster admin has to create all users and manage all policies. this doesn't scale well for service providers using ceph, and doesn't give end-users any of the power/flexibility offered by iam identity policy

the ceph cluster admin still has to create accounts and account-root users with radosgw-admin, but gives those root user credentials (access/secret keys) to an end-users so they can manage all users/keys/groups/roles/policies for their account

accounts are optional in ceph. users continue to behave the same unless they belong to an account

existing tenant-based iam apis

  • supports Role, RolePolicy, UserPolicy, OpenIDConnectProvider apis
  • roles and oidc-providers are tenant-wide
  • the rest apis require admin capabilities to use (ex. "roles=*" or "user-policy=read")
  • the identity policies from RolePolicy and UserPolicy follow the rules from Evaluating policies within a single account, not Cross-account policy evaluation logic. this means they can grant full read/write permissions on other users' resources

account-based iam apis

the iam apis work differently when the requesting identity belongs to an account:

  • iam resources (users/roles/groups/oidc-providers) are scoped to the account. can only view/modify resources that belong to your account
  • do not require admin capabilities. account-root user has access by default, and can grant access to other users/groups/roles in the account via identity policy
  • adds support for User, AccessKey, Group, GroupPolicy apis
  • adds support for managed policies like AmazonS3FullAccess and AmazonS3ReadOnlyAccess (and same for iam, sns, sts)
    • these are only supported for account users because they give blanket permissions over all resources, so rely on cross-account policy evaluation to make sense

users created by iam:CreateUser are represented the same way as normal rgw users, except that they have a non-empty account_id

account user permissions

  • account-root user has full permissions on the account's resources (including s3 buckets and objects) by default, unless some policy explicitly denies access
  • non-root users and roles have no permissions by default. some identity policy must be attached before they're authorized to make any API requests
  • cross-account policy evaluation rules apply when accessing resources not owned by the account. this requires both:
    • an identity policy must grant access to the resource (this is implicit for the account-root), and
    • a resource policy or acl must grant access to the requesting user or account

AssumeRole and accounts

  • when you assume a role that belongs to an account, you have that account's view of iam resources
  • the role's account determines whether cross-account vs. single-account policy evaluation rules apply
  • s3 buckets and objects created by an assumed role are owned by the role's account instead of the original user that assumed the role

implementation

ownership

rgw_owner as std::variant<rgw_user, rgw_account_id> for acls and ownership

get owner from s->auth.identity instead of s->user to handle AssumeRole correctly

metadata layout

.rgw.meta:accounts pool

  • account.{account-id} stores RGWAccountInfo
  • name.{tenant}${account-name} stores RGWUID which redirects to account.{account-id}
  • buckets.{account-id} stores list of buckets for s3::ListBuckets and accumulates bucket stats (as {user}.buckets does for users)
  • users.{account-id} stores list of users for iam:ListUsers
  • roles.{account-id} stores list of roles for iam:ListRoles
  • groups.{account-id} stores list of groups for iam:ListGroups

.rgw.meta:groups pool

  • info.{group-id} stores RGWGroupInfo
  • name.{tenant}${group-name} stores RGWUID which redirects to info.{group-id}
  • users.{group-id} stores list of users for iam:GetGroup

rest apis

updated existing apis with account support:

  • rgw_rest_role.cc for Role/RolePolicy
  • rgw_rest_oidc_provider.cc for OpenIDConnectProvider
  • rgw_rest_user_policy.cc for UserPolicy

new rest apis:

  • rgw_rest_iam_group.cc for Group/GroupPolicy
  • rgw_rest_iam_user.cc for User/AccessKey
  • rgw_rest_account.cc for /admin/account
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment