Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial research #1

Closed
simonw opened this issue Nov 2, 2021 · 7 comments
Closed

Initial research #1

simonw opened this issue Nov 2, 2021 · 7 comments
Labels

Comments

@simonw
Copy link
Owner

simonw commented Nov 2, 2021

The goal of this tool is to provide a CLI for creating IAM access credentials - an access key and a secret key - that are restricted to either reading from a specific bucket, writing to a specific bucket or read/write to a specific bucket.

The goal is to never have to go through the manual process described in dogsheep/dogsheep-photos#4 ever again.

@simonw simonw added the research label Nov 2, 2021
@simonw
Copy link
Owner Author

simonw commented Nov 2, 2021

It looks like I need to create specific, dedicated users for this - because only users (not roles) can have long-living access key / secret credentials according to the FAQ at https://aws.amazon.com/iam/faqs/

@simonw
Copy link
Owner Author

simonw commented Nov 2, 2021

So if I want to create a bucket called my-bucket and get back an access key and secret that can read/write to that bucket it looks like the steps are:

  1. Create the bucket
  2. Create a dedicated user. Usernames can contain any ASCII characters and only need to be unique within that AWS account, so I'm going to default to s3:read-write:my-bucket
  3. Attach a policy to that user which says they can perform s3:* against arn:aws:s3:::mybucket/* (not sure if I can attach policies directly to users or if I have to attach them to a group and put the user in that group)
  4. Create a new access key for that user

Need to do all of this using boto3.

@simonw
Copy link
Owner Author

simonw commented Nov 2, 2021

CLI design:

s3-credentials create-for my-bucket

(I considered s3-credentials create but I think I like create-for better, it feels more readable)

This creates credentials for the specified bucket.

s3-credentials whoami

This outputs the result of iam.get_user()["User"] - just because it feels useful.

@simonw
Copy link
Owner Author

simonw commented Nov 2, 2021

How should the root credentials be passed?

I'm going to mostly leave this up to boto3, which defaults to looking for environment variables or a ~/.aws/config file according to https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials

But I will also support --access-key=xxx --access-secret=yyy.

@simonw
Copy link
Owner Author

simonw commented Nov 2, 2021

Some boto3 notes from my Jupyter notebook:

import boto3

s3 = boto3.resource("s3")
# Creating a bucket in a region
bucket = s3.create_bucket(
    Bucket="simonw-s3-credentials-test",
    CreateBucketConfiguration={"LocationConstraint": "us-west-1"}
)

# Listing all buckets
for b in s3.buckets.all():
    print(b)

# Listing all access keys
iam = boto3.client("iam")
paginator = iam.get_paginator("list_access_keys")
for response in paginator.paginate():
    print(response)

@simonw
Copy link
Owner Author

simonw commented Nov 2, 2021

iam.create_user() is the method for creating a new user.

From the docstring:

  response = client.create_user(
      Path='string',
      UserName='string',
      PermissionsBoundary='string',
      Tags=[
          {
              'Key': 'string',
              'Value': 'string'
          },
      ]
  )

Having an option to add tags - maybe --user-tag key value - feels useful.

That PermissionsBoundary thing is an interesting option. The docstring just says:

The ARN of the policy that is used to set the permissions boundary for the user.

Not particularly informative! But then I tracked down the documentation here:

https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html

This is a little more useful:

AWS supports permissions boundaries for IAM entities (users or roles). A permissions boundary is an advanced feature for using a managed policy to set the maximum permissions that an identity-based policy can grant to an IAM entity. An entity's permissions boundary allows it to perform only the actions that are allowed by both its identity-based policies and its permissions boundaries.

[...]

When you use a policy to set the permissions boundary for a user, it limits the user's permissions but does not provide permissions on its own. In this example, the policy sets the maximum permissions of ShirleyRodriguez as all operations in Amazon S3, CloudWatch, and Amazon EC2. Shirley can never perform operations in any other service, including IAM, even if she has a permissions policy that allows it.

I rather like the sound of this: being able to restrict these created user accounts to ONLY be able to operate within S3 seems like a great added defense in depth.

One catch: what format should these strings be?

GitHub code search showed me some examples, and also lead me to this file which looks like a list of default available policy ARNs: https://github.com/daviddawha/ArchivesSpaceDevUNR/blob/488b5b83f9ac66a6013e9a0a02d25734886dee02/gems/gems/fog-aws-2.0.0/lib/fog/aws/iam/default_policy_versions.json

Short version: it looks like the two magic strings I care about for this application are:

  • arn:aws:iam::aws:policy/AmazonS3FullAccess
  • arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

I'm going to apply these to created users by default, and offer a --user-permissions-boundary none option for not adding one.

@simonw
Copy link
Owner Author

simonw commented Nov 2, 2021

Further research is happening in other issues now.

@simonw simonw closed this as completed Nov 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant