> ## 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 with Cobo OAuth

> Authenticate Cobo Portal Apps with Cobo OAuth. Learn to use app keys, secrets, and Org Access Tokens for secure API requests.

<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 section explains how to authenticate your API requests to the WaaS service in Cobo Portal Apps using Cobo OAuth.

## Cobo OAuth vs Cobo Auth

Cobo Auth and Cobo OAuth are two authentication mechanisms. Cobo Auth identifies clients using an API key and an API secret, while Cobo OAuth identifies clients using an app key and an app secret, and controls access to resources in other organizations through an Org Access Token, along with its permissions and scopes.

* If you are developing Cobo Portal Apps for installation and use across different organizations, use Cobo OAuth to authenticate your API requests.
* If you are developing other types of apps to access data and resources within your own organization, use Cobo Auth instead. For more details about Cobo Auth, refer to [Authentication with Cobo Auth](/v2/guides/overview/cobo-auth).

## With the WaaS SDK

If you are using the [WaaS SDK](/v2/developer-tools/quickstart-python), you only need to provide the app secret and Org Access Token in the API request as follows:

```python theme={null}
from cobo_waas2 import Configuration, ApiClient, WalletsApi

configuration = Configuration(
    # Use `https://api.dev.cobo.com/v2` for the development environment, or `https://api.cobo.com/v2` for the production environment.
    host="https://api.dev.cobo.com/v2",
    # Replace `<APP_SECRET>` with your app secret.
    api_private_key="<APP_SECRET>",
)

client = ApiClient(configuration=configuration)
# Replace `{ORG_ACCESS_TOKEN}` with the Org Access Token.
client.set_default_header("AUTHORIZATION", f"Bearer {ORG_ACCESS_TOKEN}")
```

* To learn how to generate an app key and an app secret, see [Generate an app key and an app secret](#generate-an-app-key-and-an-app-secret).
* To learn how to get and use Org Access Tokens, refer to [Org Access Tokens](/v2/apps/org-access-tokens).

## Without the WaaS SDK

If you don't use the WaaS SDK, you need to provide all the required authentication information in the request header as follows:

```javascript theme={null}
headers = {
    // Replace `{ORG_ACCESS_TOKEN}` with the Org Access Token.
    "Authorization": Bearer {ORG_ACCESS_TOKEN},
    // Replace `<APP_KEY>` with your app key.
    "Biz-Api-Key": {APP_KEY}.hex(),
    // Replace `{Nonce}` with the current time in Unix timestamp format, measured in milliseconds.
    // This value must be the same as the value of the `TIMESTAMP` field in the API signature.
    "Biz-Api-Nonce": {Nonce},
    // Replace `{YOUR_API_SIGNATURE}` with the calculated API signature.
    "Biz-Api-Signature": {YOUR_API_SIGNATURE}.hex(),
}
```

* To learn how to generate an app key and an app secret, see [Generate an app key and an app secret](#generate-an-app-key-and-an-app-secret).
* To learn how to get and use Org Access Tokens, refer to [Org Access Tokens](/v2/apps/org-access-tokens).
* To learn how to calculate the API signature using your app key, refer to [Calculate an API signature](#calculate-an-api-signature).

## App key and app secret

To ensure secure and authenticated communication between Cobo Portal Apps and the WaaS 2.0 service, a mechanism based on the app key and app secret is used. This mechanism relies on cryptographic key pairs to verify the identity of the app and the integrity of the requests.

### App key

The app key is the public key in the cryptographic key pair. It is used to identify the Cobo Portal App making the API request.

### App secret

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

The app key and app secret form a cryptographic key pair that enables secure communication with the WaaS service:

* The app key is included in API requests to identify the application to the WaaS service. It is also required in the app manifest file. For more information, refer to [Configure the manifest file](/v2/apps/build-app#configure-the-manifest-file).
* The app secret signs the requests. The WaaS service verifies the signature to confirm the request's authenticity and integrity.

### Generate an app key and an app secret

This section introduces three ways to generate an app key pair (an app key and an app secret) using the Ed25519 algorithm. You can also generate app key pairs using other tools that use the Ed25519 algorithm.

The public key will be used as an app key, and the private key will be used as an app 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 an app key pair using the Ed25519 algorithm as follows:

   ```shell theme={null}
   # Generate an app key pair
   cobo keys generate --key-type APP
   ```

   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 app secret and the `Public Key (Hex)` as your app key.

#### Use a 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())
   ```

## Calculate an 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}|{TIMESTAMP}|{PARAMS}|{BODY}`

   | Field       | Description                                                                                                                          | Example                                                                 |
   | ----------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- |
   | `METHOD`    | The HTTP method.                                                                                                                     | `GET`                                                                   |
   | `PATH`      | The API endpoint.                                                                                                                    | `/v2/transactions/transfer`                                             |
   | `TIMESTAMP` | The current time in Unix timestamp format, measured in milliseconds. This value must be the same as the nonce in the 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 your app secret to sign the string as follows:
   ```python theme={null}
   # Replace `app_secret` with your app secret.
   sk = ed25519.SigningKey(sk_s=bytes.fromhex(app_secret))
   # Sign the hashed message
   signature = sk.sign(content_hash)
   ```

Now you've calculated an API signature.
