## Deep Security REST API

### Overview

Deep Security includes a REST (REpresentational State Transfer) Web Services API to allow Deep Security functionality to be integrated with other applications. This allows for an easy, programming language-neutral method to externally access data and programming configurations. The REST API uses standard HTTP mechanisms such as GET and PUT and popular data encoding methods such as JSON and XML.

#### What Functionality is Available From the REST API?

The REST API includes the following functionality:

- Authentication - sign a user in and out.
- Cloud Accounts - create, list, update and delete cloud accounts that Deep Security Manager synchronizes with; force cloud synchronization.
- Events - list Anti-Malware and Web Reputation events.
- Status Monitoring - view the status of Deep Security Manager nodes, including various health checks.
- Tenant Management - create, list, update and delete tenant accounts; create and list database servers used by tenants.
- Usage Monitoring - retrieve statistics about what operations Deep Security Manager has performed for which tenants.

#### Finding More Information

Every API call available in the REST interface, the HTTP syntax required to access it including the HTTP path and operation (GET, PUT, etc.), and a description of the structure of the data passed to or from the API call can be found in the API documentation. This API documentation is generated from the included Java REST API client but is not specific to any programming language. Javadoc specifically for the Java REST API client can be found in the javadoc folder.

The included Java REST API client is based on the RESTEasy project and uses Apache HttpComponents™ for HTTP transport. Documentation of these projects can be found at the RESTEasy project and the Apache HttpComponents™ project.

### Getting Started

The basic steps to getting started with the REST API are as follows:

1. Enable the Status Monitoring API (Optional).
2. Create a user account that an external Web Service client can utilize.
3. Obtain the Deep Security Manager's SSL Certificate.
4. Develop a REST API client to communicate with Deep Security Manager.

#### Enabling the Status Monitoring API (Optional)

Most functions of the REST API are available after Deep Security Manager has been installed and started without requiring any additional configuration. However, if you wish to use the Status Monitoring API it must first be enabled. The API is disabled by default as it does not require authentication to access. To enable the API:

1. Open an Internet browser and connect to the Deep Security Manager: https://<hostname/IP>:4119
2. Navigate to Administration > System Settings, and select the Advanced tab.
3. Select Enabled under Status Monitoring API, then click Save.

#### Creating a Web Service User Account

Deep Security Manager allows for powerful role-based access, including settings to control if a user account may access the Web Service API or Manager user interface. For security reasons, it is recommended that a new user account and a new Web Service-specific role be created.

Both the REST and the SOAP Web Service APIs enforce all Role access controls, such as Computer Rights, Security Profile Rights, and User Rights. If a Role is created for the Web Service APIs that only permits Computers of a certain Computer Group to be viewable, then a Web Service client using that user will only be able to access the specified Computer Group.

To create a new Role for Web Service only access, complete the following steps:

1. Open an Internet browser and connect to the Deep Security Manager: https://<hostname/IP>:4119
2. Navigate to Administration > User Management > Roles, and click New.
3. Create the Role as normal, but de-select Allow Access to Deep Security Manager User Interface and select Allow Access to Web Service API.
4. When all other configuration is complete, click Save.
5. Navigate to Administration > User Management > Users, and click New.
6. Create a new user for use only with the Web Service API. Assign the new Role previously created to this user.

Make note of the new user account username and password.

#### Obtaining Deep Security Manager's SSL Certificate

All REST API clients must communicate with Deep Security Manager using HTTPS communication. Unless Deep Security Manager is run with a certificate issued by a well-know Certificate Authority, typically this means that the Deep Security Manager SSL certificate will need to be imported in to the trusted X.509 certificate store used by the REST client implementation. For Java programs, a custom trust store could be used, or the certificate could be imported in to the default trust store. More documentation of Java's SSL configuration options can be found in the Java™ Secure Socket Extension (JSSE) Reference Guide.

There are many ways to retrieve an installed Deep Security Manager's public certificate. The following is one method using Firefox:

1. Launch Firefox and connect to the Deep Security Manager web page.
2. Double-click on the Lock icon next to the address.
3. Click More Information.
4. Click View Certificate.
5. Click the Details tab.
6. Click Export...
7. Export the certificate as X.509 Certificate (DER).
8. Save it as `Manager.cer`.

#### Developing a REST API Client Application

Any programming language that supports XML or JSON encoding and the HTTP and HTTPS protocols can be used to develop a Deep Security Manager REST API client application. Unlike a SOAP-based Web Service, a REST Web Service does not publish a WSDL file that describes all of the operations and the inputs to and outputs from these operations. Instead, it is the responsibility of the client application developer to write code that calls the API according to the API's documentation.

For Java developers, the `lib` folder contains a suite of Java classes that can be used in Java applications to make Java client application development easier. Sample code demonstrating how to use these classes can be found in the `samples` folder.

For developers using other languages, or Java developers who wish to use their own REST client technology, every API call available in the REST interface, the HTTP syntax required to access it including the HTTP path and operation (GET, PUT, etc.), and a description of the structure of the data passed to or from the API call can be found in the API documentation.

