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.
The Chef Server API has the following requirements:
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.
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.
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
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.
The following authentication headers are required:
|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.|
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)
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:
and for the same request, but to the open source Chef Server:
The Chef Server API has the following endpoints: