API User Guide

CloudCheckr provides users with a REST compliant API, allowing them to access and manipulate the data in their CloudCheckr account programmatically. The API uses the HTTPS protocol to make requests and return responses in a JSON or XML format.


Additional API resources can be found below:

API Reference Guide

Admin API Reference Guide


ACCESS KEYS

AUTHENTICATION

Authentication to API endpoints is secured via randomly generated hashes. Access keys are generated and revoked within the webapp. Access keys are the SHA512 HMAC of two randomly generated 32-byte strings. Access keys are, in effect, secret keys and should not be shared. Anyone with knowledge of the access key will be able to make API calls against the account it is associated with.


CREATING API ACCESS KEY

CloudCheckr offers two distinct API access keys: Admin-level and account-level. These two keys allow for different access permissions. An admin-level API key can be used by a user to make calls against any of the cloud provider accounts in CloudCheckr. An account-level API key can only make calls against a single account.

To create an admin-level access key:

  1. Login to CloudCheckr as an administrator
  2. Above the list of your cloud accounts, expand the Admin Functions dropdown and select Admin API Keys
  3. A new window or tab will open taking you to the Admin API Access Keys management page
  4. On the API Credentials page, click the ‘Create New Admin Access key’ button
  5. Your access key will be generated and displayed on the page

To create an account-level access key:

  1. Login to your CloudCheckr account
  2. From the landing page, navigate to the cloud account you’re going to generate the API access key for
  3. On the left-side of the screen, navigate to Account Settings > API Access Keys
  4. On the API Access Keys page, click the ‘Create New Access Key’ button
  5. Your access key will be generated and subsequently displayed on the page

DISABLE/ENABLE API ACCESS KEY

Existing API access keys can be disabled and/or enabled at any time. Disabled access keys will not be able to make any calls against CloudCheckr. Any calls made using disabled access keys will return no data.

To disable or enable an admin-level access key:

  1. Login to CloudCheckr as an administrator
  2. Above the list of your accounts, click the Admin API Keys button
  3. A new window or tab will open, taking you to the API Admin Access Keys management page
  4. Locate the access key you would like to disable or enable
  5. Toggle the active switch to “on” or “off”.

To disable or enable an account-level access key:

  1. Login to your CloudCheckr account
  2. From the landing page, navigate to the cloud account you’re going to generate the API access key for
  3. On the left-side of the screen, navigate to Account Settings > API Access Keys
  4. Click API Access Keys
  5. Locate the access key you would like to disable or enable
  6. Toggle the active switch to “on” or “off”.

NOTE: This setting auto-saves and takes effect immediately.


WHAT TO DO IF YOUR ACCESS KEY IS COMPROMISED OR NEEDS TO BE REVOKED

If for any reason you believe an access key has been compromised or you want to revoke access to the API from someone with an access key, you can revoke the access key. API keys can be created and revoked as often as needed.

To revoke an account-level API access key:

  1. Login to your CloudCheckr account
  2. From the landing page, navigate to the cloud account you’re going to revoke the API access key to
  3. On the left-side of the screen, navigate to Account Settings > API Access Keys
  4. Click API Access Keys
  5. Locate the access key you would like to revoke
  6. Click the Delete button to the right of the access key
  7. Click the confirm button

Once an access key is revoked, it cannot be used to make any calls against CloudCheckr. Revoked access keys cannot be restored. A new access key must be created.


CREATING TEMPORARY ACCESS KEYS

Because Access Keys can be created and deleted as often as possible, it is recommended no applications or individuals share an Access Key. This makes it simple to create and revoke temporary Access Keys. To create a temporary Access Key, create the key, share with the application or individuals that need to use it. Then revoke the Access Key when it is no longer needed.


CALLING THE CLOUDCHECKR API

ALL CALLS ARE ENCRYPTED

CloudCheckr only supports API requests using HTTPS. Any attempts to access the API through HTTP will fail.

METHODS FOR CALLING THE API

You can use the CloudCheckr API using a variety of tools. Tools such as curl can be used to programmatically script the CloudCheckr API. You can use software like Firefox to query the API using a web browser.

Example using curl:

curl https://api.cloudcheckr.com/api/best_practice.xml/get_best_practices?access_key=0016F73669F548D585991E10F3CE2D74267BDBB1F91E4D189C459CC30236DD2C

Example in Firefox:

https://api.cloudcheckr.com/api/best_practice.xml/get_best_practices?access_key=0016F73669F548D585991E10F3CE2D74267BDBB1F91E4D189C459CC30236DD2C

Result:

