API authentication (deb/2.8/UI)

MAAS’s API uses OAuth as its authentication mechanism. This isn’t third-party (3-legged) OAuth, so the process used is what’s commonly referred to as 0-legged OAuth: the consumer accesses protected resources by submitting OAuth signed requests.

Note that some API endpoints support unauthenticated requests (i.e. anonymous access). See the API documentation for details.

Two questions you may have:

  1. How can I perform authenticated requests in python?
  2. How can I perform authenticated requests in ruby?

Here are two examples on how to perform an authenticated GET request to retrieve the list of nodes. The <key>, <secret>, <consumer_key> tokens are the three elements that compose the API key (API key = ‘<consumer_key>:<key>:<secret>’).

Python

import oauth.oauth as oauth
import httplib2
import uuid

def perform_API_request(site, uri, method, key, secret, consumer_key):
    resource_tok_string = "oauth_token_secret=%s&oauth_token=%s" % (
        secret, key)
    resource_token = oauth.OAuthToken.from_string(resource_tok_string)
    consumer_token = oauth.OAuthConsumer(consumer_key, "")

    oauth_request = oauth.OAuthRequest.from_consumer_and_token(
        consumer_token, token=resource_token, http_url=site,
        parameters={'oauth_nonce': uuid.uuid4().hex})
    oauth_request.sign_request(
        oauth.OAuthSignatureMethod_PLAINTEXT(), consumer_token,
        resource_token)
    headers = oauth_request.to_header()
    url = "%s%s" % (site, uri)
    http = httplib2.Http()
    return http.request(url, method, body=None, headers=headers)

# API key = '<consumer_key>:<key>:<secret>'
response = perform_API_request(
    'http://server/MAAS/api/1.0', '/nodes/?op=list', 'GET', '<key>', '<secret>',
    '<consumer_key>')

Ruby

require 'oauth'
require 'oauth/signature/plaintext'

def perform_API_request(site, uri, key, secret, consumer_key)
    consumer = OAuth::Consumer.new(
        consumer_key, "",
        { :site => "http://localhost/MAAS/api/1.0",
          :scheme => :header, :signature_method => "PLAINTEXT"})
    access_token = OAuth::AccessToken.new(consumer, key, secret)
    return access_token.request(:get, "/nodes/?op=list")
end

# API key = "<consumer_key>:<key>:<secret>"
response = perform_API_request(
     "http://server/MAAS/api/1.0", "/nodes/?op=list", "<key>", "<secret>",
     "consumer_key>")

I’m running into some issues trying to use OAuth1 or OAuth1Session python library to authenticate. Does anyone have a code example of using a newer oauth library? Python 3.7 on windows using pip doesn’t seem to be compatible with the oauth on the Ubuntu box we have MAAS installed on (it’s on python 3.6 which isn’t available for Windows). I’d like to rewrite this thing to use Python 3.8 if possible or newer.