### Using the REST API

This section will give a basic understanding of how to use the REST API.

#### Basic API Access

All access to the REST API is made through the Deep Security Manager URL `https://<hostname/IP>:<port>/rest`. For example, if Deep Security Manager is installed on a host named `myhost.local` and is listening on port 4119, the URL would be `https://myhost.local:4119/rest`

Because the REST API uses standard HTTP mechanisms and some of the operations can be accessed without authentication using HTTP GET, these methods can be accessed from a web browser by entering the correct address. For example, opening `https://myhost.local:4119/rest/apiVersion` would return the REST API version to the browser.

However, most REST API calls require authentication. This is provided in the form of a session identifier (SID) which is passed to the call, either as a query parameter for GET and DELETE methods or somewhere in the message body for PUT and POST methods. A session identifier is obtained by calling the /rest/authentication/login URL with the username and password of a user who is allowed to access the API. Once the application completes or the session identifier is no longer required, the session should be ended by calling the /rest/authentication/logout URL. This process is demonstrated in the sample application below.

#### Using the Provided Java REST API Client

The provided Java REST API client is based on the RESTEasy Client Framework. This framework takes the Java interfaces that have been marked up with JAX-RS annotations and generates implementations of these interfaces that can communicate with the Deep Security Manager. Using this client code takes care of all object serialization and deserialization, HTTP URLs, and HTTP methods for you.

To use the Java REST API Client, include all of the JAR files in the `lib` folder on the classpath of your application. Some of these JAR files, like `commons-logging`, are very commonly used and may already be included in your application, and if they are there is no need to include them a second time.

The interfaces for all the APIs can be found in the Java package `com.trendmicro.ds.platform.rest.api`. All of the objects sent to or from the API can be found in the Java package `com.trendmicro.ds.platform.rest.object` and its sub-packages.

#### Example Java Code

The example code here demonstrates using the Java REST API client code to authenticate a user to the REST API.

For simplicity, the code here assumes that Deep Security Manager is using a certificate issued by a well-known trusted CA. If this is not the case, the application must be made to trust the certificate. One way to do this would be:

1. Retrieve the server's certificate as described previously.
2. Import the certificate in to a new trust store using Java's keytool. For example:
   `keytool -importcert -trustcacerts -keystore dsm.jks -file Manager.cer`
3. Run the program with the JVM option `-Djavax.net.ssl.trustStore=dsm.jks` to make Java use the custom trust store.

    import javax.ws.rs.core.Response.Status;

    import org.jboss.resteasy.client.ClientResponse;
    import org.jboss.resteasy.client.ClientResponseFailure;
    import org.jboss.resteasy.client.ProxyFactory;
    import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
    import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
    import org.jboss.resteasy.spi.ResteasyProviderFactory;

    import com.trendmicro.ds.platform.rest.api.IAuthenticationAPI;
    import com.trendmicro.ds.platform.rest.message.error.ErrorMessage;
    import com.trendmicro.ds.platform.rest.object.DSCredentials;

    public class AuthenticateSample {

    	public static void main(String[] args) {
    		// URL for the REST API. Change this as appropriate.
    		String restApiUrl = "https://192.168.64.128:4119/rest";

    		// The user name to use for authentication. Change this as appropriate.
    		String username = "admin";

    		// The user's password. Change this as appropriate.
    		String password = "supersecretpassword";

    		// Variable to store the session identifier (SID).
    		String sID = null;

    		// RESTEasy client framework initialization that only needs to be done once per VM
    		RegisterBuiltin.register(ResteasyProviderFactory.getInstance());

    		// An object that will execute HTTP requests
    		ApacheHttpClient4Executor executor = new ApacheHttpClient4Executor();

    		// Create the object that will communicate with the authentication API.
    		IAuthenticationAPI authClient = ProxyFactory.create(IAuthenticationAPI.class, restApiUrl, executor);

    		// Create the object to pass to the authentication call.
    		DSCredentials credentials = new DSCredentials();
    		credentials.setUserName(username);
    		credentials.setPassword(password);

    		try {
    			System.out.println("Attempting to authenticate to Deep Security Manager REST API...");
    			sID = authClient.login(credentials);

    			System.out.println("Authentication successful.");
    			System.out.println("Authentication session ID string recieved: " + sID);

    		} catch (ClientResponseFailure e) {
    			// This is a special type of exception that means the server threw
    			// an exception because there was a problem with the credentials.
    			// It's important to handle these exceptions explicitly or the
    			// connection to the server won't be released back in to the
    			// underlying connection pool, meaning any subsequent API calls would fail.
    			// See the RESTEasy Client Framework documentation for more details.
    			ClientResponse<?> clientResponse = e.getResponse();

    			// Try to parse the error response in to an instance of the special
    			// ErrorMessage class and display the result.
    			Status status = clientResponse.getResponseStatus();
    			System.out.println("Server returned error status code " + status.getStatusCode() + " (" + status + ")");
    			ErrorMessage errorMessage = clientResponse.getEntity(ErrorMessage.class);
    			System.out.println("Returned error message: " + errorMessage.getMessage());

    		} catch (Exception e) {
    			// Some other error happened, most likely related to network communication problems.
    			System.out.println("There was an error during authentication.");
    			e.printStackTrace();

    		} finally {
    			if (sID != null) {
    				// Make sure to always log out.
    				System.out.println("");
    				System.out.println("Ending session...");
    				authClient.endSession(sID);
    				System.out.println("End session successful.");
    				// make sure the session ID isn't accidentally re-used.
    				sID = null;
    			}
    		}

    		// Cleanup: force the HTTP Client to close any open sockets
    		executor.close();

    	}

    }

