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

# Authentication

> Guide to authenticating API requests to the WaaS service using Cobo Auth, including API key and signature details.

<Tip>
  Try [Cobo WaaS Skill](/v2/guides/overview/cobo-waas-skill) in your AI coding assistant (Claude Code, Cursor, etc.). Describe your needs in natural language to auto-generate production-ready SDK code and debug faster 🚀
</Tip>

This article explains how to authenticate your API requests to the WaaS service using Cobo Auth.

To ensure secure access to your crypto assets, the WaaS service requires you to use an EdDSA signature to sign each of your API requests, except for publicly accessible API operations.

You need to provide your API key, a nonce, and an API signature as request headers:

```
headers = {
  "Biz-Api-Key": {YOUR_API_KEY}.hex(),
  "Biz-Api-Nonce": {Nonce},
  "Biz-Api-Signature": {YOUR_API_SIGNATURE}.hex(),
}
```

* Biz-Api-Key: The API key used for the request. For more details, refer to [API key](#api-key).
* Biz-Api-Nonce: The nonce. A nonce is the current time in Unix timestamp format, measured in milliseconds.
* Biz-Api-Signature: The API signature. To learn how to calculate an API signature, see [Calculate an API Signature](#calculate-the-api-signature).

If you are using Cobo's WaaS SDKs, you only need to provide your API secret because the SDKs handles the remaining steps for you.

## API key and API secret

To enable secure and authenticated communication between clients and the WaaS 2.0 service, a mechanism based on the API key and API secret is used.  This mechanism relies on cryptographic key pairs to verify the identity of the client and the integrity of the requests.

### API key

The API key is the public key in the cryptographic key pair. It is used to identify the client making the API request.

The API key is associated with permissions and wallet scopes, which define the actions the client can perform and the wallets they can access. Different API keys can be assigned with varying permissions and wallet scopes, providing granular control over client capabilities.
<Info>For more details about permissions and wallet scopes, see [Permissions and wallet scopes](/v2/guides/overview/permissions-and-scopes).</Info>

### API secret

The API secret is the private key in the key pair. It is used to sign API requests, guaranteeing their authenticity and integrity. The API secret must always remain confidential and secure to prevent unauthorized access.

The API key and API secret work as a pair to secure communication with the WaaS 2.0 service:

* The API key is included in API requests to identify the client to the WaaS service. It is required to be registered on Cobo Portal. For more information, refer to [Register an API key](https://manuals.cobo.com/en/portal/developer-console/create-api-key).
* The API secret is used to generate a signature for each API request. The WaaS service validates the signature to confirm the request’s authenticity and prevent tampering.

### Generate an API key and an API secret

This section introduces three ways to generate an API key and an API secret using the Ed25519 algorithm. You can also generate them using other tools that use the Ed25519 algorithm.

The public key will be used as an API key, and the private key will be used as an API secret.

#### Use Cobo CLI

Cobo Command Line Interface (CLI) is a powerful developer tool designed to help you build, test, and manage your integration with Cobo Wallet-as-a-Service (WaaS) 2.0 directly from the command line.

1. Install Cobo CLI using the following command:

   ```shell theme={null}
   # Install Cobo CLI using pip (Python 3.9 or newer is required).
   pip install cobo-cli
   # Alternatively, you can install Cobo CLI using Homebrew.
   brew install cobo-cli
   # Test if the installation is successful
   cobo version
   ```

   For more details about the system requirements for Cobo CLI, please refer to [Install Cobo CLI](/v2/developer-tools/cobo-cli/quick-start-guide#system-requirements).

2. Use the `keys generate` command to generate a key pair using the Ed25519 algorithm as follows:

   ```shell theme={null}
   # Generate an API key and an API secret
   cobo keys generate --key-type API
   ```

   Generated keys are securely stored in your configuration file (default: `~/.cobo/config.toml`). For more information about this command, refer to [Key management](/v2/developer-tools/cobo-cli/key-management).

#### Use OpenSSL

In a terminal window, run the following OpenSSL commands to generate a key pair using the Ed25519 algorithm:

```shell theme={null}
openssl genpkey -algorithm ed25519 -out private_key.pem

openssl pkey -in private_key.pem -pubout -out public_key.pem

echo "Private Key (Hex):"
openssl pkey -in private_key.pem -text | grep 'priv:' -A 3 | tail -n +2 | tr -d ':\n ' && echo

echo "Public Key (Hex):"
openssl pkey -pubin -in public_key.pem -text | grep 'pub:' -A 3 | tail -n +2 | tr -d ':\n ' && echo
```

You will see the output similar to the following example:

```
Private Key (Hex):
06f78882576ec0e05b1e51a33548da7e8cf958c190ba96be77b1c671f98a2b5f
Public Key (Hex):
5987dedc180167b7ab1d27e6009e5065d10d764cd85d7b64f8c968ca40326e28
```

Use the `Private Key (Hex)` as your API secret and the `Public Key (Hex)` as your API key.

#### Use the Python library

1. Install the `PyNaCl` Python library.

   In a terminal window, run the following command:

   ```shell theme={null}
   pip install PyNaCl
   ```

2. Generate a key pair.
   Import the function from the Python library to generate a key pair using the Ed25519 algorithm as follows:

   ```python theme={null}
   from nacl.signing import SigningKey
   # Create a key pair.
   sk = SigningKey.generate()
   # Print the private key in hexadecimal format.
   print("private key:", sk.encode().hex())
   # Print the public key in hexadecimal format.
   print("public key:", sk.verify_key.encode().hex())
   ```

### Register the API key

After generating an API key, you need to register the key and configure related permissions on Cobo Portal. To learn how to register an API key, see [Register an API key](https://manuals.cobo.com/en/portal/developer-console/create-api-key).

<Warning>
  The Development and Production environments use **separate Cobo Portals with separate API keys**. An API key registered in the Development environment (`portal.dev.cobo.com`) cannot authenticate requests to the Production host (`api.cobo.com`), and vice versa. Using a key from the wrong environment returns HTTP 401 / error code 2024 with the message `Your API key is not registered in this environment. Development and Production environments use separate API keys.` See [Development and production environments](/v2/guides/overview/environments) for host URLs and portal addresses.
</Warning>

## Nonce

A nonce is the current time in Unix timestamp format, measured in milliseconds.

## Calculate the API signature

The following steps introduce how to calculate an API signature.

1. First, concatenate a string based on your request as follows:

   str\_to\_sign = `{METHOD}|{PATH}|{NONCE}|{PARAMS}|{BODY}`

   | **Field** | **Description**                                                                                                                                                       | **Example**                                                             |
   | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
   | METHOD    | The HTTP method.                                                                                                                                                      | `GET`                                                                   |
   | PATH      | The API endpoint.                                                                                                                                                     | `/v2/transactions/transfer`                                             |
   | NONCE     | The nonce value. The current time in Unix timestamp format, measured in milliseconds. This value must be the same as the value in the `Biz-Api-Nonce` request header. | `1718587017026`                                                         |
   | PARAMS    | (If applicable) The query parameters.                                                                                                                                 | `chain_id=ETH&limit=10`                                                 |
   | BODY      | (If applicable) The raw request body in string format.                                                                                                                | `{"name":"Default","wallet_subtype":"Asset","wallet_type":"Custodial"}` |

2. Use the `hashlib` library to perform SHA-256 hashing twice on the string as follows:

   ```python theme={null}
   import hashlib
   content_hash = hashlib.sha256(hashlib.sha256(str_to_sign.encode()).digest()).digest()
   ```

3. Use the API secret to sign the string as follows:

   ```python theme={null}
   from nacl.signing import SigningKey

   # Create an Ed25519 signing key. Replace `api_secret` with your API secret.
   sk = SigningKey(bytes.fromhex(api_secret))
   # Sign the hashed message
   signature = sk.sign(content_hash).signature.hex()
   ```

Now you've calculated an API signature.
