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

# About authentication credentials

> Learn about IdP credentials, CDF authentication, and common troubleshooting for developers.

This guide explains the authentication credentials you need to connect applications and services to Cognite Data Fusion (CDF), how they work together, and how to troubleshoot common issues.

## What are IdP credentials vs. CDF credentials?

When authenticating to CDF, you work with two distinct systems that work together:

### Identity provider (IdP) credentials

Your **identity provider (IdP)** is an external authentication service (like Microsoft Entra ID, Amazon Cognito, or Auth0) that verifies who you are. IdP credentials include:

* **IdP client ID**: A unique identifier for your application registered in the IdP. Think of this as your application's username in the IdP system.
* **IdP client secret**: A confidential password for your application. This proves your application is who it claims to be.
* **IdP tenant ID**: (For Microsoft Entra ID) Identifies which organization's directory to authenticate against.
* **IdP token URL**: The endpoint where your application requests access tokens from the IdP.

These credentials are created and managed in your IdP (not in CDF). They allow your application to obtain an **access token** from the IdP.

### CDF credentials

**CDF credentials** refer to the permissions and group memberships configured within Cognite Data Fusion:

* **CDF groups**: Define what capabilities (permissions) members have to access CDF resources.
* **CDF service accounts**: Represent applications or processes that need to access CDF.
* **CDF capabilities**: Specific permissions like `timeseries:read` or `assets:write`.

CDF doesn't store passwords or secrets. Instead, CDF trusts the access tokens issued by your configured IdP.

### How they work together

```mermaid theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
sequenceDiagram
    participant App as Your application
    participant IdP as Identity provider
    participant CDF as Cognite Data Fusion
    
    App->>IdP: 1. Request token with client ID + secret
    IdP->>IdP: 2. Verify credentials
    IdP->>App: 3. Return access token
    App->>CDF: 4. API request with access token
    CDF->>CDF: 5. Validate token & check group membership
    CDF->>App: 6. Return data (if authorized)
```

**The flow:**

1. Your application uses IdP credentials (client ID and secret) to request an access token from the IdP.
2. The IdP verifies the credentials and issues an access token.
3. Your application includes this access token in requests to CDF.
4. CDF validates the token and checks which CDF groups the principal (user or service account) belongs to.
5. CDF grants or denies access based on the capabilities assigned to those groups.

## Understanding audience and scopes

When requesting an access token from your IdP, you need to specify two important parameters:

### Audience

The **audience** identifies which resource server (API) the access token is intended for. For CDF, this is typically your CDF cluster URL.

**Example values:**

* `https://api.cognitedata.com` (for most CDF clusters).
* `https://westeurope-1.cognitedata.com` (for specific regional clusters).
* `https://your-cluster.cognitedata.com` (for your specific cluster).

The audience ensures that tokens issued for CDF cannot be used to access other APIs, and vice versa.

### Scopes

**Scopes** define what level of access you're requesting. They act as filters on top of your CDF group permissions. You can only access what both your scopes AND your CDF group memberships allow.

For the complete list of scopes and their definitions, see [Access token scopes](/cdf/access/concepts/access_token_scopes).

For most applications, use the `user_impersonation` scope to get full access based on your CDF group memberships:

```python theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
scopes = ['https://your-cluster.cognitedata.com/user_impersonation']
```

Or use the shorthand `.default` scope (for Microsoft Entra ID):

```python theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
scopes = ['https://your-cluster.cognitedata.com/.default']
```

## User authentication vs. service principal authentication

CDF supports two types of authentication principals:

|                    | User authentication (interactive)         | Service principal (non-interactive)                   |
| ------------------ | ----------------------------------------- | ----------------------------------------------------- |
| **Use for**        | Web apps, desktop apps, Jupyter notebooks | Extractors, transformations, CI/CD, Cognite Functions |
| **Flow**           | Authorization code with PKCE              | Client credentials (OAuth 2.0)                        |
| **Credentials**    | User's username/password                  | Client ID + secret                                    |
| **Token lifetime** | Shorter (about 1 hour)                    | Can be longer                                         |
| **CDF principal**  | User account                              | Service account                                       |

| Setup requirement | User authentication  | Service principal             |
| ----------------- | -------------------- | ----------------------------- |
| IdP app type      | Public client or SPA | Confidential client           |
| Redirect URIs     | Required             | Not required                  |
| Client secret     | Not used             | Required                      |
| CDF membership    | User in CDF groups   | Service account in CDF groups |

