Create and Manage API Keys

Deep Security API keys enable you to authenticate your API calls with Deep Security Manager. API keys provide a secret key that you include in your  HTTP request headers that the manger authenticates. Each API key is also associated with a user role that determines the actions that you can perform. An expiry date determines when key access terminates.

You can create API keys using the Deep Security Manager UI or the API.

Obtain a role ID

Obtain a role ID when you are assigning a role to a user or API key. When you do not know the ID of a role, you can search for the role then get the role ID.

For example, a program that generates a report on computer security statuses requires read access to all computers. The Auditor role that Deep Security Manager provides by default provides read-only access to computers and policies, and is appropriate for this task.

If you want to create a role, see Control Access Using Roles.

Use the following general steps to search for a role and obtain the ID:

  1. Create a SearchCriteria object that defines the search criteria.
  2. Add the SearchCriteria to a SearchFilter.
  3. Create an AdministratorRolesApi object and use it to perform the search.
  4. Obtain the ID from the returned Role object.

Example: Search for a role

Python
def search_roles_by_name(api, configuration, api_version, api_exception, role_name):
    """ Searches for a role by name and returns the ID.

    :param api: The Deep Security API modules.
    :param configuration: Configuration object to pass to the api client.
    :param api_version: The version of the API to use.
    :param api_exception: The Deep Security API exception module.
    :param role_name: The role name to search.
    :return: The ID of the found role, or None if no role is found.
    """

    # Store the role ID - default is None
    role_id = None
    
    # Search criteria
    name_criteria = api.SearchCriteria()
    name_criteria.field_name = "name"
    name_criteria.string_value = role_name
    name_criteria.string_test = "equal"

    # Search filter
    role_filter = api.SearchFilter()
    role_filter.search_criteria = [name_criteria]

    # Perform the search and obtain the ID of the returned role
    try:
        # Perform the search
        admin_roles_api = api.AdministratorRolesApi(api.ApiClient(configuration))
        roles = admin_roles_api.search_administrator_roles(api_version, search_filter=role_filter)

        if len(roles.roles) > 0:
            role_id = roles.roles[0].id

            return "The role ID for the " + str(role_name) + " role is " + str(role_id) + "."

    except api_exception as e:
        return "Exception: " + str(e)
JavaScript
/*
 * Searches for a role by name and returns the ID.
 * @param {String} roleName The role name to search for.
 * @param {object} api The API module.
 * @param {String} apiVersion The API version to use.
 * @return {Promise} A promise that contains the ID of the found role or undefined if not found.
 */
exports.searchRolesByName = function(roleName, api, apiVersion) {
  return new Promise((resolve, reject) => {
    let newRoleID; // Stores the role ID -- default is undefined

    // Search criteria
    const nameCriteria = new api.SearchCriteria();
    nameCriteria.fieldName = "name";
    nameCriteria.stringValue = roleName;
    nameCriteria.stringTest = api.SearchCriteria.StringTestEnum.equal;

    // Search filter
    const roleFilter = new api.SearchFilter();
    roleFilter.searchCriteria = [nameCriteria];

    // Search options
    const searchOptions = {
      searchFilter: roleFilter,
      overrides: false
    };

    // Perform the search
    const adminRolesApi = new api.AdministratorRolesApi();
    adminRolesApi
      .searchAdministratorRoles(apiVersion, searchOptions)
      .then(returnedRoles => {
        // Resolve the role ID
        if (returnedRoles.roles.length > 0) {
          newRoleID = returnedRoles.roles[0].ID;
        }
        resolve(newRoleID);
      })
      .catch(error => {
        reject(error);
      });
  });
};
Java
/*
 * Searches for a role by name. 
 * @param roleName The role name to search. 
 * @returns An integer that equals the found role, or null if no role is found
 */
public static Integer searchRolesByName(String roleName) {
	Integer roleId = null;

	//Search criteria
	SearchCriteria nameCriteria = new SearchCriteria();
	nameCriteria.setFieldName("name");
	nameCriteria.setStringValue(roleName);
	nameCriteria.setStringTest(SearchCriteria.StringTestEnum.EQUAL);

	//Search filter
	SearchFilter roleFilter = new SearchFilter();
	roleFilter.addSearchCriteriaItem(nameCriteria);

	//Perform the search and obtain the ID of the returned role
	AdministratorRolesApi adminRolesApi = new AdministratorRolesApi();
	try {
		AdministratorRoles roles = adminRolesApi.searchAdministratorRoles(roleFilter, "v1");
		if(roles.getRoles().size() > 0) {		
			roleId = roles.getRoles().get(0).getID();
		}
	} catch (ApiException e) {
		System.out.println(e.getMessage());			
		e.printStackTrace();
	}
	return roleId;
}

Create an API key in Deep Security Manager

Create an API key to use for authenticating your requests with Deep Security Manager. When you create an API key, you provide the following properties:

  • A name
  • The role to associate with the key
  • The time zone to associate with the key. This is the default time zone used for interpreting date and time values in API calls and responses.
  • Optionally an expiry date that limits access to a specific period of time.

Upon creation of an API key, you are provided a unique secret key that is associated with the API key. You use this secret key with your API calls for authenticating. You must store the secret key when it is provided because at no other time are you able to obtain it. If you lose the secret key you must create a new API key or create a new secret key for the API key.

An account with administrator privileges is required to create an API key.
  1. In Deep Security Manager, click Administration > User Management > API Keys.
  2. Click New and enter the property values for the API key.
  3. Click Next.
    The secret key is presented. This is the only time that you can obtain the secret key.
  4. Copy the secret key and securely store it.
  5. Click Close.

Create an API key using an SDK

To use an SDK create an API key, create an ApiKey object and set the name and the ID of the role to associate with the API key. You can also specify the following optional properties:

  • A description
  • The time zone
  • The locale
  • The expiry date

Use an APIKeysApi object to create the API key on Deep Security Manager. The ApiKey object that is returned contains the secret key.

To use the API to create an API key, use the Create an API Key operation of the apikeys endpoint. (See the API Keys section of the API Reference.)

Example: Create an API key for auditing

The following example creates an API key for auditing purposes. The key expires 2 weeks after creation.

Python
def create_audit_key(api, configuration, api_version, api_exception, key_name):
    import time
    """ Creates an API key with read-only permissions that expires in 2 weeks.

    :param api: The Deep Security API modules.
    :param configuration: Configuration object to pass to the api client.
    :param api_version: The version of the API to use.
    :param api_exception: The Deep Security API exception module.
    :param key_name: The name for the key.
    :return: An APIKeysApi object that contains the ID of the created API key.
    """

    # Set key properties
    time_to_expiry_in_ms = 14 * 24 * 60 * 60 * 1000
    current_time_in_ms = int(round(time.time() * 1000))

    key = api.ApiKey()
    key.key_name = key_name
    key.description = "Read-only access"
    key.role_id = "2"
    key.locale = "en-US"
    key.time_zone = "Asia/Tokyo"
    key.expiry_date = current_time_in_ms + time_to_expiry_in_ms # expires in 2 weeks

    try:
        # Create the key on Deep Security Manager
        api_keys_api = api.APIKeysApi(api.ApiClient(configuration))
        return api_keys_api.create_api_key(key, api_version)

    except api_exception as e:
        return "Exception: " + str(e)
