API Conversations and Why They are Important

API Interactions are designed to be easy

Believe it or not, the IT infrastructure industry is trying to make things easier by building API access out.

Programmatic interfaces are a new mental model competing for brain-space with GUI and CLI implementations; we need to play to its strengths:

API Conversation Structure

API Conversations

RESTful, SOAP, and NetCONF interfaces all interleave the concept of a conversation with the Hypertext Transfer Protocol (HTTP) standards:

NB: Most API implementers (vendors) will implement API standards very loosely!

NB: RESTful interfaces will be used for the examples in this post, as it’s quickly becoming the most common.

Authentication

Authentication is where most new users get stuck. It’s complicated, but usually an API provider will also leverage an SDK to simplify the authentication process when you “graduate” to a programming language.

This only covers what a client has to do to perform API work - implementing an API (and authorization with it) is considerably more complex.

Basic Authentication

The title says it all, this authentication schema just uses Base64 encoding (ASCII-formatted binary) to place your username and password in an HTTP header:

Authorization: Basic {{ Base64 String }}

If this approach makes you feel a little uncomfortable, it should. This is not a secure way to execute commands; it puts your credentials at risk. There are a few ways to mitigate the security risks:

Most new API sessions will at least start using Basic authentication, so these guidelines will apply unless client certificate authentication is used.

Here are some examples of client authentication use:

cURL
curl -u {{ username }} -p {{ password }} https://{{ api_endpoint }}/get_stuff
curl --header 'Authorization: Basic {{ string }}' https://{{ api_endpoint }}/get_stuff
Python 3
import requests
import sys

try:
    # This example is to generate a bearer token with Cisco's Firepower Threat Defense
    do_api_url = "https://{{fmc_ip}}/api/fmc_platform/v1/auth/generatetoken"
    # The Requests library supports converting to Base64 from a tuple to keep things simple
    do_api_request = requests.request(
        "POST",
        url= do_api_url,
        auth=(username, password)
    )
    do_api_request.raise_for_status()
except requests.Timeout:
    sys.exit("TCP Timeout!")
except HTTPError as e:
    sys.exit("HTTP Error Found! " + do_api_request.status_code + " " + str(e))

Token Authentication

Most API Providers will require you to use safer authentication for continued requests. This is a good thing - but it does add of work. Usually, Basic or Certificate authentication is used to establish a timeboxed token for future authentication.

These tokens have several forms:

Here are some examples:

cURL
# GitHub follows the Bearer standard
curl --request GET \
--url "https://api.github.com/octocat" \
--header "Authorization: Bearer YOUR-TOKEN" \
--header "X-GitHub-Api-Version: 2022-11-28"
# VMware vSphere uses `vmware-api-session-id` as an API key
curl --location --globoff 'https://{{vsphere_vcenter}}/api/content/library/{{vsphere_base_images_library}}' \
--header 'vmware-api-session-id: {{vsphere_key}}'
# Cisco FirePower uses `X-auth-access-token` as a custom header
curl --location --globoff 'https://{{fmc_ip}}/api/fmc_config/v1/domain/{{domain_uuid}}/devices/devicerecords' \
--header 'X-auth-access-token: {{auth_token}}'
Python 3
# Cisco DNA Center uses `X-Auth-Token` as a custom header
import requests
import json
import sys

url = "https://sandboxdnac2.cisco.com/dna/intent/api/v1/site"

payload = {}
headers = {
  'Content-Type': 'application/json',
  'X-Auth-Token': '{{ token }}'
}

try:
    response = requests.request("GET", url, headers=headers, data=payload)
    response.raise_for_status()
    print(response.text)
except requests.Timeout:
    sys.exit("TCP Timeout!")
except HTTPError as e:
    sys.exit("HTTP Error Found! " + do_api_request.status_code + " " + str(e))

Verbs

In API Terminology, clients (and servers) should identify what type of operation they intend to execute with a matching HTTP Method:

Why?

Infrastructure operators benefit from programmatic interface usage, but the pattern differs.

Researching secure, well-managed authentication methods leaves a lot of room for improvement with the commodity resources available today, and a security engineer with even some basic API knowledge can quickly and easily secure resources with these rules. It’s easy to imagine how firewalling an API service can quickly become secure:

allow user any GET under /api/v3/healthcheck
allow user admin PUT under /*
deny user off-net any under /*
deny user any DELETE under /*

Essentially, any load balancer can become a highly granular firewall for an API.

APIs are easy to parse due to their dictionary formats. Prior to their inception, network engineers had to write screen scrapers like Scrapli and “guess” what value in a given table has what meaning. YAML and JSON formats allow language-native association between values not normally present in a tab-separated table like a routing table.

The most important advantage to API automation, though, is for change safety. No matter what discipline you follow, invasive IT work is completed at night and with a strict schedule - one that does not promote thoroughness. Leverage APIs to check if your system is healthy - only you as the engineer know how to do that - and make change windows less stressful.

Some Tips