## Sessions for long-lived workloads

Access tokens are short-lived (typically about 1 hour). For background workloads that run for extended periods—such as Transformations, Functions, Data Workflows, and the PostgreSQL Gateway—CDF uses **sessions** instead of tokens alone.

Sessions maintain access to CDF resources over time. You create a session using your IdP credentials (client ID and secret), and the API returns a **nonce** that you pass to the consumer (for example, a Transformation or Function). The consumer binds the session to obtain an access token and session key for subsequent refreshes.

<Info>
  Sessions support three creation methods: **client credentials** (for service accounts), **token exchange** (run as current user), and **one-shot token exchange** (short-lived, no refresh). See the [Sessions API reference](/api-reference/concepts/20230101/sessions) for details.
</Info>

## Step-by-step: Obtaining and using credentials

### For service principal authentication (most common for developers)

To obtain credentials for service principal authentication, follow the guides for your IdP. These guides cover registering your application, creating a client secret, configuring API permissions, creating a CDF service account, and adding it to groups.

**Microsoft Entra ID:**

* [Configure CDF with Microsoft Entra ID](/cdf/access/entra/guides/configure_cdf_azure_oidc) — Register the Cognite API and permit organizational sign-in.
* [Add service principal](/cdf/access/entra/guides/add_service_principal) — Register your app, create a client secret, and add the service principal to a CDF group.
* [Create and link Entra ID groups](/cdf/access/entra/guides/create_groups_oidc) — Create groups and link them to Entra ID groups.

**Amazon Cognito:** [Configure CDF with Amazon Cognito](/cdf/access/aws/guides/configure_cdf_cognito)

After you have your IdP credentials (client ID, client secret, tenant ID) and a linked CDF service account, use them in your application as follows.

<Steps>
  <Step title="Use credentials in your application">
    **Python example:**

    ```python wrap theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
    from cognite.client import CogniteClient
    from cognite.client.credentials import OAuthClientCredentials

    # Your IdP credentials
    client_id = "your-client-id"
    client_secret = "your-client-secret"
    tenant_id = "your-tenant-id"  # For Entra ID
    cluster = "your-cluster"  # e.g., "westeurope-1"
    project = "your-project"

    # Token URL (for Entra ID)
    token_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"

    # Scopes and audience
    scopes = [f"https://{cluster}.cognitedata.com/.default"]

    # Create credentials provider
    credentials = OAuthClientCredentials(
        token_url=token_url,
        client_id=client_id,
        client_secret=client_secret,
        scopes=scopes
    )

    # Create CDF client
    client = CogniteClient(
        project=project,
        base_url=f"https://{cluster}.cognitedata.com",
        credentials=credentials
    )

    # Test connection
    print(client.iam.token.inspect())
    ```

    **Configuration file example (for extractors):**

    ```yaml wrap theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
    cognite:
      project: your-project
      base-url: https://your-cluster.cognitedata.com
      
      idp-authentication:
        client-id: ${IdP_CLIENT_ID}
        client-secret: ${IdP_CLIENT_SECRET}
        tenant: ${IdP_TENANT_ID}
        scopes:
          - https://your-cluster.cognitedata.com/.default
        token-url: https://login.microsoftonline.com/${IdP_TENANT_ID}/oauth2/v2.0/token
        audience: https://your-cluster.cognitedata.com
    ```
  </Step>
</Steps>

### For user authentication (interactive applications)

For interactive applications (web apps, Jupyter notebooks, desktop apps), register your application in your IdP as a **public client** or **SPA**, configure redirect URIs, and implement the authorization code flow with PKCE. No client secret is needed.

**Microsoft Entra ID:** See [Register custom web applications](/cdf/access/entra/guides/register_custom_webapp) or [Desktop apps and Python SDK](/dev/sdks/python/register_app_jupyter_sdk) depending on your use case.

<Steps>
  <Step title="Implement authorization code flow">
    **Python example:**

    ```python wrap theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
    from cognite.client import CogniteClient
    from cognite.client.credentials import OAuthInteractive

    client_id = "your-client-id"
    tenant_id = "your-tenant-id"
    cluster = "your-cluster"
    project = "your-project"

    authority_url = f"https://login.microsoftonline.com/{tenant_id}"
    scopes = [f"https://{cluster}.cognitedata.com/.default"]

    credentials = OAuthInteractive(
        authority_url=authority_url,
        client_id=client_id,
        scopes=scopes
    )

    client = CogniteClient(
        project=project,
        base_url=f"https://{cluster}.cognitedata.com",
        credentials=credentials
    )

    # This will open a browser for user login
    print(client.iam.token.inspect())
    ```
  </Step>
