Authenticate

Describes the detailed steps to authenticate to Cluster Optimizer’s API.

This section describes the detailed steps to authenticate to Cluster Optimizer’s API.

Overview

Authentication through an HTTP API is crucial for securing resources and ensuring only authorized users and services can access data.

  • API Authentication: The API utilizes a token-based authentication mechanism to ensure secure access to cluster data and operations. Users must first generate an API token through the Cluster Optimizer interface, which is then used to authenticate all API requests.
  • Role-Based Access Control (RBAC): The API integrates with the platform’s RBAC system, ensuring that users have the appropriate permissions when accessing or modifying resources.

Cluster Optimizer’s API provides authentication through HTTP Header Authorization. For example:

GET /api/resource HTTP/1.1
Host: api.example.com
Authorization: Bearer <Access_Token>

Construct the Access Token

To generate an Access Token using an Access Key and Access Key Secret, you typically use a signing algorithm (like HMAC) to create a unique, secure key that is used for authenticating API requests. Below is a detailed step-by-step process for generating an API key securely:

1. Prepare Your Access Key and Secret

You will typically be given an Access Key (public identifier) and an Access Key Secret (private identifier). The Access Key identifies the client, while the Access Key Secret is used to sign and verify API requests securely.

2. Generate a Message to Sign

Before generating a signed API key, you need a message that combines Access Key, Timestamp and Nonce with : as a separator:

  • Access Key : The public identifier of the client.
  • Timestamp: To prevent replay attacks, include a timestamp (in nanoseconds).
  • Nonce: A random string to prevent replay attacks.

For example (in Go language):

message:=fmt.Sprintf("%s:%d:%s", accessKeyID, timestamp, nonce)

In this example, accessKeyID is the access key ID of the client, timestamp is the timestamp in nanoseconds, and nonce is a random string.

3. Sign the Message with HMAC-SHA256

The next step is to use the API key secret to generate a signature using HMAC-SHA256. This signature ensures the request has not been tampered with and that the client is legitimate.

Example (in Go language) is as follows:

func generateSignature( keyID string, keySecret string, timestamp int64, nonce string) (string, error) {
  message:=fmt.Sprintf("%s:%d:%s", keyID, timestamp, nonce)
  h:=hmac.New(sha256.New, []byte(keySecret))
  if _, err:=h.Write([]byte(message)); err!=nil {
    return"", err
  }
  signature:=base64.StdEncoding.EncodeToString(h.Sum(nil))
  returnsignature, nil
}

This function generates a signature by hashing the message using the API key secret and the HMAC-SHA256 algorithm.

4. Construct the Access Token

After generating the signature, you can construct the final API key by combining the Access Token (public) and the generated signature (private).

Example API request with a signed API key in the header is as follows:

GET /api/resource HTTP/1.1
Host: api.example.com
Authorization: Bearer <accessKey>/<timestamp>/<nonce>/<signature>

In this example:

  • accessKey is the public access key.
  • timestamp: To prevent replay attacks, include a timestamp (in nanoseconds).
  • nonce: A random string to prevent replay attacks.
  • signature is the HMAC-SHA256 signed message using the secret.

Example (in Go language) is as follows::

func GenerateAccessToken(keyID string, keySecret string, timestamp int64, nonce string) (string, error) {
  if timestamp==0 {
    timestamp=time.Now().UTC().UnixNano()
  }
  signature, err:=generateSignature(keyID, keySecret, timestamp, nonce)
  if err!=nil {
    return"", err
  }
  return utils.URLEncode(fmt.Sprintf("%s/t%d/t%s/t%s", keyID, timestamp, nonce, signature)), nil
}

5. Construct HTTP Request

You can construct an HTTP request using the access token generated and access methods provided by generated code using open api specification.

Example (in Go language) is as follows:

client:= NewAPIClient(&Configuration{
  BasePath: "http://api.example.com",
})
apiKey:="AKFgGMF3FWWe5mgkz3UWBMgaUgrzBMUV"
apiSecret:="******"
nonce:="NONe5mgkz3GBk"
accessToken, _:= GenerateAccessToken(apiKey, apiSecret, 0, nonce)
ctx:=context.Background()
ctx=context.WithValue(ctx, ContextAccessToken, accessToken)
rules, _, err:=client.NotificationRuleApi.ListNotificationRules(ctx, &NotificationRuleApiListNotificationRulesOpts{})

Next

In the next section, we will explore following APIs:

  • Management API: Manage clusters, cluster access accounts, access keys, notification channels, notification rules and so on.
  • Optimize API: Provider recommendation and optimization for kubernetes resources, such as node group, persistent volume, workload and so on.