JavaScript
/*
 * Creates an API key with read-only permissions that expires in 2 weeks.
 * @param {ApiClient} api The Deep Security API exports.
 * @param {String} keyName The name for the API key.
 * @param {String} apiVersion The API version to use.
 * @returns {Promise} A promise object that resolves to the ID of the created API key.
*/
exports.createAuditKey = function(api, keyName, apiVersion) {
  return new Promise((resolve, reject) => {
    // Key properties
    const key = new api.ApiKey();
    key.keyName = keyName;
    key.description = "Read-only access";
    key.roleID = "2";
    key.locale = api.ApiKey.LocaleEnum["en-US"];
    key.timeZone = "Asia/Tokyo";
    key.expiryDate = Date.now() + 1000 * 60 * 60 * 24 * 14;

    // Create the key on Deep Security Manager
    const apiKeysApi = new api.APIKeysApi();
    apiKeysApi
      .createApiKey(key, apiVersion)
      .then(newKey => {
        // Return the key ID
        resolve(newKey.ID);
      })
      .catch(error => {
        reject(error);
      });
  });
};
Java
/*
 * Creates an API key for auditing that expires in 2 weeks.
 * @param keyName The name for the API key.
 */
public static ApiKey createAuditKey(String keyName){
  //Create a key object
  ApiKey key = new ApiKey();
  key.setKeyName(keyName);
  key.setDescription("Read-only access");
  key.setRoleID(2);
  key.setLocale(ApiKey.LocaleEnum.EN_US);
  key.setTimeZone("Asia/Tokyo");
  //Expires 2 weeks from now
  key.setExpiryDate(new Date().getTime() + TimeUnit.DAYS.toMillis(14));
  //Create the key on Deep Security Manager
  ApiKey newKey = new ApiKey();
  ApiKeysApi apiKeysApi = new ApiKeysApi();
  try {
    newKey = apiKeysApi.createApiKey(key, "v1");
  } catch (ApiException e) {
    System.out.println(e.getMessage());
    e.printStackTrace();
  }
  return newKey;
}
For information about authenticating API calls, see Authenticate with Deep Security Manager.

Create an API key using a username and password

To automate a task when no API key is created yet, you can use the API and a username and password to create the first API key:

  1. Use the /api/sessions resource to obtain a valid session cookie and request ID.
  2. Use the session cookie and request ID in a request to the /api/apikeys resource to create the API key.

Once created, use the API key to make subsequent calls to Deep Security Manager.

Use an HTTP client such as Postman, Paw, or cURL to send a POST request to the /api/sessions resource. The response includes a cookie that contains the session ID, and the response body contains the request ID.

The /api/sessions resource is not available in an SDK at this time.

Use the following information to create the request:

  • Request type: POST
  • URL: https://<Deep Security Manager Hostname>:<port>/api/sessions, for example https://localhost:4119/api/sessions
  • First header:
    • Name: api-version
    • Value: v1
  • Second header:
    • Name: Content-type
    • Value: application/json
  • Body (include the tenantName and mfaCode as well if necessary):
    {
      "userName": "myUserName",
      "password": "myPassword"
    }

Here is an example cURL command. The response cookies are saved in the cookie.txt file. If your Deep Security Manager instance uses an unsigned certificate, add the --insecure option.

curl -i -X POST \
  https://localhost:4119/api/sessions \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -H 'api-version: v1' \
  -c cookie.txt \
  -d '{
"userName": "myUserName",
"password": "myPassword"
}'

The Set-Cookie response header includes the session ID in the sID cookie. The response body includes the response ID as the value of RID. The response resembles the following example:

X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1;mode=block
Cache-Control: no-cache,no-store
Pragma: no-cache
Set-Cookie: sID=D5EE2AC155601C895B33B701080D40A6; Path=/; Secure; HttpOnly
Content-Type: application/json
Content-Length: 141
Date: Wed, 24 Oct 2018 15:29:53 GMT

{
    "administratorID": 1,
    "created": 1540309893123,
    "lastActivity": 1540309893123,
    "accessType": "webService",
    "RID": "77DFF81036170DBF92CB71E4559512B9"
}

Use an HTTP client such as Postman, Paw, or cURL to send a POST request to the /api/apikeys resource. Use the session cookie and the response ID that you obtained from the /api/sessions resource to authenticate the call.