</Steps>

## Common authentication errors and solutions

### Error: "Access denied" when generating access token

**Symptoms:**

* HTTP 401 Unauthorized.
* Error message: "AADSTS7000215: Invalid client secret provided".
* Error message: "invalid\_client".

**Causes and solutions:**

<Accordion title="Invalid or expired client secret">
  **Cause:** The client secret has expired or was copied incorrectly.

  **Solution:**

  1. Go to your IdP app registration.
  2. Create a new client secret.
  3. Update your application configuration with the new secret.
  4. Ensure there are no extra spaces or characters when copying.
</Accordion>

<Accordion title="Incorrect client ID">
  **Cause:** The client ID doesn't match the registered application.

  **Solution:**

  1. Verify the client ID in your IdP matches your configuration.
  2. Check for typos or extra characters.
  3. Ensure you're using the Application (client) ID, not the Object ID.
</Accordion>

<Accordion title="Wrong tenant ID">
  **Cause:** Authenticating against the wrong Entra ID tenant.

  **Solution:**

  1. Verify the tenant ID in your token URL.
  2. Ensure the service principal exists in the correct tenant.
  3. Check that the token URL format is correct: `https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token`.
</Accordion>

<Accordion title="Missing API permissions">
  **Cause:** The application doesn't have permission to access the CDF API.

  **Solution:**

  1. Go to your app registration > API permissions.
  2. Add the required CDF API permissions.
  3. Grant admin consent for the permissions.
  4. Wait a few minutes for changes to propagate.
</Accordion>

### Error: "Forbidden" or "Insufficient permissions" when calling CDF API

**Symptoms:**

* HTTP 403 Forbidden.
* Successfully obtained token but cannot access CDF resources.
* Error message: "The principal does not have the required capabilities".

**Causes and solutions:**

<Accordion title="Service account not in any CDF groups">
  **Cause:** The CDF service account exists but isn't a member of any groups.

  **Solution:**

  1. Go to CDF > Manage access > Groups.
  2. Add your service account to appropriate groups.
  3. Verify the groups have the required capabilities.
  4. Wait a few minutes for changes to take effect.
</Accordion>

<Accordion title="Insufficient capabilities in CDF groups">
  **Cause:** The CDF groups don't have the capabilities needed for your operation.

  **Solution:**

  1. Identify which capability is needed (e.g., `timeseries:write`).
  2. Go to the group settings in CDF.
  3. Add the required capability.
  4. Verify the scope (all resources or specific data sets).
</Accordion>

<Accordion title="Scope too restrictive">
  **Cause:** The requested scope filters out the capabilities you need.

  **Solution:**

  1. Check your scope configuration.
  2. Use `user_impersonation` or `.default` scope for full access.
  3. If using specific scopes (like `DATA.VIEW`), ensure they match your needs.
  4. Remember: access is the intersection of scopes AND group capabilities.
</Accordion>

<Accordion title="Service account not linked to IdP application">
  **Cause:** The CDF service account's client ID doesn't match the IdP application.

  **Solution:**

  1. Go to CDF > Manage access > Service accounts.
  2. Verify the client ID matches your IdP application.
  3. If incorrect, delete and recreate the service account with the correct client ID.
</Accordion>

### Error: "Invalid audience" or "Invalid token"

**Symptoms:**

* HTTP 401 Unauthorized.
* Error message: "The audience is invalid".
* Token validation fails.

**Causes and solutions:**

<Accordion title="Wrong audience in token request">
  **Cause:** The audience parameter doesn't match your CDF cluster.

  **Solution:**

  1. Verify your CDF cluster URL (e.g., `https://westeurope-1.cognitedata.com`).
  2. Ensure the audience in your token request matches exactly.
  3. For Entra ID, the audience is typically included in the scope: `https://your-cluster.cognitedata.com/.default`.
</Accordion>

<Accordion title="Wrong CDF base URL">
  **Cause:** Your application is connecting to the wrong CDF cluster.

  **Solution:**

  1. Verify your CDF cluster name.
  2. Update the base URL in your client configuration.
  3. Ensure the base URL matches the audience in your token.
