CloudVault is a self-hosted web app for people who live in S3 and AWS. A single Go binary does two jobs at once:
- A modern object browser for any S3-compatible storage — AWS S3, MinIO, Ceph, Wasabi, Cloudflare R2 and friends. Browse, upload, download, share, presign and bulk-manage objects across as many accounts as you need, each picked from the sidebar.
- A read-only AWS key inspector that tells you in seconds exactly what an access key can see and do: its identity, enabled regions, reachable services, a resource inventory and a security-posture audit — without touching a single resource.
Credentials are entered once as reusable keys, attached to endpoints through connections, and everything — keys, connections and the scanned region list — is managed in the UI and persisted to a single SQLite file. No config files, no restarts, no credentials in environment variables.
Based on cloudlena/s3manager. CloudVault started as a fork of that project and has since grown into a distinct application (reusable keys, a standalone AWS key inspector, managed connections & regions, a rebuilt design system). Huge thanks to the original authors — the upstream project is licensed under Apache-2.0 and that license is retained here.
- Modern, responsive UI with a sidebar and light/dark mode, split into two menus: Storage (connections & buckets) and AWS Tool (Keys, Regions, Key inspector)
- Keys (AWS Tool) — reusable, named S3/AWS credentials managed in one place; connections reference a key and the inspector operates on one. Each key carries a cloud provider (auto-detected AWS/GCP or set manually) and remembers its last inspection — open a key to review the saved capability report (
/keys/{id}) - Manage S3 connections from the UI (
/connections) — add, edit, delete and test connections without restarting; a connection = a key + endpoint/region/TLS/proxy, persisted in SQLite - Per-connection proxy support — route S3 traffic for a connection through an
http,httpsorsocks5forward proxy (with optional credentials) - Key inspector (AWS Tool) — a read-only capability scan of a key (saved or entered ad-hoc): caller identity (STS), enabled regions, and which of ~27 AWS services the key can access (S3, EC2, IAM, Lambda, DynamoDB, KMS, ECS/EKS, Route 53, CloudFront, CloudTrail, GuardDuty, …) checked across every managed region. For a valid key it also reports a resource inventory (counts + samples), a security-posture audit (public buckets, users without MFA, old access keys, security groups open to the world, missing CloudTrail,
*admin), IAM account counts and the granted actions parsed from the key's own (and its groups') policies. The full report is saved to the key. Makes no changes to any resource. - List all buckets in your account
- Create a new bucket
- List all objects in a bucket
- Upload new objects to a bucket
- Download object from a bucket
- Delete an object in a bucket
Keys, connections and the region list are managed entirely in the UI and persisted in SQLite — there is no environment-variable connection configuration.
Connections and their credentials are configured in the UI (see below). The application itself is configured with these environment variables:
PORT: The port the app should listen on (defaults to8080)ALLOW_DELETE: Enable buttons to delete objects (defaults totrue)FORCE_DOWNLOAD: Add response headers for object downloading instead of opening in a new tab (defaults totrue)LIST_RECURSIVE: List all objects in buckets recursively (defaults tofalse)BUCKET_NAME: Restrict the buckets view to a single named bucket (defaults to unset, showing all buckets)DB_PATH: Path to the SQLite database that stores keys, connections and regions (defaults to/data/cloudvault.db; mount a volume there to persist them)ALLOW_CONNECTION_MANAGEMENT: Enable adding/editing/deleting keys, connections and regions and running the inspector from the UI (defaults totrue;falsemakes the whole app read-only)SSE_TYPE: Specified server side encryption (defaults blank) Valid values can beSSE,KMS,SSE-Call others values don't enable the SSESSE_KEY: The key needed for SSE method (only forKMSandSSE-C)TIMEOUT: The read and write timeout in seconds (default to600- 10 minutes)ROOT_URL: A root URL prefix if running behind a reverse proxy (defaults to unset)
Open AWS Tool → Keys to add a reusable credential (name + access key id/secret, or an IAM
role). Then open /connections to add a connection that references a key plus an endpoint
(blank = AWS s3.amazonaws.com), a region picked from the managed list, TLS options and an
optional proxy (URL + credentials). The Endpoint may be left blank to use AWS
(s3.amazonaws.com), and the Region is a dropdown from the managed region list. Use
Test to verify a connection before saving. Editing a key updates every connection that
references it. Everything is stored in SQLite (DB_PATH) and reloaded on startup.
AWS Tool → Regions is the single place to maintain the AWS region list. It seeds a handful of common regions and you can add/remove more. The list populates the region dropdown on the connection form and defines exactly which regions the Key inspector scans.
AWS Tool → Key inspector runs a read-only scan of a key — either a saved key or credentials
entered ad-hoc — completely independently of any S3 connection. For AWS keys it reports the caller
identity (sts:GetCallerIdentity), the enabled regions (ec2:DescribeRegions), a service-by-service
access matrix (probing a cheap read-only API of S3, EC2, IAM, Lambda, DynamoDB, SQS, SNS, CloudWatch,
Logs, KMS, Secrets Manager, RDS, CloudFormation) across every managed region — each regional
service shows a chip per region — the attached IAM policy names, and the S3 buckets with their
regions. Every probe is a List*/Describe*/Get* call — nothing is created, modified or
deleted. Gated behind ALLOW_CONNECTION_MANAGEMENT.
- Run
make build - Execute the created binary (
bin/cloudvault) and visit http://localhost:8080
-
Run
docker run -p 8080:8080 -v "$PWD/data:/data" salingnh/cloudvaultThen open http://localhost:8080, add a Key and a Connection in the UI.
CloudVault is a single stateless container plus a SQLite volume, so any standard Deployment +
PersistentVolumeClaim works. If you previously ran the upstream project, the community
s3manager Helm chart can be adapted by
pointing its image at salingnh/cloudvault.
If there are multiple S3 users/accounts in a site then multiple instances of CloudVault can be
run in Kubernetes and exposed behind a single nginx reverse proxy ingress. Each instance can be
run with a ROOT_URL environment variable set that accounts for the reverse proxy location.
If the nginx configuration block looks like:
location /teamx/ {
proxy_pass http://cloudvault-teamx:8080/;
auth_basic "teamx";
auth_basic_user_file /conf/teamx-htpasswd;
}
location /teamy/ {
proxy_pass http://cloudvault-teamy:8080/;
<other nginx settings>
}Then the instance behind the cloudvault-teamx service has ROOT_URL=teamx and the instance
behind cloudvault-teamy has ROOT_URL=teamy. Other nginx settings can be applied to each
location. The nginx instance can be hosted on some reachable address and reverse proxy to the
different S3 accounts.
- Run
make lint
- Run
make test
- Run
make build-image
There is an example docker-compose.yml file that spins up a MinIO S3 service and CloudVault. You can try it by issuing the following command:
$ docker compose upCloudVault is then available at http://localhost:18080. On first run, open AWS Tool → Keys
to add a key (for the bundled MinIO use cloudvault / cloudvault), then Storage → Manage
connections to add a connection (endpoint s3:9000, SSL off).
CloudVault is built on top of the excellent cloudlena/s3manager by Lena Fuhrimann and contributors, and is distributed under the same Apache-2.0 license (see LICENSE). If you just need a lightweight S3 bucket browser, do check out the original.
