From eae5593cbe6f6be9ccd30398f1d2be9c7cb93561 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Wed, 18 Dec 2024 21:48:35 -0800 Subject: [PATCH] get-public-access-block and set-public-access-block, closes #92 --- docs/help.md | 90 +++++++++++++++++++++++++------- docs/other-commands.md | 35 +++++++++++++ s3_credentials/cli.py | 113 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 219 insertions(+), 19 deletions(-) diff --git a/docs/help.md b/docs/help.md index 70b9477..07a5d26 100644 --- a/docs/help.md +++ b/docs/help.md @@ -33,25 +33,27 @@ Options: --help Show this message and exit. Commands: - create Create and return new AWS credentials for specified... - debug-bucket Run a bunch of diagnostics to help debug a bucket - delete-objects Delete one or more object from an S3 bucket - delete-user Delete specified users, their access keys and their... - get-bucket-policy Get bucket policy for a bucket - get-cors-policy Get CORS policy for a bucket - get-object Download an object from an S3 bucket - get-objects Download multiple objects from an S3 bucket - list-bucket List contents of bucket - list-buckets List buckets - list-roles List roles - list-user-policies List inline policies for specified users - list-users List all users for this account - policy Output generated JSON policy for one or more buckets - put-object Upload an object to an S3 bucket - put-objects Upload multiple objects to an S3 bucket - set-bucket-policy Set bucket policy for a bucket - set-cors-policy Set CORS policy for a bucket - whoami Identify currently authenticated user + create Create and return new AWS credentials for... + debug-bucket Run a bunch of diagnostics to help debug a bucket + delete-objects Delete one or more object from an S3 bucket + delete-user Delete specified users, their access keys and... + get-bucket-policy Get bucket policy for a bucket + get-cors-policy Get CORS policy for a bucket + get-object Download an object from an S3 bucket + get-objects Download multiple objects from an S3 bucket + get-public-access-block Get the public access settings for an S3 bucket + list-bucket List contents of bucket + list-buckets List buckets + list-roles List roles + list-user-policies List inline policies for specified users + list-users List all users for this account + policy Output generated JSON policy for one or more... + put-object Upload an object to an S3 bucket + put-objects Upload multiple objects to an S3 bucket + set-bucket-policy Set bucket policy for a bucket + set-cors-policy Set CORS policy for a bucket + set-public-access-block Configure public access settings for an S3 bucket. + whoami Identify currently authenticated user ``` ## s3-credentials create --help @@ -262,6 +264,25 @@ Options: -a, --auth FILENAME Path to JSON/INI file containing credentials --help Show this message and exit. ``` +## s3-credentials get-public-access-block --help + +``` +Usage: s3-credentials get-public-access-block [OPTIONS] BUCKET + + Get the public access settings for an S3 bucket + + Example usage: + + s3-credentials get-public-access-block my-bucket + +Options: + --access-key TEXT AWS access key ID + --secret-key TEXT AWS secret access key + --session-token TEXT AWS session token + --endpoint-url TEXT Custom endpoint URL + -a, --auth FILENAME Path to JSON/INI file containing credentials + --help Show this message and exit. +``` ## s3-credentials list-bucket --help ``` @@ -540,6 +561,37 @@ Options: -a, --auth FILENAME Path to JSON/INI file containing credentials --help Show this message and exit. ``` +## s3-credentials set-public-access-block --help + +``` +Usage: s3-credentials set-public-access-block [OPTIONS] BUCKET + + Configure public access settings for an S3 bucket. + + Example: + + s3-credentials set-public-access-block my-bucket --block-public-acls false + + To allow full public access to the bucket, use the --allow-public-access flag: + + s3-credentials set-public-access-block my-bucket --allow-public-access + +Options: + --block-public-acls BOOLEAN Block public ACLs for the bucket (true/false). + --ignore-public-acls BOOLEAN Ignore public ACLs for the bucket + (true/false). + --block-public-policy BOOLEAN Block public bucket policies (true/false). + --restrict-public-buckets BOOLEAN + Restrict public buckets (true/false). + --allow-public-access Set all public access settings to false + (allows full public access). + --access-key TEXT AWS access key ID + --secret-key TEXT AWS secret access key + --session-token TEXT AWS session token + --endpoint-url TEXT Custom endpoint URL + -a, --auth FILENAME Path to JSON/INI file containing credentials + --help Show this message and exit. +``` ## s3-credentials whoami --help ``` diff --git a/docs/other-commands.md b/docs/other-commands.md index 4bd49a1..f2b3191 100644 --- a/docs/other-commands.md +++ b/docs/other-commands.md @@ -603,3 +603,38 @@ Or for the common case of setting a policy to allow GET access to all buckets: ```bash s3-credentials set-bucket-policy my-bucket --allow-all-get ``` + +## get-public-access-block + +The `get-public-access-block` command displays the current public access block configuration for a bucket: +```bash +s3-credentials get-public-access-block my-bucket +``` +Example output: + +```json +{ + "BlockPublicAcls": false, + "IgnorePublicAcls": false, + "BlockPublicPolicy": false, + "RestrictPublicBuckets": false +} +``` + +## set-public-access-block + +The `set-public-access-block` command can be used to set the public access block configuration for a bucket: +```bash +s3-credentials set-public-access-block my-bucket \ + --block-public-acls true \ + --ignore-public-acls true \ + --block-public-policy true \ + --restrict-public-buckets true +``` +Each of the above options accepts `true` or `false`. + +You can use the `--allow-public-access` shortcut to set everything to `false` in one go: +```bash +s3-credentials set-public-access-block my-bucket \ + --allow-public-access +``` diff --git a/s3_credentials/cli.py b/s3_credentials/cli.py index 49d3bff..306f749 100644 --- a/s3_credentials/cli.py +++ b/s3_credentials/cli.py @@ -1525,6 +1525,119 @@ def delete_objects(bucket, keys, prefix, silent, dry_run, **boto_options): ) +@cli.command() +@click.argument("bucket", required=True) +@common_boto3_options +def get_public_access_block(bucket, **boto_options): + """ + Get the public access settings for an S3 bucket + + Example usage: + + s3-credentials get-public-access-block my-bucket + """ + s3 = make_client("s3", **boto_options) + try: + response = s3.get_public_access_block(Bucket=bucket) + except botocore.exceptions.ClientError as e: + raise click.ClickException(e) + click.echo(json.dumps(response["PublicAccessBlockConfiguration"], indent=4)) + + +@cli.command() +@click.argument("bucket", required=True) +@click.option( + "--block-public-acls", + type=bool, + default=None, + help="Block public ACLs for the bucket (true/false).", +) +@click.option( + "--ignore-public-acls", + type=bool, + default=None, + help="Ignore public ACLs for the bucket (true/false).", +) +@click.option( + "--block-public-policy", + type=bool, + default=None, + help="Block public bucket policies (true/false).", +) +@click.option( + "--restrict-public-buckets", + type=bool, + default=None, + help="Restrict public buckets (true/false).", +) +@click.option( + "--allow-public-access", + is_flag=True, + help="Set all public access settings to false (allows full public access).", +) +@common_boto3_options +def set_public_access_block( + bucket, + block_public_acls, + ignore_public_acls, + block_public_policy, + restrict_public_buckets, + allow_public_access, + **boto_options, +): + """ + Configure public access settings for an S3 bucket. + + Example: + + s3-credentials set-public-access-block my-bucket --block-public-acls false + + To allow full public access to the bucket, use the --allow-public-access flag: + + s3-credentials set-public-access-block my-bucket --allow-public-access + """ + s3 = make_client("s3", **boto_options) + + # Default public access block configuration + public_access_block_config = {} + + if allow_public_access: + # Set all settings to False if --allow-public-access is provided + public_access_block_config = { + "BlockPublicAcls": False, + "IgnorePublicAcls": False, + "BlockPublicPolicy": False, + "RestrictPublicBuckets": False, + } + else: + # Add values only if they are explicitly provided + if block_public_acls is not None: + public_access_block_config["BlockPublicAcls"] = block_public_acls + if ignore_public_acls is not None: + public_access_block_config["IgnorePublicAcls"] = ignore_public_acls + if block_public_policy is not None: + public_access_block_config["BlockPublicPolicy"] = block_public_policy + if restrict_public_buckets is not None: + public_access_block_config["RestrictPublicBuckets"] = ( + restrict_public_buckets + ) + + if not public_access_block_config: + raise click.ClickException( + "No valid options provided. Use --help to see available options." + ) + + # Apply the public access block configuration to the bucket + s3.put_public_access_block( + Bucket=bucket, PublicAccessBlockConfiguration=public_access_block_config + ) + + click.echo( + f"Updated public access block settings for bucket '{bucket}': {public_access_block_config}", + err=True, + ) + + def output(iterator, headers, nl, csv, tsv): if nl: for item in iterator: