> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cloud.cdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> All requests to the Connect AI Embed API must be properly authenticated using JSON Web Tokens (JWT).

CData requires that a JWT is signed using the RSA 256 algorithm.

## Creating a JWT

Follow these steps to create a JWT.

<Steps>
  <Step>
    Create a JWT header with this format:
    `{"alg": "RS256", "typ": "JWT"}`
  </Step>

  <Step>
    Base64url encode the JWT header.
  </Step>

  <Step>
    Construct a JSON Claims Set for the JWT with the following parameters.

    | Parameter        | Description                                                                                                                                                                                                                                                                                                                        |
    | :--------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `tokenType`      | powered-by (This JWT token is type `powered-by`.)                                                                                                                                                                                                                                                                                  |
    | `iat`            | The time the JWT is issued, expressed as the number of seconds from 1970-01-01T0:0:0Z measured in UTC.                                                                                                                                                                                                                             |
    | `exp`            | The date and time at which the token expires, expressed as the number of seconds from 1970-01-01T0:0:0Z measured in UTC.                                                                                                                                                                                                           |
    | `iss`            | The account Id of the parent account.                                                                                                                                                                                                                                                                                              |
    | `sub`            | The account Id of the sub-account (optional for [Create Account](/en/API/Account-API) and [List Connections](/en/API/List-Connections)).                                                                                                                                                                                           |
    | `connection_ids` | A JSON array containing a list of connection Ids accessible to the end user (required when calling the per-connection MCP endpoint; otherwise optional). Must be a JSON array of strings (such as `["id-1","id-2"]`), not a JSON-encoded string. Passing a stringified array causes the per-connection MCP endpoint to return 403. |

    <p>The following is an example JSON Claim Set for the JWT:</p>

    ```bash theme={null}
    {
       "tokenType": "powered-by",
       "iat": current_time_seconds,
       "exp": expiration_time_seconds,
       "iss": "your_oem_account_id_here",
       "sub": "your_sub_account_id_here",
       "connection_ids": ["connection_id_1","connection_id_2"]
     }
    ```
  </Step>

  <Step>
    Base64url encode the JSON Claims Set without any line breaks.
  </Step>

  <Step>
    Create a string for the encoded JWT Header and the encoded JWT Claims Set in the following format:

    ```bash theme={null}
    Base64UrlEncode(JWT_header) + "." + Base64UrlEncode(JWT_Claims_Set)
    ```
  </Step>

  <Step>
    Sign the token with your [private key](#generating-a-private-key) and format the token.
  </Step>

  <Step>
    Register the [public key](#generating-a-public-key) certificate in Privacy-Enhanced Mail (PEM) format in the management account. Open a support ticket with Connect AI to register the public key.
  </Step>
</Steps>

## Generating JWT Keys

A JWT requires a public and private key in PEM format. You sign the JWT with your private key and you register the public key with CData. There are several ways to generate JWT keys. The examples below use `openssl`.

### Generating a Private Key

The following example shows how to generate the JWT private key using `openssl`:

```bash theme={null}
openssl genrsa -out ./private.key 4096
```

Your current directory should now contain the `private.key`. Do not share this file with anyone!

### Generating a Public Key

Use the private key to generate the public key. In `openssl`, the command is as follows:

```bash theme={null}
openssl rsa -in private.key -pubout -outform PEM -out public.key
```

Your current directory should now contain the `public.key`, which you need to share with CData.

## Code Samples

Click the relevant tab for the code sample for creating a JWT.

<Tabs>
  <Tab title="Java">
    **Creating a JWT in Java:**

    Add the `com.auth0:java-jwt` dependency to your project (Maven: `com.auth0:java-jwt:4.4.0`, Gradle: `implementation 'com.auth0:java-jwt:4.4.0'`).

    ```java expandable wrap theme={null}
    import com.auth0.jwt.JWT;
    import com.auth0.jwt.algorithms.Algorithm;

    import java.security.KeyFactory;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.util.Arrays;
    import java.util.Base64;
    import java.util.Date;
    import java.util.List;

    public class JWTExample {

        public static void main(String[] args) throws Exception {

            String privateKeyPem = """
                    your_secret_key_here
                    """
                .replace("-----BEGIN PRIVATE KEY-----", "")
                .replaceAll("\\s+", "")
                .replace("-----END PRIVATE KEY-----", "");

            byte[] keyBytes = Base64.getDecoder().decode(privateKeyPem);
            RSAPrivateKey privateKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
                .generatePrivate(new PKCS8EncodedKeySpec(keyBytes));

            List<String> connectionIds = Arrays.asList(
                "your_connection_id_1_here",
                "your_connection_id_2_here"
            );

            long nowSeconds = System.currentTimeMillis() / 1000;

            String token = JWT.create()
                .withClaim("tokenType", "powered-by")
                .withIssuedAt(new Date(nowSeconds * 1000))
                .withExpiresAt(new Date((nowSeconds + 300) * 1000))
                .withIssuer("your_oem_account_id_here")
                .withSubject("your_sub_account_id_here")
                .withClaim("connection_ids", connectionIds)
                .sign(Algorithm.RSA256(null, privateKey));

            System.out.println(token);
        }
    }
    ```
  </Tab>

  <Tab title="Python">
    **Creating a JWT in Python:**

    Use the PyJWT and cryptography packages in Python. You can install these via pip: `pip install pyjwt` and `pip install cryptography`.

    ```python expandable wrap theme={null}
    import jwt
    import datetime

    # Secret key used to sign the JWT
    secret_key = """your_secret_key_here"""

    # Payload (claims) for the JWT

    current_datetime_seconds = datetime.datetime.today().timestamp()
    expiration_datetime_seconds = (datetime.datetime.today() + datetime.timedelta(minutes=5)).timestamp();

    payload = {
        'tokenType': 'powered-by',
        'iat': current_datetime_seconds,
        'exp': expiration_datetime_seconds,
        'iss': 'your_oem_account_id_here',
        'sub': 'your_sub_account_id_here',
        'connection_ids': ['your_connection_id_1_here', 'your_connection_id_2_here'],  # optional: required for scoped MCP server access
      }

    # Create the JWT token
    token = jwt.encode(payload, secret_key, algorithm='RS256')

    print(token)
    ```
  </Tab>

  <Tab title="C#">
    **Creating a JWT in C#:**

    Use the Nuget Package Manager Console to install the `System.IdentityModel.Tokens.Jwt` library with the following command:

    `Install-Package System.IdentityModel.Tokens.Jwt`.

    ```csharp expandable wrap theme={null}
    using System.Collections.Generic;
    using System.IdentityModel.Tokens.Jwt;
    using System.Security.Cryptography;
    using Microsoft.IdentityModel.Tokens;

    var secretKey = "your_secret_key_here";
    var rsa = new RSACryptoServiceProvider();
    rsa.ImportFromPem(secretKey.ToCharArray());
    var signingCredentials = new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha256);

    var currentTime = DateTime.UtcNow;
    var expirationTime = currentTime.AddMinutes(5);

    var payload = new JwtPayload
    {
        { "tokenType", "powered-by" },
        { "iss", "your_oem_account_id_here" },
        { "sub", "your_sub_account_id_here" },
        { "connection_ids", new List<string> { "your_connection_id_1_here", "your_connection_id_2_here" } }, 
        // List<string> serializes as a JSON array in the token payload. Optional: required for scoped MCP server access
        { "iat", EpochTime.GetIntDate(currentTime) },
        { "exp", EpochTime.GetIntDate(expirationTime) },
    };

    var token = new JwtSecurityToken(new JwtHeader(signingCredentials), payload);
    var tokenString = new JwtSecurityTokenHandler().WriteToken(token);
    Console.WriteLine(tokenString);
    ```
  </Tab>

  <Tab title="node.js">
    **Creating a JWT in node.js:**

    ```js wrap theme={null}
    const jwt = require("jsonwebtoken");

    // Claims
    const currentTimeInSeconds = Math.floor(Date.now() / 1000); // Convert milliseconds to seconds
    const expirationTimeInSeconds = currentTimeInSeconds + 60 * 5; // Example: 5 min

    const claims = {
      tokenType: "powered-by",
      iat: currentTimeInSeconds,
      exp: expirationTimeInSeconds,
      iss: "your_oem_account_id_here",
      sub: "your_sub_account_id_here",
      connection_ids: ["your_connection_id_1_here", "your_connection_id_2_here"], // optional: required for scoped MCP server access
    };

    // Secret key to sign the token
    const secretKey = `your_secret_key_here`;

    // Generate JWT token
    const token = jwt.sign(claims, secretKey, { algorithm: "RS256" });

    console.log(token);
    ```

    To run the code, save index.js and execute it as follows:

    ```bash theme={null}
    node index.js
    ```
  </Tab>
</Tabs>
