Skip to content

Commit

Permalink
add vignette for working with s3 and iam together #27
Browse files Browse the repository at this point in the history
  • Loading branch information
sckott committed Feb 27, 2025
1 parent d59cc97 commit 13d0a48
Show file tree
Hide file tree
Showing 3 changed files with 355 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ vign_auth:
${RSCRIPT} -e "Sys.setenv(NOT_CRAN='true'); knitr::knit('auth.Rmd.og', output = 'auth.Rmd')";\
cd ..

vign_s3iam:
cd vignettes;\
${RSCRIPT} -e "Sys.setenv(NOT_CRAN='true')" \
-e "knitr::knit('s3iam.Rmd.og', output = 's3iam.Rmd')";\
sed "s/${AWS_ACCOUNT_ID}/*****/g" s3iam.Rmd > tmp && mv tmp s3iam.Rmd;\
cd ..

test:
SIXTYFOUR_RUN_LOCAL_ONLY_TESTS=true ${RSCRIPT} -e "devtools::test()"

Expand Down
192 changes: 192 additions & 0 deletions vignettes/s3iam.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
---
title: "Managing buckets in a small group of users"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Managing buckets in a small group of users}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---



A common use case is to manage a small group of users and their access to AWS resources. This can be done using the `sixtyfour` package, which provides a set of high-level functions to make your life easier.

## Installation


``` r
library(sixtyfour)
library(purrr)
```

## User groups

First, create two user groups - `admin` and `users` - with the `six_admin_setup()` function.




``` r
six_admin_setup(users_group = "myusers", admin_group = "myadmin")
#> ℹ whoami: *****
#> ℹ
#> ℹ myusers group created - add users to this group that do not require admin permissions
#> ℹ Added policies to the myusers group: AmazonRDSReadOnlyAccess, AmazonRedshiftReadOnlyAccess, AmazonS3ReadOnlyAccess,
#> AWSBillingReadOnlyAccess, and IAMReadOnlyAccess
#> ℹ
#> ℹ myadmin group created - add users to this group that require admin permissions
#> ℹ Added policies to the myadmin group: AdministratorAccess, Billing, CostOptimizationHubAdminAccess, AWSBillingReadOnlyAccess, and
#> AWSCostAndUsageReportAutomationPolicy
#> ℹ
#> ℹ Done!
```

## Users

Next, create five users - one in the `admin` group, three in the `users` group, and one not in either group.

The admin user:


``` r
name_admin <- random_user()
user_admin <- six_user_create(name_admin, copy_to_cb = FALSE)
#> ℹ Added policy UserInfo to UpstartCoding
#> ✔ Key pair created for UpstartCoding
#> ℹ AccessKeyId: *****
#> ℹ SecretAccessKey: *****
aws_user_add_to_group(name_admin, "myadmin")
```

The non-admin users:


``` r
users_non_admin <- map(1:3, \(x) {
six_user_create(random_user(), copy_to_cb = FALSE)
})
#> ℹ Added policy UserInfo to FumingMatron
#> ✔ Key pair created for FumingMatron
#> ℹ AccessKeyId: *****
#> ℹ SecretAccessKey: *****
#> ℹ Added policy UserInfo to ForkedBounds
#> ✔ Key pair created for ForkedBounds
#> ℹ AccessKeyId: *****
#> ℹ SecretAccessKey: *****
#> ℹ Added policy UserInfo to MemorableLustre
#> ✔ Key pair created for MemorableLustre
#> ℹ AccessKeyId: *****
#> ℹ SecretAccessKey: *****
invisible(map(users_non_admin, \(x) {
aws_user_add_to_group(x$UserName, "myusers")
}))
names_users <- map_chr(users_non_admin, \(x) x$UserName)
```

And last, create a user that is not part of either of the above groups.


``` r
name_user_wo <- random_user()
user_wo_access <- six_user_create(name_user_wo, copy_to_cb = FALSE)
#> ℹ Added policy UserInfo to PedestrianDoorst
#> ✔ Key pair created for PedestrianDoorst
#> ℹ AccessKeyId: *****
#> ℹ SecretAccessKey: *****
```

## Buckets and files

Create a bucket, and put a file in it.


``` r
bucket <- random_string("bucket")
demo_rds_file <- file.path(system.file(), "Meta/demo.rds")
six_bucket_upload(path = demo_rds_file, remote = bucket, force = TRUE)
#> [1] "s3://bucketqozlabhg/demo.rds"
```

## Check access

Then check access for the user that should not have access




``` r
withr::with_envvar(
c("AWS_REGION" = user_wo_access$AwsRegion,
"AWS_ACCESS_KEY_ID" = user_wo_access$AccessKeyId,
"AWS_SECRET_ACCESS_KEY" = user_wo_access$SecretAccessKey
),
aws_bucket_list_objects(bucket)
)
#> Error: AccessDenied (HTTP 403). User: arn:aws:iam::*****:user/PedestrianDoorst is not authorized to perform: s3:ListBucket on resource: "arn:aws:s3:::bucketqozlabhg" because no identity-based policy allows the s3:ListBucket action
```

User PedestrianDoorst does not have access (read or write), as intended.

Then check access for a user that should have read access:


``` r
withr::with_envvar(
c("AWS_REGION" = users_non_admin[[1]]$AwsRegion,
"AWS_ACCESS_KEY_ID" = users_non_admin[[1]]$AccessKeyId,
"AWS_SECRET_ACCESS_KEY" = users_non_admin[[1]]$SecretAccessKey
),
{
# read
aws_bucket_list_objects(bucket)

# write
links_rds_file <- file.path(system.file(), "Meta/links.rds")
six_bucket_upload(path = links_rds_file, remote = bucket, force = TRUE)
}
)
#> Error in `map()`:
#> ℹ In index: 1.
#> Caused by error:
#> ! AccessDenied (HTTP 403). User: arn:aws:iam::*****:user/FumingMatron is not authorized to perform: s3:PutObject on resource: "arn:aws:s3:::bucketqozlabhg/links.rds" because no identity-based policy allows the s3:PutObject action
```