</Accordion>

### Error: "Token expired"

**Symptoms:**

* HTTP 401 Unauthorized.
* Error message: "Token is expired".
* Works initially but fails after some time.

**Causes and solutions:**

<Accordion title="Token not being refreshed">
  **Cause:** The application is using an expired token and not requesting a new one.

  **Solution:**

  1. Most SDKs handle token refresh automatically.
  2. Verify you're using the latest SDK version.
  3. For custom implementations, implement token refresh logic.
  4. Check the `min-ttl` setting in extractor configurations.
</Accordion>

<Accordion title="Long-running processes">
  **Cause:** Process runs longer than token lifetime (typically 1 hour).

  **Solution:**

  1. Implement automatic token refresh.
  2. For extractors, ensure `min-ttl` is set (default: 30 seconds).
  3. Use the SDK's built-in token management.
  4. Monitor token expiration and refresh proactively.
</Accordion>

## Debugging checklist

When troubleshooting authentication issues, check these items in order:

<Steps>
  <Step title="Verify IdP credentials">
    * [ ] Client ID is correct
    * [ ] Client secret is valid and not expired
    * [ ] Tenant ID is correct (for Entra ID)
    * [ ] Token URL is properly formatted
  </Step>

  <Step title="Test token acquisition">
    Use a simple script to test getting a token:

    ```python wrap theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
    import requests

    token_url = "https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
    data = {
        "grant_type": "client_credentials",
        "client_id": "your-client-id",
        "client_secret": "your-client-secret",
        "scope": "https://your-cluster.cognitedata.com/.default"
    }

    response = requests.post(token_url, data=data)
    print(response.status_code)
    print(response.json())
    ```

    If this fails, the issue is with your IdP credentials.
  </Step>

  <Step title="Inspect the token">
    Use CDF's token inspection endpoint:

    ```python wrap  theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
    from cognite.client import CogniteClient

    # After creating client with credentials
    token_info = client.iam.token.inspect()
    print(token_info)
    ```

    Check:

    * [ ] Token is valid
    * [ ] Correct project
    * [ ] Service account or user is identified
    * [ ] Group memberships are listed
  </Step>

  <Step title="Verify CDF configuration">
    * [ ] Service account exists in CDF
    * [ ] Service account client ID matches IdP application
    * [ ] Service account is member of at least one group
    * [ ] Groups have required capabilities
    * [ ] Capabilities have correct scope (all vs specific data sets)
  </Step>

  <Step title="Check scope and audience">
    * [ ] Audience matches CDF cluster URL
    * [ ] Scopes are correctly formatted
    * [ ] Scopes include necessary permissions
    * [ ] Using `user_impersonation` or `.default` for full access
  </Step>
</Steps>

## Best practices

When working with authentication credentials:

* **Store secrets securely** — Never commit client secrets to version control. Use environment variables or secret management services.
* **Use service accounts for automation** — Don't use personal user accounts for automated processes.
* **Rotate secrets regularly** — Set expiration dates on client secrets and rotate them before expiry.
* **Apply the principle of least privilege** — Only grant the minimum capabilities needed for each service account.
* **Monitor token usage** — Use CDF audit logs to track API access and identify issues.
* **Use SDK token management** — Let the SDK handle token refresh automatically rather than implementing custom logic.
* **Test in development first** — Verify authentication works in a development environment before deploying to production.

## Related resources

* [Access management concepts](/cdf/access/concepts/concepts)
* [Access token scopes](/cdf/access/concepts/access_token_scopes)
* [Configure CDF with Microsoft Entra ID](/cdf/access/entra/guides/configure_cdf_azure_oidc)
* [Configure CDF with Amazon Cognito](/cdf/access/aws/guides/configure_cdf_cognito)
* [Python SDK authentication](/dev/sdks/python/python_auth_oidc)
* [Register custom web applications](/cdf/access/entra/guides/register_custom_webapp)

**API reference:**

* [Tokens](/api-reference/concepts/20230101/tokens) — Token inspection endpoint
* [Sessions](/api-reference/concepts/20230101/sessions) — Long-lived access for Transformations, Functions, and more
* [Principals](/api-reference/concepts/20230101/principals) — User accounts and service accounts
* [Groups](/api-reference/concepts/20230101/groups) — Capabilities and group membership