<BestPractice>
    <BestPracticeName>
    	Auto Scaling Groups Not Using Cooldown Period
    </BestPracticeName>
    <ShortDescription>
    	Checks each Auto Scaling group to verify they are configured to utilize cooldown periods. Lists each group that does not.
    </ShortDescription>
    <LongDescription>
    	<p>When enabled, Auto Scaling will automatically scale EC2 capacity up or down, according to pre-defined conditions. During period of high-demand, the number of EC2 instances will increase to meet that demand. When there is little or no demand, the number of instances decreases to help minimize costs. </p><p>Cooldown periods help to prevent Auto Scaling from initiating additional scaling activities before the effects of previous activities are visible. Because scaling activities are suspended when an Auto Scaling group is in cooldown, an adequate cooldown period helps to prevent a trigger from firing based on stale metrics. If a cool-down period is not configured, the scaling policy may scale up and down too quickly. </p><p><a href="http://docs.amazonwebservices.com/AutoScaling/latest/DeveloperGuide/scaling_plan.html#scaling_policies" target="_blank">Go here to learn more.</a></p>
    </LongDescription>
    <Category>
    	Usage
    </Category>
    <Importance>
    	Low
    </Importance>
    <CountOfResults>
    	2
    </CountOfResults>
    <Results>
        <Result>
        	Auto Scaling Group: agcmgroup | Cooldown: 1 second(s) | Region: US East (N. Virginia)
        </Result>
        <Result>
        	Auto Scaling Group: changemon | Cooldown: 1 second(s) | Region: US East (N. Virginia)
        </Result>
    </Results>
</BestPractice>

RETURNING RESULTS FROM THE API

Results from the API can be returned in JSON or XML.

In the example call below:

https://api.cloudcheckr.com/api/help.xml/get_all_api_endpoints

The “.xml” content type in the endpoint URL tells the API to return the results in XML. To return the results in JSON, simply switch the content type:

https://api.cloudcheckr.com/api/help.json/get_all_api_endpoints

API POST REQUIREMENTS

When sending API requests via POST method, the request needs to be set up as follows:

  • You must add the Content-Type to the request headers
  • You can pass the access_key parameter as a query string or in the request headers (latter recommended!)
  • The parameters must be sent in the body of the request in the appropriate content type format

See the following example request below.

POST /account.json/get_account
Host: localhost
Accept: application/json
Content-Type: application/json
access_key: access_key_here

{
  "account_name": "dummy_account"
}

API PAGINATION

When you select from the API, it returns up to 100 results. If you have more than 100 results, you will have 2 additional fields in the results.

The 2 additional fields are:
HasNext – boolean value indicating if you need to call the API to get more results.
NextToken – the string you should pass to the function to get additional results

For example, you call the API here to get a list of EC2 instances:

https://api.cloudcheckr.com/api/inventory.xml/get_resources_ec2_details?access_key=[access_key]

You receive back the following response:

<?xml version="1.0"?>
  <GetResourcesEc2DetailsResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
     <HasNext>true</HasNext>
     <NextToken>H4sIAAAAAAAEAJWQQQvCMAyF</NextToken>
     <DateOfResults>2014-08-31T16:21:34</DateOfResults>
     <Ec2Instances>
     ...<snip>...

Notice the 2 new fields. Under Ec2Instances, you will have the first 100 results. To retrieve the next 100 results, send the new URL.

https://api.cloudcheckr.com/api/inventory.xml/get_resources_ec2_details?access_key=[access_key]&next_token=H4sIAAAAAAAEAJWQQQvCMAyF

You will receive back the following response.

<?xml version="1.0"?>
   <GetResourcesEc2DetailsResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <HasNext>true</HasNext>
      <NextToken>KLSDJFLIEDLKNEI</NextToken>
      <DateOfResults>2014-08-31T16:21:34</DateOfResults>
      <Ec2Instances>
      ...<snip>...

To get the following set of 100 results, generate and submit the next URL using the next_token.

https://api.cloudcheckr.com/api/inventory.xml/get_resources_ec2_details?access_key=[access_key]&next_token=KLSDJFLIEDLKNEI

Continue this process until you receive back a response with:

<HasNext>false</HasNext>

ERRORS

Error codes are returned as text in the HTTP content. Look for the field “ErrorMessage” and “ErrorCode” for error messages.


USE CASE

The CloudCheckr API has many useful features. One example use-case for the API is to leverage the inventory in CloudCheckr to run vulnerability assessments against a list of publicly accessible resourses.

The Python script below is designed to pull the list of public IPs from the CloudCheckr inventory and use that to call another command line tool. This could be used to kick off a vulnerability assessment against each IP address.

This script supports three data sources to pull public IP addresses from.

1) EC2PublicIPs – gets the list of public IP addresses assigned to any of your EC2 instances. Does not validate if they are accessible by security groups, VPC, etc., Only that they have a defined public IP address.

2) PubliclyAccessibleResources – gets the list of public IP addresses from the Perimeter Assessment Report. Limited to those that are accessible within a VPC or as EC2-Classic. Also lists RDS, S3, and other resources you could review for security assessments.

