Rebar iOS Data in Transit

Monkton, Inc.

Part of Rebar's compliance with NIAP and other associated security profiles is adherence to the API Boundary for Data in Transit (DIT). DIT compliance for the app is achieved in a few ways. One is making direct calls with the URLSession or extending Rebar's RebarWrapper class. Rebar also has transparent support for AFNetworking.

Rebar Hub Endpoints

We strongly suggest using Endpoints that have been configured in the Rebar Hub to reach backend resources and other API methods. This will enable you to build a zero trust infrastructure from the app to your backend.

URLSession

With URLSession and NSMutableURLRequest you can make secure requests to the Rebar Hub or other server based resources. With Rebar's tooling under the hood to further secure data in transit, we can keep an eye on and provide more security for transactions. From enhanced certificate validations and TLS pinning, you now have extensible controls to protect data going to and coming from devices.

You can make direct calls to the Rebar Hub and call your Endpoints directly with the built in URLSession class, we will demonstrate how to do that below:

/**
 Call this method when finished
 */
var finished: (() -> ())? = nil

/**
 Owns the task for calling the server
 */
fileprivate var urlSessionDataTask: URLSessionDataTask? = nil;

/**
 This method will call our API method from the server
 */
func makeServerCall() {
    
    // Get the app config url
    let configHost = RebarAppController.default.configuration.apiHost
    
    // API Method we will invoke
    let apiMethod = "/api/app-api-name"
    
    // This is the full URL that we will invoke
    let urlToAccess = URL(string: "\(configHost)\(apiMethod)")!
    
    // Start building the request
    let request: NSMutableURLRequest! = NSMutableURLRequest(url: urlToAccess);
    
    // Set the HTTP Method
    request.httpMethod = "GET";

    // Set the Host Name
    request.setValue(urlToAccess.host, forHTTPHeaderField: "Host");
    
    let connection = URLSession(
        configuration: URLSessionConfiguration.ephemeral,
        delegate: nil,
        delegateQueue: nil)
    
    self.urlSessionDataTask = connection.dataTask(with: request as URLRequest, completionHandler: {
        [weak self] (data, response, error) -> Void in
        guard let self = self else { return }
        
        if error != nil {
            print("error: \(error!.localizedDescription): \(error!)")
        } else if data != nil {
            // Do something with the data
        }
        
        DispatchQueue.main.async {
            self.finished?();
        }
        
    });
    
    // Start the task here
    self.urlSessionDataTask?.resume();
    
}

As you can see, quick and easy to securely make the call. Our prefight configuration of the app takes care of the signatures and conditioning data to send to the server and through the Rebar Hub.

Rebar Wrapper

When implemented, RebarWrapper will encapsulate all the functionality necessary to make compliant HTTPS/TLS calls.

At this time, Rebar only implements HTTPS/TLS server calls. Other protocols will be implemented in the future.

Web Service Configuration

Rebar's RebarWrapper relies on interacting with the Rebar Middleware. The Rebar Middleware acts as a secure proxy to backend web services within your system, leveraging authentication mechanisms like JWT.

The middleware allows you to define web service connections to backend systems. Those hooks can be accessed within your app with the RebarWrapper class by simply calling the Web API methods.

Leveraging RebarWrapper

RebarWrapper encapsulates all the functionality necessary to make secure HTTPS calls over TLS using NIAP compliant algorithms. The implementation ensures that simple calls are necessary to invoke server API methods.

The RebarWrapper is intended to be used with the Rebar's API Endpoint for APIs.

With the API Endpoints, all that needs to be specified as the URL value is the Usable API Path from the Endpoint screen.

class RebarAppWrapper : RebarWrapper {
	
	/**
		Perform a server GET
	*/
	func myGet() {
		self.get("api/demoapp/my-get-method", contentType: RebarWrapper.JSON_CONTENT_TYPE, headers: nil);
	}
	
	/**
		Perform a server PUT
	*/
	func myPut() {
		self.put("api/demoapp/my-put-method", contentType: RebarWrapper.JSON_CONTENT_TYPE, headers: nil, post: ["some-key":"some value"]);
	}
	
	/**
		Perform a server POST
	*/
	func myCreate(email: String!, password: String!, fullName: String!) {
		
		let credentials: [String:AnyObject] = ["email":email, "password": password, "name": fullName];
		
		self.post("api/demoapp/add-some-account", contentType: RebarWrapper.JSON_CONTENT_TYPE, headers: nil, post: credentials);
	}
	
}

Invoking a Wrapper Class

Rebar's HTTPS wrapper is meant to be simple to develop against. We provide three closure/block handlers to handle different states of the request. Rebar expects most requests to be JSON data, thus the getJson methods for the RebarSecureResponse class.

  • successfulRequest provides the response data from the server if the request is successful.
  • failedRequest provides feedback to why the request failed. Rebar generally handles most of the error process and the willLogoff flag MUST be respected to go no further. The getApiError()?.show should be invoked with a UIViewController as a parameter.
  • cleanupRequest provides the means to cleanup the response after either a success or failure.

	var appWrapper: RebarAppWrapper? = nil;
	func callServer() {
		
		// Set our wrapper handler
		self.appWrapper = RebarAppWrapper();
		
		// Registration is complete now, cleanup
		self.appWrapper?.cleanupRequest = {
			self.appWrapper = nil;
		};
		
		// What to do when there is a successful request
		self.appWrapper?.successfulRequest = {(response: RebarSecureResponse!) in
			// Grab the contents if applicable
			if let contents: [String:AnyObject] = response.getJson()!.dictionaryObject? {
				if let account = contents["account"] as! [String:AnyObject]! {
					// Do something here...
				}
			}
		};
		
		// What to do when the request fails
		self.appWrapper?.failedRequest = {(response: RebarSecureResponse!, willLogoff: Bool) in
			guard !willLogoff else {
				// If we have logged off, do nothing and exit. Rebar
				// handles the rest
				return;
			}
			// Show the error message now
			response.getApiError()?.show(self);
		};
		
		// Perform a put operatoon
		self.appWrapper?.myPut();
		
	}