#### Using the Java Sample Code

Some Java sample code is included in the `samples` folder. These samples are part of an Eclipse project that can be imported in to your Eclipse workspace using the following procedure:

1. Open the File menu in Eclipse and select Import...
2. Select General > Existing Projects into Workspace for the import source
3. Click Browse... and select the `restapi/samples` folder as the root
4. Ensure the REST API Samples project is selected, and click Finish

The sample files can be run within Eclipse by opening the file and selecting Run > Run As > Java Application. The samples require command-line arguments which will need to be set through the Run Configurations screen.

#### API Documentation

A description of every method available in the REST API can be found in the API reference documentation. This documentation is programming language-neutral.

Documentation in javadoc format is also provided for users of the Java REST API Client.

### Response Processing

#### HTTP Status Codes

The REST API uses standard HTTP status codes to return the status of requests. The table below shows the response codes that may be used and the circumstances under which they are returned.

HTTP Status Code | Returned When
--- | ---
200 OK | The request completed successfully.
400 Bad Request | The caller did not supply all of the data required by the call.
401 Unauthorized | The caller's SID has timed out due to inactivity. The authentication process must be repeated.
403 Forbidden | The calling user has not been granted Role rights to access the Web Services APIs. The calling user has not been granted Role rights to call the API that failed. The caller's SID is invalid. The caller is a user in a Tenant but the API is restricted to primary Tenant Users only.
404 Not Found | The caller accessed an invalid URL that is not part of the REST API. The caller specified a resource that does not exist. For example, attempting to delete a Tenant by ID but giving the ID of a non-existent Tenant.
405 Method Not Found | The caller has specified an HTTP method that is not allowed for the given URL. For example, using an HTTP POST to access an API that is specified as requiring GET access.
500 Internal Server Error | A database error occurs. Some other unhandled error occurs.

#### Error Responses

When an API call returns a status code other than 200 OK, the response body will include an XML structure like:

    <error>
        <message>Error message string</message>
    </error>

The error message included may be helpful for debugging the problem, but will not be suitable for presenting to end users of an application.

#### API Calls Returning javax.ws.rs.core.Response

Some API calls are documented as returning an object of type `javax.ws.rs.core.Response`. These calls can be thought of as returning nothing more than the HTTP status code.

When using the provided Java REST API client, it is important to retrieve the result of such calls instead of ignoring them. Once you have the `Response` object, the underlying connection to the server must be manually released back to the connection pool, as described in the RESTEasy Client Framework. For example:

`org.jboss.resteasy.client.ClientResponse<?> clientResponse = (ClientResponse<?>)apiObject.methodThatReturnsResponse(methodParameters);
clientResponse.releaseConnection();`

### Other Considerations

#### Specifying Dates in Query Parameters

When specifying dates in search queries, they should be encoded using the date encoding rules set out in section 5 of RFC 822, except that years should be encoded as 4 digits instead of 2 as per section 5.2.14 of RFC 1123. For example, November 31 2012 at 3:45 PM Eastern Standard Time would be encoded as `31 Nov 2012 15:45:00 -0500`.

In Java, these dates could be encoded using `java.text.SimpleDateFormat` with a date format pattern `"dd MMM yyyy HH:mm:ss zzz"`.

Example: If your session ID were `DC5A4AA79326DF3E149A26EA2DA6B0C7`, you could query all host protection information from November 31 2012 at 3:45 PM Eastern Standard Time onwards using the following URL, where spaces in the date encoding have been URL encoded with '%20':
`https://hostname:4119/rest/monitoring/usages/hosts/protection?sID=DC5A4AA79326DF3E149A26EA2DA6B0C7&from=31%20Nov%202012%2015:45:00%20-0500`

#### Multi-Tenant Permissions

Many of the REST APIs are related to managing a multi-Tenant environment. Beyond the normal Role rights required, these APIs also require the user making the API call to be a user in the primary Tenant account. Attempts to call these APIs with a user from a Tenant will return a response with status code 403 Forbidden. The APIs that can only be called by a primary Tenant user are:

- `/monitoring` - the monitoring API
- `/multitenantconfiguration` - the multi-Tenant configuration API
- `/tenants` - the Tenant API
- `/tenantdatabaseservers` - the Tenant Database Server API
- `/tenanttemplate` - the Tenant template API