3) ElasticIPs (currently a Work-In-Progress) – gets the list of Elastic IP addresses that are registered to your account. Is only a subset of the attack surface of your AWS accounts.

From within the script you can call out directly to run another tool with each IP address you find. As well, the script creates an output file containing the list of IP addresses you can then use to feed your vulnerability assessment engine.

NOTE: You can run this script against Multi-Account Views as well as specific AWS accounts. By defining a Multi-Account View that encompasses all your configured AWS account, you can get the complete list of publicly accessible IP addresses across many AWS accounts.

import sys
import requests
import csv
import time
from requests.exceptions import ConnectionError, MissingSchema, ReadTimeout

#DATA STRUCTURES
cloudcheckrSession = requests.Session()
ipAddresses = []

#GLOBAL SETTINGS
fetchMode = ''  # 0 = EC2PublicIPs, 1 = PubliclyAccessibleResources, 2 = ElasticIPs
cloudcheckrapikey = ''
environment = 'app'  # check if you should be using app2

### CONSTANTS ###

# API Calls
ec2PublicIPs = 'https://{0}.cloudcheckr.com/api/inventory.json/get_resources_ec2_details?access_key={1}'
publiclyAccessibleResources = 'https://{0}.cloudcheckr.com/api/security.json/get_publicly_accessible_resources?access_key={1}'
elasticIp = 'TO BE IMPLEMENTED'


def main():
    print('Starting CloudCheckr public IP collector')

    global fetchMode
    global cloudcheckrapikey
    global environment

    # Default to EC2 Collection
    if sys.argv.__len__() == 1:
        fetchMode = 'EC2PublicIPs'
        print('Getting the list of EC2 Public IP addresses from CloudCheckr')

    # Determine what data we are getting
    elif sys.argv.__len__() == 2:
        if sys.argv[1] == '0':
            fetchMode = 'EC2PublicIPs'
            print('Getting the list of EC2 Public IP addresses from CloudCheckr')
        elif sys.argv[1] == '1':
            fetchMode = 'PubliclyAccessibleResources'
            print('Getting the list of publicly accessible resources from CloudCheckr')
        elif sys.argv[1] == '2':
            fetchMode = 'ElasticIPs'
            print('Getting the list of Elastic IP Addresses from CloudCheckr')
            print('NOT YET SUPPORTED')

    # Go get the data data from the CloudCheckr API
    if (fetchMode == 'EC2PublicIPs'):
        collectEC2PublicIPs(cloudcheckrapikey)
    elif (fetchMode == 'pa'):
        collectPubliclyAccessibleResources(cloudcheckrapikey)
    # need to add EIP when its ready

    # Export IP Addresses to CSV
    timestr = time.strftime("%Y%m%d-%H%M%S")

    with open('ipaddresses-' + timestr + '.csv', 'w', newline='') as output:
        writer = csv.writer(output, lineterminator='\n')
        for ip in ipAddresses:
            writer.writerow([ip])


def collectEC2PublicIPs(apiKey):

    # Format API URL depending on environment and insert API Key
    apiUrl = ec2PublicIPs.format(environment, cloudcheckrapikey).strip()

    # Request JSON from API and parse through for public IP addresses
    try:
        r = requests.get(apiUrl, timeout=10)

        if r.status_code == 200:
            response = r.json()
            for instance in response['Ec2Instances']:
                if instance['PublicIpAddress'] is not None:
                    ipAddresses.append(instance['PublicIpAddress'])
                    # Here you can use instance['IpAddress'] as they are handed to you
                    # Or you can utilize the csv that the script exports to retreive an array of IP addresses.

    except ConnectionError as c:
        print('The API is not responding')
    except MissingSchema as m:
        print(apiUrl + ' is not a valid URL. Make sure your API Key is valid and was entered correctly.')
    except ReadTimeout as t:
        print('Request to ' + apiUrl + ' timed out')


def collectPubliclyAccessibleResources(apiKey):

    # Format API URL depedning on environment and insert API Key
    apiUrl = publiclyAccessibleResources.format(environment, cloudcheckrapikey).strip()

    # Request JSON from API and parse through for public IP addresses
    try:
        r = requests.get(apiUrl, timeout=10)

        if r.status_code == 200:
            response = r.json()
            for instance in response['PubliclyAccessibleEc2Instances']:
                if instance['IpAddress'] is not None:
                    ipAddresses.append(instance['IpAddress'])
                    # Here you can use instance['IpAddress'] as they are handed to you
                    # Or you can utilize the csv that the script exports to retreive an array of IP addresses.

    except ConnectionError as c:
        print('The API is not responding')
    except MissingSchema as m:
        print(apiUrl + ' is not a valid URL. Make sure your API Key is valid and was entered correctly.')
    except ReadTimeout as t:
        print('Request to ' + apiUrl + ' timed out')

main()