User FumingMatron does have access for read and NOT for write, as intended.

And make sure the admin has read and write access


``` r
withr::with_envvar(
c("AWS_REGION" = user_admin$AwsRegion,
"AWS_ACCESS_KEY_ID" = user_admin$AccessKeyId,
"AWS_SECRET_ACCESS_KEY" = user_admin$SecretAccessKey
), {
# read
aws_bucket_list_objects(bucket)

# write
links_rds_file <- file.path(system.file(), "Meta/links.rds")
six_bucket_upload(path = links_rds_file, remote = bucket, force = TRUE)
}
)
#> [1] "s3://bucketqozlabhg/links.rds"
```

User UpstartCoding does have access for read and write, as intended.

## Cleanup

Then cleanup the users, groups and buckets:


``` r
# Users
map(c(name_admin, names_users, name_user_wo), six_user_delete)

# Groups
map(c("myadmin", "myusers"), six_group_delete)

# Bucket
six_bucket_delete(bucket, force = TRUE)
```
156 changes: 156 additions & 0 deletions vignettes/s3iam.Rmd.og
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
---
title: "Managing buckets in a small group of users"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Managing buckets in a small group of users}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
library(sixtyfour)
aws_configure(redacted = TRUE)
```

A common use case is to manage a small group of users and their access to AWS resources. This can be done using the `sixtyfour` package, which provides a set of high-level functions to make your life easier.

## Installation

```{r setup}
library(sixtyfour)
library(purrr)
```

## User groups

First, create two user groups - `admin` and `users` - with the `six_admin_setup()` function.

```{r delete-admin-user-groups, echo=FALSE}
if (aws_group_exists("myadmin")) without_verbose(six_group_delete("myadmin"))
if (aws_group_exists("myusers")) without_verbose(six_group_delete("myusers"))
```

```{r setup-admin-user-groups}
six_admin_setup(users_group = "myusers", admin_group = "myadmin")
```

## Users

Next, create five users - one in the `admin` group, three in the `users` group, and one not in either group.

The admin user:

```{r create-admin-user, results='hide'}
name_admin <- random_user()
user_admin <- six_user_create(name_admin, copy_to_cb = FALSE)
aws_user_add_to_group(name_admin, "myadmin")
```

The non-admin users:

```{r create-non-admin-users}
users_non_admin <- map(1:3, \(x) {
six_user_create(random_user(), copy_to_cb = FALSE)
})
invisible(map(users_non_admin, \(x) {
aws_user_add_to_group(x$UserName, "myusers")
}))
names_users <- map_chr(users_non_admin, \(x) x$UserName)
```

And last, create a user that is not part of either of the above groups.

```{r create-wo-access-user}
name_user_wo <- random_user()
user_wo_access <- six_user_create(name_user_wo, copy_to_cb = FALSE)
```

## Buckets and files

Create a bucket, and put a file in it.

```{r create-bucket}
bucket <- random_string("bucket")
demo_rds_file <- file.path(system.file(), "Meta/demo.rds")
six_bucket_upload(path = demo_rds_file, remote = bucket, force = TRUE)
```

## Check access

Then check access for the user that should not have access

```{r sleep-so-it-all-works, echo=FALSE, results="hide"}
Sys.sleep(15)
```

```{r verify-user-wo, error=TRUE}
withr::with_envvar(
c("AWS_REGION" = user_wo_access$AwsRegion,
"AWS_ACCESS_KEY_ID" = user_wo_access$AccessKeyId,
"AWS_SECRET_ACCESS_KEY" = user_wo_access$SecretAccessKey
),
aws_bucket_list_objects(bucket)
)
```

User `r user_wo_access$UserName` does not have access (read or write), as intended.

Then check access for a user that should have read access:

```{r verify-user, error=TRUE}
withr::with_envvar(
c("AWS_REGION" = users_non_admin[[1]]$AwsRegion,
"AWS_ACCESS_KEY_ID" = users_non_admin[[1]]$AccessKeyId,
"AWS_SECRET_ACCESS_KEY" = users_non_admin[[1]]$SecretAccessKey
),
{
# read
aws_bucket_list_objects(bucket)

# write
links_rds_file <- file.path(system.file(), "Meta/links.rds")
six_bucket_upload(path = links_rds_file, remote = bucket, force = TRUE)
}
)
```

User `r users_non_admin[[1]]$UserName` does have access for read and NOT for write, as intended.

And make sure the admin has read and write access

```{r verify-admin}
withr::with_envvar(
c("AWS_REGION" = user_admin$AwsRegion,
"AWS_ACCESS_KEY_ID" = user_admin$AccessKeyId,
"AWS_SECRET_ACCESS_KEY" = user_admin$SecretAccessKey
), {
# read
aws_bucket_list_objects(bucket)

# write
links_rds_file <- file.path(system.file(), "Meta/links.rds")
six_bucket_upload(path = links_rds_file, remote = bucket, force = TRUE)
}
)
```

User `r user_admin$UserName` does have access for read and write, as intended.

## Cleanup

Then cleanup the users, groups and buckets:

```{r cleanup, message=FALSE, results='hide'}
# Users
map(c(name_admin, names_users, name_user_wo), six_user_delete)

# Groups
map(c("myadmin", "myusers"), six_group_delete)

# Bucket
six_bucket_delete(bucket, force = TRUE)
```

0 comments on commit 13d0a48

Please sign in to comment.