The SDKs do not support the use of session IDs and resource IDs for authentication at this time.

Use the following information to create the request:

    • Request type: POST
    • URL: https://<Deep Security Manager Hostname>:<port>/api/apikeys, for example https://localhost:4119/api/sessions
    • First header:
      • Name: api-version
      • Value: v1
    • Second header:
      • Name: Content-type
      • Value: application/json
    • Third header:
      • Name: rID
      • Value: The request ID that you obtained from the sessions resource, for example 77DFF81036170DBF92CB71E4559512B9
    • Cookie: Include the sID cookie from the response that you received from the /api/sessions resource.
    • Body:
      {
        "keyName": "First Key",
        "description": "Created using a request ID",
        "roleID: 1
      }

For information about obtaining the role ID, see Obtain a role ID.
Here is an example cURL command. The session cookie is included via the cookie.txt file. If your Deep Security Manager instance uses an unsigned certificate, add the --insecure option.

curl -X POST \
  https://192.168.60.128:4119/api/apikeys \
  -H 'Content-Type: application/json' \
  -H 'Postman-Token: 6f81da09-e5e2-421b-a38a-d5679f50608d' \
  -H 'api-version: v1' \
  -H 'rID: 77DFF81036170DBF92CB71E4559512B9' \
  -b cookie.txt \
  -d '{
  "keyName": "First Key",
  "description": "Created using a request ID",
  "roleID": 1
}'

The response body includes the secret key as the value of secretKey, similar to the following example:

{
    "keyName": "First Key",
    "description": "Created using a request ID",
    "locale": "en-US",
    "roleID": 1,
    "timeZone": "America/New_York",
    "active": true,
    "created": 1540310105209,
    "unsuccessfulSignInAttempts": 0,
    "secretKey": "8:4rFctPvno+dxntueMcso4F61SUZMFVt3I6SczG7ysOA=",
    "serviceAccount": false,
    "ID": 8
}

Save the secretKey so that you can later use it in the secret-api-key header of your API calls.

Reset a secret key

Use an APIKeysApi object to generate a new secret key for an existing API key. For example, reset the secret key when periodically rotating API keys. When you reset the secret key, the returned API key contains the new secret key.

Example: Generate a secret for an API key

The following example creates a new secret key for an existing API key.

Python
def reset_key_secret(api, configuration, api_version, api_exception, key_id):
    """ Resets the secret of an API key.

    :param api: The Deep Security API modules.
    :param configuration: Configuration object to pass to the api client.
    :param api_version: The version of the API to use.
    :param api_exception: The Deep Security API exception module.
    :param key_id: The ID of the key.
    :return: An APIKeysApi object that contains the secret of the key.
    """

    try:
        # Reset the key
        api_keys_api = api.APIKeysApi(api.ApiClient(configuration))
        return api_keys_api.replace_api_secret_key(key_id, api_version)

    except api_exception as e:
        return "Exception: " + str(e)
JavaScript
/*
 * Resets the secret key of an API key.
 * @param {ApiClient} api The Deep Security API exports.
 * @param {Integer} keyID The ID of the API key.
 * @param {String} apiVersion The API version to use.
 * @returns {Promise} A promise object that resolves to the secret of the key.
*/
exports.resetKeySecret = function(api, keyID, apiVersion) {
  return new Promise((resolve, reject) => {
    const apiKeysApi = new api.APIKeysApi();
    apiKeysApi.replaceApiSecretKey(keyID, apiVersion)
      .then(key => {
        resolve(key.secretKey);
      })
      .catch(error => {
        reject(error);
      });
  });
};
Java
/*
 * Resets the secret key for an API key.
 * @param key The API Key.
 */
