{"skill":{"slug":"r2-cli","displayName":"Cloudflare R2 CLI","summary":"Minimal Python CLI for secure upload, download, list, and delete operations on Cloudflare R2 storage using AWS Signature V4 authentication.","description":"# Cloudflare R2 CLI Skill\n\n## Skill Metadata\n\n```yaml\nname: \"r2-cli\"\ndescription: \"A minimal CLI tool for interacting with Cloudflare R2 storage using Python. Supports upload, download, list, and delete operations via S3-compatible API with AWS Signature V4.\"\nversion: \"1.0.6\"\nauthor:\n  username: \"@zororaka00\"\n  name: \"Web3 Hungry\"\n  x_account: \"https://x.com/web3hungry\"\ncategory: \"storage\"\ntags: [\"cloudflare\", \"python\", \"r2\", \"storage\"]\nsource: \"r2.py\"\ncredentials:\n  required: true\n  type: \"environment\"\n  variables:\n    - CF_R2_ACCOUNT_ID\n    - CF_R2_ACCESS_KEY_ID\n    - CF_R2_SECRET_ACCESS_KEY\n    - CF_R2_BUCKET\n    - CF_R2_REGION\nruntime:\n  language: \"python\"\n  version: \"3.11+\"\n  dependencies:\n    - \"defusedxml>=0.7.1\"\n  env:\n    - name: \"CF_R2_ACCOUNT_ID\"\n      required: true\n      description: \"Cloudflare account ID\"\n    - name: \"CF_R2_ACCESS_KEY_ID\"\n      required: true\n      description: \"R2 access key ID\"\n    - name: \"CF_R2_SECRET_ACCESS_KEY\"\n      required: true\n      description: \"R2 secret access key\"\n    - name: \"CF_R2_BUCKET\"\n      required: true\n      description: \"R2 bucket name\"\n    - name: \"CF_R2_REGION\"\n      required: false\n      description: \"Region (default: auto)\"\n\nrequired_env_vars:\n  - CF_R2_ACCOUNT_ID\n  - CF_R2_ACCESS_KEY_ID\n  - CF_R2_SECRET_ACCESS_KEY\n  - CF_R2_BUCKET\n  - CF_R2_REGION\nprimaryEnv: CF_R2_ACCESS_KEY_ID\nprimarySecretEnv: CF_R2_SECRET_ACCESS_KEY\n```\n\n## Overview\n\nThis skill provides a minimal CLI tool for interacting with Cloudflare R2 storage using Python.\nThe script (`r2.py`) implements upload, download, list, and delete operations via the Cloudflare R2 S3-compatible API.\n\nIt is designed for secure usage in restricted environments with minimal dependencies while following modern security best practices.\n\n## Dependencies\n\n* Python **3.11+**\n* Requires: `defusedxml` (for secure XML parsing)\n\n> The tool primarily uses the Python standard library. Only `defusedxml` is required to harden XML parsing against known attacks.\n\n## Installation\n\nNo package installation is required for the CLI itself.\n\nIf `defusedxml` is not already available:\n\n```bash\npip install defusedxml\n```\n\n## Features\n\n* Upload objects to a bucket\n* Download objects from a bucket\n* List objects in a bucket\n* Delete objects from a bucket\n* AWS Signature V4 compatible authentication (HMAC SHA256)\n* Secure credential handling via environment variables\n* Hardened HTTP client with HTTPS-only enforcement\n* Safe XML parsing using defused XML protections\n\n## Prerequisites\n\n* Python **3.11+**\n* Cloudflare account with R2 enabled\n* Bucket created in Cloudflare R2\n* API keys with appropriate permissions (least privilege)\n* Bucket name must be DNS-compliant (lowercase letters, numbers, hyphens, 3–63 characters, no underscores)\n\n## Environment Variables\n\n| Variable                  | Description              | Example                                |\n| ------------------------- | ------------------------ | -------------------------------------- |\n| `CF_R2_ACCOUNT_ID`        | Cloudflare account ID    | `123e4567-e89b-12d3-a456-426614174000` |\n| `CF_R2_ACCESS_KEY_ID`     | R2 access key ID         | `AKIAxxxxxxxxxxxx`                     |\n| `CF_R2_SECRET_ACCESS_KEY` | R2 secret key            | `xxxxxxxxxxxxxxxxxxxxxxxx`             |\n| `CF_R2_BUCKET`            | Bucket name              | `my-r2-bucket`                         |\n| `CF_R2_REGION`            | Region (default: `auto`) | `auto`                                 |\n\n`CF_R2_REGION` behavior:\n\n* `auto` (default): automatically selects the appropriate region for Cloudflare R2.\n* Custom value: you may specify a region string if required by your environment (for example `us-east-1` for compatibility scenarios).\n\n## Environment Setup\n\nThis tool reads credentials directly from operating system environment variables.\nSet the variables globally before running the CLI.\n\n### Linux / macOS (bash / zsh)\n\n```bash\nexport CF_R2_ACCOUNT_ID=\"your_account_id\"\nexport CF_R2_ACCESS_KEY_ID=\"your_access_key\"\nexport CF_R2_SECRET_ACCESS_KEY=\"your_secret_key\"\nexport CF_R2_BUCKET=\"your_bucket_name\"\nexport CF_R2_REGION=\"auto\"\n```\n\n**Security Note:** These credentials should only be set temporarily in the current session. For production environments, use secure secret management solutions.\n\n### Windows (PowerShell)\n\n```powershell\n$env:CF_R2_ACCOUNT_ID=\"your_account_id\"\n$env:CF_R2_ACCESS_KEY_ID=\"your_access_key\"\n$env:CF_R2_SECRET_ACCESS_KEY=\"your_secret_key\"\n$env:CF_R2_BUCKET=\"your_bucket_name\"\n$env:CF_R2_REGION=\"auto\"\n```\n\n**Security Note:** These credentials should only be set temporarily in the current session. For production environments, use secure secret management solutions.\n\n### Recommended Secure Credential Management\n\nFor production environments, consider using:\n- **Cloudflare Workers Secrets** (for Cloudflare environments)\n- **AWS Secrets Manager** (if using AWS)\n- **HashiCorp Vault** (enterprise secret management)\n- **Docker Secrets** (for containerized deployments)\n- **Kubernetes Secrets** (for Kubernetes environments)\n- **OS-level keyring** (e.g., `keyring` Python package)\n\n### Verify Environment\n\n```bash\necho $CF_R2_ACCOUNT_ID\n```\n\nIf a value prints, the environment is configured correctly.\n\n> **Important:** Never commit credentials to version control. Use environment variables provided by your operating system or a secure secret management solution.\n\n## Usage\n\n```bash\n# Upload a file\npython r2.py upload --file local_file.txt --key remote_file.txt\n\n# Download a file\npython r2.py download --key remote_file.txt --file local_file.txt\n\n# List objects\npython r2.py list\n\n# Delete an object\npython r2.py delete --key remote_file.txt\n```\n\n## Security Best Practices\n\n* Never commit credentials to version control.\n* Use environment variables managed by your operating system, container runtime, or secret manager.\n* Apply least-privilege access when creating API keys.\n* Rotate keys regularly and revoke compromised keys.\n* All credentials are loaded at runtime from environment variables.\n* HTTPS is strictly enforced and hostnames are validated to prevent unexpected network access.\n* XML responses are parsed using the **defusedxml** library to prevent XXE and entity expansion attacks.\n* Errors are handled without exposing sensitive information such as credentials or secrets.\n\n## Credential Security\n\nNever store credentials inside source code or configuration files committed to version control.\nUse environment variables provided by your operating system or a secure secret management solution.\n\n## Future Improvements\n\n* Multipart uploads for large objects\n* Retry with exponential backoff\n* Progress indicators\n* Bucket management commands\n* Streaming upload/download to reduce memory usage\n","tags":{"cloudflare":"1.0.6","latest":"1.0.6","python":"1.0.6","r2":"1.0.6","storage":"1.0.6"},"stats":{"comments":0,"downloads":866,"installsAllTime":32,"installsCurrent":0,"stars":0,"versions":7},"createdAt":1771656152491,"updatedAt":1778491597572},"latestVersion":{"version":"1.0.6","createdAt":1771659057692,"changelog":"Version 1.0.6\n\n- Added required_env_vars, primaryEnv, and primarySecretEnv entries to the skill metadata for clearer environment variable usage and secret designation.\n- No changes to code or functional behavior; documentation updated only.","license":null},"metadata":null,"owner":{"handle":"zororaka00","userId":"s1772arktepfj8py25kyfyv4hx884q42","displayName":"Web3 Hungry","image":"https://avatars.githubusercontent.com/u/24318495?v=4"},"moderation":null}