Ionic Releases New Machina Tools for Amazon S3, Google Cloud Storage, and Azure Blob Storage

Ionic released version 1.1.0 of Machina Tools for Amazon S3, Google Cloud Storage, and Azure Blob Storage.  These “cloud connectors” make it easier for developers to protect and control access to data stored in the cloud. Organizations can then monitor and record all attempts to access cloud data. Developers can add this capability to their existing custom applications without changing program logic.

Release highlights include:

  • New classes and methods that simplify coding
  • New code samples
  • Updated documentation

New Classes and Methods

With the 1.1.0 release, new Agent based constructors: were added to be more flexible when configuring Machina interactions. In the previous versions, a persistor was used with the constructors, but now the constructors use an agent. In all the code samples, setting the metadata is optional. Below is an AWS S3 example:

Old AWS S3 implementation:

IonicEncryptionMaterialsProvider iemp = new IonicEncryptionMaterialsProvider();
iemp.setIonicMetadataMap(S3SampleApp.getMetadataMap());

// Load a plain-text device profile (SEP) from disk
DeviceProfilePersistorPlainText ptPersistor = new DeviceProfilePersistorPlainText();

String profilePath = Paths.get(HOME +   "/.ionicsecurity/profiles.pt").toFile().getCanonicalPath();
try {
    ptPersistor.setFilePath(profilePath);
    iemp.setPersistor(ptPersistor)
} catch (IonicException e) {
    System.err.println(e.getMessage());
    System.exit(1)
}

return (IonicS3EncryptionClient) IonicS3EncryptionClientBuilder.standard()
                .withEncryptionMaterials(iemp).build();

New AWS S3 Implementation:

String profilePath = Paths.get(HOME +
    "/.ionicsecurity/profiles.pt").toFile().getCanonicalPath();
Agent agent = new Agent(new DeviceProfilePersistorPlainText(profilePath));
agent.setMetadata(getMetadataMap());
return IonicS3EncryptionClientBuilder.standard().withIonicAgent(agent).buildIonic();

Although not shown here, the above code can result in the following exceptions: IOException, IllegalArgumentException, and IonicException.

Here is the implementation for Google Cloud.  Note that GoogleIonicStorage previously used a persistor, but now uses an agent.

Old Google implementation:

DeviceProfilePersistorPlainText ptPersistor = new DeviceProfilePersistorPlainText();
String profilePath = 
    Paths.get(HOME + "/.ionicsecurity/profiles.pt").toFile().getCanonicalPath();
ptPersistor.setFilePath(profilePath);

GoogleIonicStorage ionicStorage = new GoogleIonicStorage(ptPersistor, storage);

ionicStorage.setIonicMetadataMap(getMetadataMap());

return ionicStorage;

New Google implementation:

String peristorPath =
    Paths.get(HOME + "/.ionicsecurity/profiles.pt").toFile().getCanonicalPath();
Agent agent = new Agent(new DeviceProfilePersistorPlainText(peristorPath));
agent.setMetadata(getMetadataMap());

return new GoogleIonicStorage(agent, storage);

The above code can throw IOException, and IonicException.

For Azure, the AzureIonicStorage class was replaced with IonicKeyResolverFactory. Also some of the method names have changed. These changes were needed to be in alignment with the other cloud connectors.

For the IonicEncryptionMaterialsProvider class, Agent accessor methods, getAgent() and setAgent() have been added. The following Agent configuration setters and getters have been deprecated.

  • getIonicMetadataMap()
  • setIonicMetadataMap()
  • setPersistor()

Below is an Azure implementation. Note the class changes.

Old Azure implementation:

DString persistorPath = 
    Paths.get(HOME + "/.ionicsecurity/profiles.pt").toFile().getCanonicalPath();
DeviceProfilePersistorPlainText ptPersistor =
    new DeviceProfilePersistorPlainText(persistorPath);
Agent agent = new Agent(ptPersistor);

AzureIonicStorage ionicStorage = new AzureIonicStorage(agent);