public static ApiKey resetKeySecret(ApiKey key){
  ApiKeysApi apiKeysApi = new ApiKeysApi();
  ApiKey resetKey = new ApiKey();
  try {
    resetKey = apiKeysApi.replaceApiSecretKey(key.getID(), "v1");
  } catch (ApiException e) {
    System.out.println(e.getMessage());
    e.printStackTrace();
  }
  return resetKey;
}

Control API key access after creation

After you create an API key you still have control over the API key’s access to Deep Security Manager:

  • Modify access rights: Modify the role that is associated with the API key or associate the API key with a different role.
  • Revoke access: Either lock out the key to temporarily revoke access, or delete the API key to permanently revoke access.

To use the Deep Security Manager to modify the API key, go to  Administration > User Management > API Keys, select the API key and click Properties.

Example: Change the role for an API key

The following example code changes the role that is associated with the key.

Python
def modify_key_role(api, configuration, api_version, api_exception, key_id, role_id):
    """ Changes the role that an API key uses.

    :param api: The Deep Security API modules.
    :param configuration: Configuration object to pass to the api client.
    :param api_version: The version of the API to use.
    :param api_exception: The Deep Security API exception module.
    :param key_id: The ID of the key.
    :param role_id: The ID of the role to use.
    :return: An APIKeysApi object that contains the ID of the role that the key uses.
    """

    # Create a key and set the role ID
    key = api.ApiKey()
    key.role_id = role_id

    try:
        # Modify the key on Deep Security Manager
        api_keys_api = api.APIKeysApi(api.ApiClient(configuration))
        api_keys_api.modify_api_key(key_id, key, api_version)
        return key.role_id

    except api_exception as e:
        return "Exception: " + str(e)
JavaScript
/*
 * Changes the role that an API key uses.
 * @param {ApiClient} api The Deep Security API exports.
 * @param {Integer} keyID The ID of the API key.
 * @param {Integer} roleID The ID of the role to use.
 * @param {String} apiVersion The API version to use.
 * @returns {Promise} A promise object that resolves to the ID of the role that the key uses.
*/
exports.modifyKeyRole = function(api, keyID, roleID, apiVersion) {
  return new Promise((resolve, reject) => {
    // Create a key and set the role ID
    const key = new api.ApiKey();
    key.roleID = roleID;

    //Modify the key on Deep Security Manager
    const apiKeysApi = new api.APIKeysApi();
    apiKeysApi.modifyApiKey(keyID, key, apiVersion)
      .then(key => {
        resolve(key.roleID);
      })
      .catch(error => {
        reject(error);
      });
  });
};
Java
/*
 * Changes the user role with which an API key is associated.
 * @param key The API key to modify.
 */
public static ApiKey modifyKeyRole (ApiKey key, int roleID) {
  //Create Key object that uses the role
  ApiKey keyWithRole = new ApiKey();
  keyWithRole.setRoleID(roleID);
  ApiKeysApi apiKeysApi = new ApiKeysApi();
  try {
    apiKeysApi.modifyApiKey(key.getID(), keyWithRole, "v1");
    keyWithRole = apiKeysApi.describeApiKey(key.getID(), "v1");
  } catch (ApiException e) {
    e.printStackTrace();
  }
  return keyWithRole;
}

Secure your secret keys

Implement API key-management strategies to maximize their security and prevent system compromise.

Due to the similarities between API key secret keys and cryptographic secret keys, you can adopt estabished best practices for managing cryptographic keys. The Open Web Application Security Project (OWASP) publishes a Key Management Cheat Sheet. Many of the items in the Key Management LifeCycle Best Practices section can be applied to the secret keys of API keys.

If you are storing secret keys, you can use a key management system to encrypt, store, and decrypt your secret keys, such as the Amazon Key Management Service (KMS). Similarly you can use a trusted platform module (TPM).

Consider regularly rotating keys to prevent access in the event that API keys are compromised. Alternatively, you can create API keys as needed and then delete them after use, or set a short expiry date.