Official Plugins (Kuzzle v2.x)
S3 v2.x
2

Kuzzle Plugin S3 #

S3 has a right system to limit who can upload files to buckets.

Presigned URLs are special disposable Urls generated by S3. It is possible to upload a file directly to one of these URLs so that it can be stored into the bucket.

These URLs must be generated on the server side, this plugin includes among other things the generation of these URLs so that developers can then send their files directly to S3 from a client application.

Installation #

Clone the plugin repository in your plugins/available directory and then link it to the plugins/enabled directory.

git clone https://github.com/kuzzleio/kuzzle-plugin-s3 plugins/available/kuzzle-plugin-s3
ln -s ../available/kuzzle-plugin-s3 plugins/enabled/kuzzle-plugin-s3

Then go to your plugin directory and run the following command npm install.

You can now restart Kuzzle and check http://localhost:7512, you should see the plugin name under the key serverInfo.kuzzle.plugins.s3.

Plugin configuration #

In your kuzzlerc file, you can change the following configuration variable:

  • bucketName: AWS S3 bucket
  • endpoint: AWS S3 compatible service endpoint. It must include the protocol and port.
  • s3ClientOptions: AWS S3 client configuration options.
  • region: AWS S3 region (has to be inside s3ClientOptions)
  • signedUrlTTL: TTL in ms format before the presigned URL expires, or before the uploaded file is deleted
  • redisPrefix: Redis key prefix
  • vault.accessKeyIdPath: Path to the AWS Access key id in the Vault
  • vault.secretAccessKeyPath: Path to the AWS secret access key in the Vault
{
  "plugins": {
    "s3": {
      "bucketName": "your-s3-bucket",
      "endpoint": "https://s3.eu-west-3.amazonaws.com",
      "s3ClientOptions": {
        "s3ForcePathStyle": false
        "region": "eu-west-3",
      },      
      "signedUrlTTL": "20min",
      "redisPrefix": "s3Plugin/uploads",
      "vault": {
        "accessKeyIdPath": "aws.s3.accessKeyId",
        "secretAccessKeyPath": "aws.s3.secretAccessKey"
      }
    }
  }
}

Usage with a S3 compatible API #

Use a custom Minio endpoint #

This works with a Minio endpoint but it will work with any S3 compatible provider

Set the plugins.s3.endpoint configuration key to your Minio URL.

Set plugins.s3.s3ClientOptions.s3ForcePathStyle to false.

Example: kuzzlerc file

{
  "plugins": {
    "s3": {
      "bucketName": "your-bucket-name",
      "endpoint": "https://minio.local",
      "s3ClientOptions": {
        "s3ForcePathStyle": false
      },      
    }
  }
}

Example: Framework config object

app.config.set('plugins.s3.bucketName', 'your-bucket-name');
app.config.set('plugins.s3.endpoint', 'https://minio.local');
app.config.set('plugins.s3.s3ClientOptions.s3ForcePathStyle', false);

Credentials #

This plugin needs AWS S3 credentials with the PutObject and DeleteObject permissions.

These credentials can be set in the Vault.

By default the format is the following:

{
  "aws": {
    "s3": {
      "accessKeyId": "accessKeyId",
      "secretAccessKey": "secretAccessKey"
    }
  }
}

You can change the path of the credentials used by the plugin by changing the vault.accessKeyIdPath and vault.secretAccessKeyPath values in the configuration.

If you cannot use the Vault, it's also possible to set the AWS S3 credentials in the following environment variables:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

Environment variable have precedence over the Vault.

AWS S3 Bucket configuration #

First you must configure your bucket to allow public access to uploaded files.
Go to the Permissions tab in your bucket configuration and in Bucket Policy add the following statement:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AddPerm",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::your-bucket-name/*"
    }
  ]
}

Then you have to allow Cross Origin Request by editing the CORS Configuration:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>your-app-domain.com</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Content-Type</AllowedHeader>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>