Skip to end of metadata
Go to start of metadata



This is a technical description of the authentication method used when API clients make requests to the Chef Server

For a broad overview of the authentication process see Authentication and Authorization

Protocol Overview

Authentication occurs by constructing a specific set of HTTP headers, and then signing a subset of those headers and information about the request using the API client's private key. The server verifies the signature using the public key of the specified API client.

Required Authentication Headers

Every API request must contain the following headers:

  • X-Ops-Timestamp: A timestamp in ISO-8601 format. The time must be in UTC, indicated by a trailing Z, and separated by the character "T". The following is an example of a time in this format:
  • X-Ops-UserId: The name of the API client whose private key will be used to create the authorization header.
  • X-Ops-Content-Hash: The body of the request, hashed using SHA1 and encoded using Base64. See Hashing below.
  • X-Ops-Sign: Set to "version=1.0"
  • X-Ops-Authorization-N: One or more headers whose value are the signature of the "canonical headers", encoded in Base64. See Canonical Headers and X-Ops-Authorization Headers below.

Note, that these are the headers required for authentication. Other headers such as "Accept" should also be included in your request.

Canonical Headers

The Canonical Header is a string in the following format:

HTTP_METHOD is the method being used in the API request (e.g., GET or POST) and must be capitalized. HASHED_PATH is the path of the request (e.g., "/clients") hashed with SHA1 and encoded using Base64 (see Hashing). The path must not have repeated "/"s and must not end in a "/", unless the path is "/".

Hashing

All Hashing is done using SHA1 and encoded in Base64. The Base64 encoding should have line breaks every 60 characters.

X-Ops-Authorization Headers

To create the Authorization Headers, the canonical header is signed with the API client's private key and encoded using Base64. The private key must be an RSA key in SSL's PEM format. This signature is then broken in into 60 character strings and placed in the headers X-Ops-Authorization-1 through X-Ops-Authorization-N where N is the last header needed to send the entire string.

The Chef server decrypts the X-Ops-Authorization headers and ensures their content matches the content of the non-encrypted headers that were sent. Further, the timestamp of the message is checked to ensure that the request has been received within a reasonable amount of time.

Within Chef, this authorization method is implemented by mixlib-authentication.

Making API Requests in Ruby

From a Knife Plugin or Knife Exec script

When creating a Knife Plugin or Knife Exec script, the libraries required to make authenticated API requests have already been included. In the most cases, one will not need to make API calls directly when using knife plugins or knife exec scripts, as it is easier to interact with nodes, clients, and other objects via other means. See the Knife Plugins and Knife Exec page for details.

In a Knife Exec script (and Shef), the api object already includes all of the necessary configuration to make API calls using the following methods:

API Request from a Knife Exec Script, Example 1
API Request from a Knife Exec Script, Example 2

Moreover, whenever possible, api will return an object of the relevant type, on which you can call methods.

API Request from a Knife Exec Script, Example 2

In a Knife Plugin, the rest object is similar to the api client. The only difference is the function names:

API Request from a Knife Plugin

Note that knife will handle any HTTP exceptions that arise within your knife plugin or exec script.

Arbitrary Ruby Scripts

On a system with Chef installed, the easiest way to make authenticated API request is to use the chef libraries.

Alternatively, you can use mixlib-authentication directly.

Making API Requests in Python


As with Knife Plugins and Knife Exec scripts, you will typically not want to make API calls directly, but use other facilities provided by the library.

For example, the following is the example provided in PyChef's README:

However, it is also possible to make API calls directly:

Note: Both of these examples assume that your current working directory is such that PyChef can find a valid chef configuration file in the same manner chef-client or knife would find its configuration.

Making API Requests with Curl

It is also possible to make authenticated API requests using curl or wget provided you have various common tools installed.
The following is an example of how one can create an authenticated request using curl. It is a Bash shell script which requires the following utilities: awk, openssl

After sourcing this shell script into your local shell, you might use it as follows:







Hosted Chef Authorization


API Clients



Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.