ionicStorage.setIonicMetadataMap(getMetadataMap());

return ionicStorage;

New Azure implementation:

String persistorPath =
   Paths.get(HOME + "/.ionicsecurity/profiles.pt").toFile().getCanonicalPath();
DeviceProfilePersistorPlainText ptPersistor =
   new DeviceProfilePersistorPlainText(persistorPath);
Agent agent = new Agent(ptPersistor);
agent.setMetadata(getMetadataMap());

return new IonicKeyResolverFactory(agent);

New Code Samples

New “Hello, World!” code samples have been added for each cloud connector. These provide simple examples showing how to encrypt and decrypt a string to the cloud. The logic is:

  1. obtain a Machina cloud connector client
  2. encrypt and upload a string to the cloud
  3. download the encrypted string from the cloud and decrypt it.

If you haven’t done any cloud data transfers, these examples will get you started and your data will be protected as well.

The “Hello, World!” examples for each cloud connector are discussed in more detail on the Machina Developers site, and code is located in Ionic’s GitHub (see table below). 

AWS S3 DiscussionAWS S3 code example
Google DiscussionGoogle code example
Azure DiscussionAzure code example

Updated Documentation

The Javadocs have been updated and now contain only the Cloud Connector classes and methods.

A checkstyle.xml file has been added to assist in adhering to coding standards.

All the cloud connectors require Machina Java SDK 2.6 or later as a dependency and support Java versions 8 to 11.

Code Modification

Here is a snippet showing how to modify the put an object into S3 storage example from Amazon:

import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

import java.io.File;
import java.nio.file.Paths;

/**
 * Upload a file to an Amazon S3 bucket.
 *
 * This code expects that you have AWS credentials set up per:
 * http://docs.aws.amazon.com/java-sdk/latest/developer-guide/setup-credentials.html
 */
public class PutObject {
    public static void main(String[] args) {
        final String USAGE = "\n" +
                "To run this example, supply the name of an S3 bucket and a file to\n" +
                "upload to it.\n" +
                "\n" +
                "Ex: PutObject <bucketname> <filename>\n";

        if (args.length < 2) {
            System.out.println(USAGE);
            System.exit(1);
        }

        String bucket_name = args[0];
        String file_path = args[1];
        String key_name = Paths.get(file_path).getFileName().toString();

        System.out.format("Uploading %s to S3 bucket %s...\n", file_path, bucket_name);
        final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
        try {
            s3.putObject(bucket_name, key_name, new File(file_path));
        } catch (AmazonServiceException e) {
            System.err.println(e.getErrorMessage());
            System.exit(1);
        }
        System.out.println("Done!");
    }
}

Replace this line of code, final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build(); with the following code:

        Agent agent = new Agent();
        try {
            String persistorPath = System.getProperty("user.home") + "/.ionicsecurity/profiles.pw";
            DeviceProfilePersistorPassword persistor =
                    new DeviceProfilePersistorPassword(persistorPath);
            persistor.setPassword(persistorPassword);
            agent.initialize(persistor);
        } catch (IonicException e) {
            System.out.println(e.getMessage());
            System.exit(1);
        }

        IonicS3EncryptionClient client =
            IonicS3EncryptionClientBuilder.standard().withIonicAgent(agent).buildIonic();

And add the required import files:

import com.ionic.cloudstorage.awss3.IonicS3EncryptionClient;
import com.ionic.cloudstorage.awss3.IonicS3EncryptionClientBuilder;
import com.ionic.sdk.agent.Agent;
import com.ionic.sdk.device.profile.persistor.DeviceProfilePersistorPassword;
import com.ionic.sdk.error.IonicException;

Summary

With the above example, you can see how easy it is to modify your existing cloud transfer code to protect data using Machina Tools when transferring objects to the cloud.

To get started with the Machina Tools for Cloud Connectors, follow these links:

If you’d like to try these examples but don’t have a Machina account, go to Start for Free and signup for a Free account. Additional developer resources are available at Machina Developers.