This API provides simple restful API access to Amazon's S3 service.
GET /v1/s3/ping
GET /v1/s3/version
GET /v1/s3/metrics
# Managing buckets
POST /v1/s3/{account}/buckets
GET /v1/s3/{account}/buckets
HEAD /v1/s3/{account}/buckets/{bucket}
GET /v1/s3/{account}/buckets/{bucket}
PUT /v1/s3/{account}/buckets/{bucket}
DELETE /v1/s3/{account}/buckets/{bucket}
GET /v1/s3/{account}/buckets/{bucket}/duck
# Managing bucket users
POST /v1/s3/{account}/buckets/{bucket}/users
GET /v1/s3/{account}/buckets/{bucket}/users
GET /v1/s3/{account}/buckets/{bucket}/users/{user}
PUT /v1/s3/{account}/buckets/{bucket}/users/{user}
DELETE /v1/s3/{account}/buckets/{bucket}/users/{user}
# Managing websites
POST /v1/s3/{account}/websites
HEAD /v1/s3/{account}/websites/{website}
GET /v1/s3/{account}/websites/{website}
PUT /v1/s3/{account}/websites/{website}
PATCH /v1/s3/{account}/websites/{website}
DELETE /v1/s3/{account}/websites/{website}
GET /v1/s3/{account}/websites/{website}/duck
# Managing website users
POST /v1/s3/{account}/websites/{website}/users
GET /v1/s3/{account}/websites/{website}/users
GET /v1/s3/{account}/websites/{website}/users/{user}
PUT /v1/s3/{account}/websites/{website}/users/{user}
DELETE /v1/s3/{account}/websites/{website}/users/{user}
Authentication is accomplished via a pre-shared key. This is done via the X-Auth-Token
header.
When creating a bucket, by default, an IAM policy (of the same name) is created with full access to that bucket...
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:DeleteBucketWebsite",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetAccelerateConfiguration",
"s3:GetBucketAcl",
"s3:GetBucketCORS",
"s3:GetBucketLocation",
"s3:GetBucketLogging",
"s3:GetBucketNotification",
"s3:GetBucketPolicy",
"s3:GetBucketTagging",
"s3:GetBucketVersioning",
"s3:GetBucketWebsite",
"s3:GetLifecycleConfiguration",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectVersion",
"s3:GetObjectVersionAcl",
"s3:GetReplicationConfiguration",
"s3:ListAllMyBuckets",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListBucketVersions",
"s3:ListMultipartUploadParts",
"s3:PutAccelerateConfiguration",
"s3:PutBucketAcl",
"s3:PutBucketCORS",
"s3:PutBucketLogging",
"s3:PutBucketNotification",
"s3:PutBucketPolicy",
"s3:PutBucketRequestPayment",
"s3:PutBucketTagging",
"s3:PutBucketVersioning",
"s3:PutBucketWebsite",
"s3:PutLifecycleConfiguration",
"s3:PutReplicationConfiguration",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl",
"s3:ReplicateDelete",
"s3:ReplicateObject",
"s3:RestoreObject"
],
"Resource": [
"arn:aws:s3:::my-awesome-bucket"
]
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-awesome-bucket/*"
]
}
]
}
and a group is created with that policy attached. To allow access to a bucket, create a bucket user
by POSTing to the /v1/s3/{account}/buckets/{bucket}/users
endpoint.
GET /v1/s3/{account}/buckets
Response Code | Definition |
---|---|
200 OK | return the list of buckets |
400 Bad Request | badly formed request |
404 Not Found | account not found |
500 Internal Server Error | a server error occurred |
POST `/v1/s3/{account}/buckets
{
"Tags": [
{
"Key": "Application",
"Value": "HowToGet"
},
{
"Key": "COA",
"Value": "Take.My.Money.$$$$"
},
{
"Key": "CreatedBy",
"Value": "Big Bird"
}
],
"Lifecycle": "deep-archive",
"BucketInput": {
"Bucket": "foobarbucketname"
}
}
{
"Bucket": "/foobarbucketname",
"Policy": {
"Arn": "arn:aws:iam::12345678910:policy/foobarbucketname-BktAdmPlc",
"AttachmentCount": 0,
"CreateDate": "2019-03-01T15:33:52Z",
"DefaultVersionId": "v1",
"Description": null,
"IsAttachable": true,
"Path": "/",
"PermissionsBoundaryUsageCount": 0,
"PolicyId": "ABCDEFGHI12345678",
"PolicyName": "foobarbucketname-BktAdmPlc",
"UpdateDate": "2019-03-01T15:33:52Z"
},
"Group": {
"Arn": "arn:aws:iam::12345678910:group/foobarbucketname-BktAdmGrp",
"CreateDate": "2019-03-01T15:33:52Z",
"GroupId": "GROUPID123",
"GroupName": "foobarbucketname-BktAdmGrp",
"Path": "/"
}
}
Response Code | Definition |
---|---|
202 Accepted | creation request accepted |
400 Bad Request | badly formed request |
403 Forbidden | you don't have access to bucket |
404 Not Found | account not found |
409 Conflict | bucket or iam policy already exists |
429 Too Many Requests | service or rate limit exceeded |
500 Internal Server Error | a server error occurred |
503 Service Unavailable | an AWS service is unavailable |
Updating a bucket currently only supports updating the bucket's tags
PUT /v1/s3/{account}/buckets/foobarbucketname
{
"Tags": [
{ "Key": "Application", "Value": "HowToGet" },
{ "Key": "COA", "Value": "Take.My.Money.$$$$" },
{ "Key": "CreatedBy", "Value": "Big Bird" }
]
}
Response Code | Definition |
---|---|
200 OK | deleted bucket |
400 Bad Request | badly formed request |
500 Internal Server Error | a server error occurred |
HEAD /v1/s3/{account}/buckets/foobarbucketname
Response Code | Definition |
---|---|
200 OK | bucket exists |
403 Forbidden | you don't have access to bucket |
404 Not Found | account or bucket not found |
500 Internal Server Error | a server error occurred |
GET /v1/s3/{account}/buckets/foobarbucketname
{
"Tags": [
{ "Key": "Application", "Value": "HowToGet" },
{ "Key": "COA", "Value": "Take.My.Money.$$$$" },
{ "Key": "CreatedBy", "Value": "Big Bird" }
],
"Logging": {
"TargetBucket": "foobar-buckets-access-logs",
"TargetGrants": null,
"TargetPrefix": "s3/foobarbucketname/"
},
"Empty": true
}
Response Code | Definition |
---|---|
200 OK | okay |
404 Not Found | bucket was not found |
400 Bad Request | badly formed request |
500 Internal Server Error | a server error occurred |
DELETE `/v1/s3/{account}/buckets/{bucket}
Response Code | Definition |
---|---|
200 OK | deleted bucket |
400 Bad Request | badly formed request |
403 Forbidden | you don't have access to bucket |
404 Not Found | account or bucket not found |
409 Conflict | bucket is not empty |
500 Internal Server Error | a server error occurred |
POST `/v1/s3/{account}/buckets/{bucket}/users
{
"User": { "UserName": "somebucketuser" },
}
{
"User": {
"Arn": "arn:aws:iam::12345678910:user/somebucketuser",
"CreateDate": "2019-03-01T16:11:00Z",
"PasswordLastUsed": null,
"Path": "/",
"PermissionsBoundary": null,
"Tags": null,
"UserId": "AIDAJJSBBEAVOQLFAAUCG",
"UserName": "somebucketuser"
},
"AccessKey": {
"AccessKeyId": "ABCDEFGHIJ12345678",
"CreateDate": "2019-03-01T16:11:00Z",
"SecretAccessKey": "sssshimsupersekretdonttellanyoneyousawme",
"Status": "Active",
"UserName": "somebucketuser"
}
}
Response Code | Definition |
---|---|
200 OK | user created |
400 Bad Request | badly formed request |
403 Forbidden | you don't have access to bucket |
404 Not Found | account or user not found when creating key |
409 Conflict | user already exists |
429 Too Many Requests | service or rate limit exceeded |
500 Internal Server Error | a server error occurred |
GET /v1/s3/{account}/bucket/users/{user}
{
"User": {
"Arn": "arn:aws:iam::12345678910:user/somebucketuser",
"CreateDate": "2019-03-19T18:31:14Z",
"PasswordLastUsed": null,
"Path": "/",
"PermissionsBoundary": null,
"Tags": null,
"UserId": "AIDAJJSBBEAVOQLFAAUCG",
"UserName": "somebucketuser"
},
"AccessKeys": [
{
"AccessKeyId": "AKIAJTGA5ITTTJ7WOR7A",
"CreateDate": "2019-03-19T18:31:14Z",
"Status": "Active",
"UserName": "somebucketuser"
}
],
"Groups": [
{
"Arn": "arn:aws:iam::12345678910:group/somebucketuser",
"CreateDate": "2019-03-19T14:20:01Z",
"GroupId": "AGPAJ6SYNPMFP6O5KXQJW",
"GroupName": "somebucketuser-BktAdmGrp",
"Path": "/"
}
],
"Policies": [
{
"Arn": "arn:aws:iam::12345678910:policy/somebucketuser-BktAdmPlc",
"PolicyName": "somebucketuser-BktAdmPlc"
}
]
}
PUT /v1/s3/{account}/buckets/{bucket}/users/{user}
{
"DeletedKeyIds": [
"ABCDEFGHIJK123456789"
],
"AccessKey": {
"AccessKeyId": "LMNOPQRSTUVW123456789",
"CreateDate": "2019-03-01T16:14:07Z",
"SecretAccessKey": "sssshimsupersekretdonttellanyoneyousawme",
"Status": "Active",
"UserName": "someuser-admin1"
}
}
Response Code | Definition |
---|---|
200 OK | keys reset successfully |
400 Bad Request | badly formed request |
403 Forbidden | you don't have access to delete the user |
404 Not Found | account or user not found |
429 Too Many Requests | service or rate limit exceeded |
500 Internal Server Error | a server error occurred |
GET `/v1/s3/{account}/buckets/{bucket}/users/{user}
[
{
"Arn": "arn:aws:iam::12345678910:user/someuser-admin1",
"CreateDate": "2019-03-01T16:11:00Z",
"PasswordLastUsed": null,
"Path": "/",
"PermissionsBoundary": null,
"Tags": null,
"UserId": "ABCDEFGHI12345678",
"UserName": "someuser-admin1"
},
{
"Arn": "arn:aws:iam::12345678910:user/someuser-admin2",
"CreateDate": "2019-03-01T16:11:00Z",
"PasswordLastUsed": null,
"Path": "/",
"PermissionsBoundary": null,
"Tags": null,
"UserId": "ZYXWUTS87654321",
"UserName": "someuser-admin2"
}
]
DELETE `/v1/s3/{account}/buckets/{bucket}/users/{user}
Response Code | Definition |
---|---|
200 OK | deleted user |
400 Bad Request | badly formed request |
403 Forbidden | you don't have access to delete the user |
404 Not Found | account or user not found |
429 Too Many Requests | service or rate limit exceeded |
500 Internal Server Error | a server error occurred |
POST /v1/s3/{account}/websites
{
"Tags": [
{ "Key": "Application", "Value": "HowToGet" },
{ "Key": "COA" "Value", "Value": "Take.My.Money.$$$$" },
{ "Key": "CreatedBy", "Value": "Big Bird" }
],
"BucketInput": {
"Bucket": "foobar.bulldogs.cloud"
},
"WebsiteConfiguration": {
"IndexDocument": { "Suffix": "index.html" }
}
}
{
"Bucket": "/foobar.bulldogs.cloud",
"Policy": {
"Arn": "arn:aws:iam::12345678910:policy/foobar.bulldogs.cloud-BktAdmPlc",
"AttachmentCount": 0,
"CreateDate": "2019-03-01T15:33:52Z",
"DefaultVersionId": "v1",
"Description": null,
"IsAttachable": true,
"Path": "/",
"PermissionsBoundaryUsageCount": 0,
"PolicyId": "ABCDEFGHI12345678",
"PolicyName": "foobar.bulldogs.cloud-BktAdmPlc",
"UpdateDate": "2019-03-01T15:33:52Z"
},
"Group": {
"Arn": "arn:aws:iam::12345678910:group/foobar.bulldogs.cloud-BktAdmGrp",
"CreateDate": "2019-03-01T15:33:52Z",
"GroupId": "GROUPID123",
"GroupName": "foobar.bulldogs.cloud-BktAdmGrp",
"Path": "/"
},
"Distribution": {
"ARN": "arn:aws:cloudfront::12345678910:distribution/ABCDEFGHIJKL",
"DistributionConfig": {
"Aliases": {
"Items": [
"foobar.bulldogs.cloud"
],
"Quantity": 1
},
"CallerReference": "12345678-9012-3456-6789-094d26464c6c",
"Comment": "foobar.bulldogs.cloud",
"DefaultCacheBehavior": {
...
"TargetOriginId": "foobar.bulldogs.cloud",
"TrustedSigners": {
"Enabled": false,
"Items": null,
"Quantity": 0
},
"ViewerProtocolPolicy": "redirect-to-https"
},
"DefaultRootObject": "index.html",
"Enabled": true,
"HttpVersion": "http2",
"IsIPV6Enabled": true,
"Logging": {
"Bucket": "",
"Enabled": false,
"IncludeCookies": false,
"Prefix": ""
},
"Origins": {
"Items": [
{
...
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginKeepaliveTimeout": 5,
"OriginProtocolPolicy": "http-only",
"OriginReadTimeout": 30,
"OriginSslProtocols": {
"Items": [
"TLSv1",
"TLSv1.1",
"TLSv1.2"
],
"Quantity": 3
}
},
"DomainName": "foobar.bulldogs.cloud.s3-website-us-east-1.amazonaws.com",
"Id": "foobar.bulldogs.cloud",
"OriginPath": "",
"S3OriginConfig": null
}
],
"Quantity": 1
},
"PriceClass": "PriceClass_100",
"Restrictions": {
"GeoRestriction": {
"Items": [
"US"
],
"Quantity": 1,
"RestrictionType": "whitelist"
}
},
"ViewerCertificate": {
"ACMCertificateArn": "arn:aws:acm:us-east-1:12345678910:certificate/111111111-2222-3333-4444-55555555555",
"Certificate": "arn:aws:acm:us-east-1:12345678910:certificate/111111111-2222-3333-4444-55555555555",
"CertificateSource": "acm",
"CloudFrontDefaultCertificate": null,
"IAMCertificateId": null,
"MinimumProtocolVersion": "TLSv1.1_2016",
"SSLSupportMethod": "sni-only"
},
...
},
"DomainName": "1234567abcdef.cloudfront.net",
"Id": "ABCDEFGHIJKLMNOP",
"InProgressInvalidationBatches": 0,
"LastModifiedTime": "2019-05-09T10:50:35.79Z",
"Status": "InProgress"
},
"DnsChange": {
"Comment": "Created by s3-api",
"Id": "/change/C176E51B123456",
"Status": "PENDING",
"SubmittedAt": "2019-05-09T10:50:37.194Z"
}
}
Response Code | Definition |
---|---|
202 Accepted | creation request accepted |
400 Bad Request | badly formed request |
403 Forbidden | you don't have access to bucket |
404 Not Found | account not found |
409 Conflict | bucket or iam policy already exists |
429 Too Many Requests | service or rate limit exceeded |
500 Internal Server Error | a server error occurred |
503 Service Unavailable | an AWS service is unavailable |
You can generate a cyberduck bookmark file based on your bucket name. The file should be saved with the .duck
extension. This file does not contain secrets and is safe for distribution. When imported into cyberduck, you will be prompted for the access keys.
GET /v1/s3/{account}/buckets/{bucket}/duck
HEAD /v1/s3/{account}/websites/{website}
GET /v1/s3/{account}/websites/{website}
{
"Tags": [
{ "Key": "Application", "Value": "HowToGet" },
{ "Key": "COA", "Value": "Take.My.Money.$$$$" },
{ "Key": "CreatedBy", "Value": "Big Bird" }
],
"Logging": {
"TargetBucket": "foobar-sites-access-logs",
"TargetGrants": null,
"TargetPrefix": "s3/foobar.bulldogs.cloud/"
},
"Empty": true,
"DNSRecord": {
"AliasTarget": {
"DNSName": "abcdefgh12345.cloudfront.net.",
"EvaluateTargetHealth": false,
"HostedZoneId": "ABCDEFGHIJ12345"
},
"Failover": null,
"GeoLocation": null,
"HealthCheckId": null,
"MultiValueAnswer": null,
"Name": "foobar.bulldogs.cloud.",
"Region": null,
"ResourceRecords": null,
"SetIdentifier": null,
"TTL": null,
"TrafficPolicyInstanceId": null,
"Type": "A",
"Weight": null
},
"Distribution": {
"ARN": "arn:aws:cloudfront::12345678910:distribution/ABCDEFGHIJKL",
"DistributionConfig": {
"Aliases": {
"Items": [
"foobar.bulldogs.cloud"
],
"Quantity": 1
},
"CallerReference": "12345678-9012-3456-6789-094d26464c6c",
"Comment": "foobar.bulldogs.cloud",
"DefaultCacheBehavior": {
...
"TargetOriginId": "foobar.bulldogs.cloud",
"TrustedSigners": {
"Enabled": false,
"Items": null,
"Quantity": 0
},
"ViewerProtocolPolicy": "redirect-to-https"
},
"DefaultRootObject": "index.html",
"Enabled": true,
"HttpVersion": "http2",
"IsIPV6Enabled": true,
"Logging": {
"Bucket": "",
"Enabled": false,
"IncludeCookies": false,
"Prefix": ""
},
"Origins": {
"Items": [
{
...
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginKeepaliveTimeout": 5,
"OriginProtocolPolicy": "http-only",
"OriginReadTimeout": 30,
"OriginSslProtocols": {
"Items": [
"TLSv1",
"TLSv1.1",
"TLSv1.2"
],
"Quantity": 3
}
},
"DomainName": "foobar.bulldogs.cloud.s3-website-us-east-1.amazonaws.com",
"Id": "foobar.bulldogs.cloud",
"OriginPath": "",
"S3OriginConfig": null
}
],
"Quantity": 1
},
"PriceClass": "PriceClass_100",
"Restrictions": {
"GeoRestriction": {
"Items": [
"US"
],
"Quantity": 1,
"RestrictionType": "whitelist"
}
},
"ViewerCertificate": {
"ACMCertificateArn": "arn:aws:acm:us-east-1:12345678910:certificate/111111111-2222-3333-4444-55555555555",
"Certificate": "arn:aws:acm:us-east-1:12345678910:certificate/111111111-2222-3333-4444-55555555555",
"CertificateSource": "acm",
"CloudFrontDefaultCertificate": null,
"IAMCertificateId": null,
"MinimumProtocolVersion": "TLSv1.1_2016",
"SSLSupportMethod": "sni-only"
},
...
},
"DomainName": "1234567abcdef.cloudfront.net",
"Id": "ABCDEFGHIJKLMNOP",
"InProgressInvalidationBatches": 0,
"LastModifiedTime": "2019-05-09T10:50:35.79Z",
"Status": "InProgress"
},
}
Response Code | Definition |
---|---|
200 OK | okay |
400 Bad Request | badly formed request |
500 Internal Server Error | a server error occurred |
Updating a website currently only supports updating the bucket's tags
PUT /v1/s3/{account}/websites/{website}
See Update a bucket
DELETE /v1/s3/{account}/websites/{website}
Responds with a status code and the deleted objects
{
"Website": "foobar.bulldogs.cloud",
"Users": [],
"Policies": [
"foobar.bulldogs.cloud-BktAdmPlc",
"foobar.bulldogs.cloud-WebAdmPlc"
],
"Groups": [
"foobar.bulldogs.cloud-BktAdmGrp",
"foobar.bulldogs.cloud-WebAdmGrp"
],
"DNSRecord": {
"AliasTarget": {
"DNSName": "abcdefgh12345.cloudfront.net.",
"EvaluateTargetHealth": false,
"HostedZoneId": "ABCDEFGHIJ12345"
},
"Name": "foobar.bulldogs.cloud.",
"Type": "A",
...
},
"Distribution": {
"ARN": "arn:aws:cloudfront::12345678910:distribution/ABCDEFGHIJKL",
"DistributionConfig": {
"Aliases": {
"Items": [
"foobar.bulldogs.cloud"
],
"Quantity": 1
},
...
},
"DomainName": "1234567abcdef.cloudfront.net",
"Id": "ABCDEFGHIJKLMNOP",
"Status": "InProgress"
...
},
}
Response Code | Definition |
---|---|
200 OK | deleted website |
400 Bad Request | badly formed request |
403 Forbidden | you don't have access |
404 Not Found | account or website not found |
409 Conflict | website bucket is not empty |
500 Internal Server Error | a server error occurred |
PATCH /v1/s3/{account}/websites/{website}
{
"CacheInvalidation": ["/*"]
}
Responds with a status code and the changes
{
"Invalidation": {
"CreateTime": "2019-05-20T19:51:54.715Z",
"Id": "GGHHIIJJKKLLOO",
"InvalidationBatch": {
"CallerReference": "2b0fd0c2-e683-44a0-8d4d-3922e965d4a4",
"Paths": {
"Items": [
"/*"
],
"Quantity": 1
}
},
"Status": "Completed"
},
"Location": "https://cloudfront.amazonaws.com/2018-11-05/distribution/AABBCCDDEEFF/invalidation/GGHHIIJJKKLLOO"
}
Response Code | Definition |
---|---|
200 OK | deleted website |
400 Bad Request | badly formed request |
403 Forbidden | you don't have access |
404 Not Found | account or website not found |
500 Internal Server Error | a server error occurred |
You can generate a cyberduck bookmark file based on your website name. The file should be saved with the .duck
extension. This file does not contain secrets and is safe for distribution. When imported into cyberduck, you will be prompted for the access keys.
GET /v1/s3/{account}/websites/{website}/duck
Optionally you can pass a list of groups to the user creation.
POST /v1/s3/{account}/websites/{website}/users
{
"User": { "UserName": "somebucketuser" },
"Groups": [ "BkrAdmGrp", "WebAdmGrp"]
}
{
"User": {
"Arn": "arn:aws:iam::12345678910:user/somebucketuser",
"CreateDate": "2019-03-01T16:11:00Z",
"PasswordLastUsed": null,
"Path": "/",
"PermissionsBoundary": null,
"Tags": null,
"UserId": "AIDAJJSBBEAVOQLFAAUCG",
"UserName": "somebucketuser"
},
"AccessKey": {
"AccessKeyId": "ABCDEFGHIJ12345678",
"CreateDate": "2019-03-01T16:11:00Z",
"SecretAccessKey": "sssshimsupersekretdonttellanyoneyousawme",
"Status": "Active",
"UserName": "somebucketuser"
}
}
Response Code | Definition |
---|---|
200 OK | user created |
400 Bad Request | badly formed request |
403 Forbidden | you don't have access to bucket |
404 Not Found | account or user not found when creating key |
409 Conflict | user already exists |
429 Too Many Requests | service or rate limit exceeded |
500 Internal Server Error | a server error occurred |
GET /v1/s3/{account}/websites/{website}/users/{user}
See Get a bucket user's details
GET /v1/s3/{account}/websites/{website}/users/{user}
PUT /v1/s3/{account}/websites/{website}/users/{user}
See Reset access keys for a bucket user
DELETE /v1/s3/{account}/websites/{website}/users/{user}
E Camden Fisher camden.fisher@yale.edu
GNU Affero General Public License v3.0 (GNU AGPLv3)
Copyright (c) 2019 Yale University