Opscode

Table Of Contents

Chef Server API

The Chef Server API is used to provide access to objects on the Chef Server, including nodes, environments, roles, cookbooks (and cookbook versions), and to manage an API client list and the associated RSA public key-pairs.

Requirements

The Chef Server API has the following requirements:

  • Access to a Chef Server running Chef 0.9.x or above
  • The Accept header must be set to “application/json”
  • The X-Chef-Version header must be set to the version of the Chef Server API that is being used
  • A request must be signed using Mixlib::Authentication
  • A request must be well-formatted. The easiest way to ensure a well-formatted request is to use the Chef::REST library that is bundled with Chef.

Authentication Headers

Authentication to the Chef Server occurs when a specific set of HTTP headers are signed using a private key that is associated with the machine from which the request is made. The request is authorized if the Chef Server can verify the signature using the public key. Only authorized actions are allowed.

Note

Most authentication requests made to the Chef Server are abstracted from the user. Such as when using Knife or the Chef Server user interface. In some cases, such as when using the knife exec subcommand, the authentication requests need to be made more explicitly, but still in a way that does not require authentication headers. In a few cases, such as when using arbitrary Ruby code or cURL, it may be necessary to include the full authentication header as part of the request to the Chef Server.

Header Format

All hashing is done using SHA1 and encoded in Base64. Base64 encoding should have line breaks every 60 characters. Each canonical header should be encoded in the following format:

Method:HTTP_METHOD
HashedPath:HASHED_PATH
X-Ops-Content-Hash:HASHED_BODY
X-Ops-Timestamp:TIME
X-Ops-UserId:USERID

where:

  • HTTP_METHOD is the method used in the API request (GET, POST, and so on)
  • HASHED_PATH is the path of the request (/name_of_endpoint for the open source Chef Server and /organizations/organization_name/name_of_endpoint for Hosted Chef or Private Chef). The HASHED_PATH must be hashed using SHA1 and encoded using Base64 and must not have repeated forward slashes (/) or end in a forward slash (unless the path is /).
  • The private key must be an RSA key in the SSL .pem file format. This signature is then broken into character strings (of not more than 60 characters per line) and placed in the header.

The Chef Server decrypts this header and ensures its content matches the content of the non-encrypted headers that were in the request. The timestamp of the message is checked to ensure the request was received within a reasonable amount of time. One approach generating the signed headers is to use mixlib-authentication, which is a class-based header signing authentication object similar to the one used in Chef.

Required Headers

The following authentication headers are required:

Feature Description
Accept The format in which response data will be provided, such as json, xml, html, and so on. This header is not required, but is often included to ensure that response data is returned in the desired format.
Host The host name (and port number) to which a request is sent. (Port number 80 does not need to be specified.) For example: api.opscode.com (which is the same as api.opscode.com:80) or api.opscode.com:443.
X-Chef-Version The version of the Chef executable from which a request is made. This header ensures that responses are in the correct format. For example: 11.0.4.x or 0.10.x.
X-Ops-Authorization-N One (or more) 60 character segments that comprise the canonical header. A canonical header is signed with the private key used by the client machine from which the request is sent, and is also encoded using Base64. If more than one segment is required, each should be named sequentially, e.g. X-Ops-Authorization-1, X-Ops-Authorization-2, X-Ops-Authorization-N, where N represents the integer used by the last header that is part of the request.
X-Ops-Content-Hash The body of the request. The body should be hashed using SHA1 and encoded using Base64. All hashing is done using SHA1 and encoded in Base64. Base64 encoding should have line breaks every 60 characters.
X-Ops-Sign Set this header to the following value: version=1.0.
X-Ops-Timestamp The timestamp, in ISO-8601 format and with UTC indicated by a trailing Z and separated by the character T. For example: 2013-03-10T14:14:44Z.
X-Ops-UserId The name of the API client whose private key will be used to create the authorization header.

Example

The following example shows an authentication request to Hosted Chef:

GET /organizations/organization_name/nodes HTTP/1.1
  Accept: application/json
  Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
  X-Ops-Sign: algorithm=sha1;version=1.0;
  X-Ops-Userid: user_id
  X-Ops-Timestamp: 2013-03-12T17:13:28Z
  X-Ops-Content-Hash: 2jmj7l5rfasfgSw0ygaVb/vlWAghYkK/YBwk=
  X-Ops-Authorization-1: BE3NnHeh5yFTiT3ifuwLSPCCYasdfXaRN5oZb4c6hbW0aefI
  X-Ops-Authorization-2: sL4j1qtEZzi/2WeF67UuytdsdfgbOc5CjgECQwqrym9gCUON
  X-Ops-Authorization-3: yf0p7PrLRCNasdfaHhQ2LWoE/+kTcu0dkasdfvaTghfCDC57
  X-Ops-Authorization-4: 155i+ZlthfasfhbfrtukusbIUGBKUYFjhbvcds3k0i0gqs+V
  X-Ops-Authorization-5: /sLcR7JjQky7sdafIHNEEBQrISktNCDGfFI9o6hbFIayFBx3
  X-Ops-Authorization-6: nodilAGMb166@haC/fttwlWQ2N1LasdqqGomRedtyhSqXA==
  Host: api.opscode.com:443
  X-Chef-Version: 11.4.0
  User-Agent: Chef Knife/11.4.0 (ruby-1.9.2-p320; ohai-6.16.0; x86_64-darwin11.3.0; +http://opscode.com)

Endpoints

For Hosted Chef and Private Chef, each authentication request must include /organizations/organization_name as part of the name for the endpoint. For the open source Chef Server, each authentication request must include /clients as part of the name of the endpoint. For example, the full endpoint for getting a list of roles on Hosted Chef or Private Chef:

GET /organizations/organization_name/roles

and for the same request, but to the open source Chef Server:

GET /clients/roles

The Chef Server API has the following endpoints: