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

# Credentials & Authentication

> Implement secure authentication and credential management for n8n nodes

# Credentials & Authentication

Credentials in n8n handle authentication for external services. They're defined separately from nodes and can be shared across multiple node types.

## ICredentialType Interface

All credentials implement the `ICredentialType` interface:

```typescript theme={null}
import type {
  ICredentialType,
  INodeProperties,
  IAuthenticateGeneric,
  ICredentialTestRequest,
} from 'n8n-workflow';

export class MyServiceApi implements ICredentialType {
  name = 'myServiceApi';
  displayName = 'My Service API';
  documentationUrl = 'myservice';
  properties: INodeProperties[] = [
    // Credential fields
  ];
  authenticate?: IAuthenticateGeneric;
  test?: ICredentialTestRequest;
}
```

### Required Properties

| Property           | Type               | Description                     |
| ------------------ | ------------------ | ------------------------------- |
| `name`             | string             | Internal identifier (camelCase) |
| `displayName`      | string             | Name shown in UI                |
| `documentationUrl` | string             | Link to documentation           |
| `properties`       | INodeProperties\[] | Credential input fields         |
| `authenticate`     | object             | Authentication configuration    |
| `test`             | object             | Credential test request         |

## Basic Authentication Examples

<Tabs>
  <Tab title="API Key">
    Simple API key authentication:

    ```typescript theme={null}
    export class MyServiceApi implements ICredentialType {
      name = 'myServiceApi';
      displayName = 'My Service API';
      documentationUrl = 'myservice';

      properties: INodeProperties[] = [
        {
          displayName: 'API Key',
          name: 'apiKey',
          type: 'string',
          typeOptions: { password: true },
          default: '',
          required: true,
        },
      ];

      authenticate: IAuthenticateGeneric = {
        type: 'generic',
        properties: {
          headers: {
            'X-API-Key': '={{$credentials.apiKey}}',
          },
        },
      };

      test: ICredentialTestRequest = {
        request: {
          baseURL: 'https://api.myservice.com',
          url: '/v1/auth/test',
        },
      };
    }
    ```
  </Tab>

  <Tab title="Basic Auth">
    Username and password authentication:

    ```typescript theme={null}
    export class HttpBasicAuth implements ICredentialType {
      name = 'httpBasicAuth';
      displayName = 'Basic Auth';
      documentationUrl = 'httprequest';
      genericAuth = true;

      properties: INodeProperties[] = [
        {
          displayName: 'User',
          name: 'user',
          type: 'string',
          default: '',
          resolvableField: true,
        },
        {
          displayName: 'Password',
          name: 'password',
          type: 'string',
          typeOptions: { password: true },
          default: '',
          resolvableField: true,
        },
      ];
    }
    ```
  </Tab>

  <Tab title="Bearer Token">
    Bearer token authentication:

    ```typescript theme={null}
    export class SlackApi implements ICredentialType {
      name = 'slackApi';
      displayName = 'Slack API';
      documentationUrl = 'slack';

      properties: INodeProperties[] = [
        {
          displayName: 'Access Token',
          name: 'accessToken',
          type: 'string',
          typeOptions: { password: true },
          default: '',
          required: true,
        },
      ];

      authenticate: IAuthenticateGeneric = {
        type: 'generic',
        properties: {
          headers: {
            Authorization: '=Bearer {{$credentials.accessToken}}',
          },
        },
      };

      test: ICredentialTestRequest = {
        request: {
          baseURL: 'https://slack.com',
          url: '/api/users.profile.get',
        },
        rules: [
          {
            type: 'responseSuccessBody',
            properties: {
              key: 'error',
              value: 'invalid_auth',
              message: 'Invalid access token',
            },
          },
        ],
      };
    }
    ```
  </Tab>

  <Tab title="Multiple Fields">
    Multiple credential fields:

    ```typescript theme={null}
    export class MyComplexApi implements ICredentialType {
      name = 'myComplexApi';
      displayName = 'My Complex API';
      documentationUrl = 'myservice';

      properties: INodeProperties[] = [
        {
          displayName: 'API URL',
          name: 'url',
          type: 'string',
          default: 'https://api.myservice.com',
          required: true,
        },
        {
          displayName: 'Client ID',
          name: 'clientId',
          type: 'string',
          default: '',
          required: true,
        },
        {
          displayName: 'Client Secret',
          name: 'clientSecret',
          type: 'string',
          typeOptions: { password: true },
          default: '',
          required: true,
        },
        {
          displayName: 'Environment',
          name: 'environment',
          type: 'options',
          options: [
            {
              name: 'Production',
              value: 'production',
            },
            {
              name: 'Sandbox',
              value: 'sandbox',
            },
          ],
          default: 'production',
        },
      ];

      authenticate: IAuthenticateGeneric = {
        type: 'generic',
        properties: {
          headers: {
            'Client-ID': '={{$credentials.clientId}}',
            'Client-Secret': '={{$credentials.clientSecret}}',
          },
        },
      };
    }
    ```
  </Tab>
</Tabs>

## OAuth2 Credentials

OAuth2 credentials require additional configuration:

```typescript theme={null}
export class MyServiceOAuth2Api implements ICredentialType {
  name = 'myServiceOAuth2Api';
  extends = ['oAuth2Api'];
  displayName = 'My Service OAuth2 API';
  documentationUrl = 'myservice';

  properties: INodeProperties[] = [
    {
      displayName: 'Grant Type',
      name: 'grantType',
      type: 'hidden',
      default: 'authorizationCode',
    },
    {
      displayName: 'Authorization URL',
      name: 'authUrl',
      type: 'hidden',
      default: 'https://auth.myservice.com/oauth/authorize',
    },
    {
      displayName: 'Access Token URL',
      name: 'accessTokenUrl',
      type: 'hidden',
      default: 'https://auth.myservice.com/oauth/token',
    },
    {
      displayName: 'Scope',
      name: 'scope',
      type: 'string',
      default: 'read write',
    },
    {
      displayName: 'Auth URI Query Parameters',
      name: 'authQueryParameters',
      type: 'hidden',
      default: '',
    },
    {
      displayName: 'Authentication',
      name: 'authentication',
      type: 'hidden',
      default: 'body',
    },
  ];
}
```

## Credential Testing

The `test` property defines how to validate credentials:

<CodeGroup>
  ```typescript Simple Test theme={null}
  test: ICredentialTestRequest = {
    request: {
      baseURL: 'https://api.myservice.com',
      url: '/v1/auth/verify',
      method: 'GET',
    },
  };
  ```

  ```typescript Test with Rules theme={null}
  test: ICredentialTestRequest = {
    request: {
      baseURL: 'https://api.myservice.com',
      url: '/v1/auth/verify',
    },
    rules: [
      {
        type: 'responseSuccessBody',
        properties: {
          key: 'status',
          value: 'error',
          message: 'Authentication failed',
        },
      },
      {
        type: 'responseCode',
        properties: {
          value: 401,
          message: 'Invalid credentials',
        },
      },
    ],
  };
  ```

  ```typescript Custom Test Function theme={null}
  // In credentials file
  test: ICredentialTestRequest = {
    request: {
      baseURL: 'https://api.myservice.com',
      url: '/v1/auth/verify',
    },
  };

  // In node file
  methods = {
    credentialTest: {
      async testApiCredentials(
        this: ICredentialTestFunctions,
        credential: ICredentialsDecrypted,
      ): Promise<INodeCredentialTestResult> {
        const credentials = credential.data as ICredentialDataDecryptedObject;

        try {
          const options: IHttpRequestOptions = {
            url: 'https://api.myservice.com/v1/auth/verify',
            headers: {
              'X-API-Key': credentials.apiKey as string,
            },
          };

          const response = await this.helpers.httpRequest(options);

          if (response.status !== 'ok') {
            return {
              status: 'Error',
              message: 'Invalid API key',
            };
          }

          return {
            status: 'OK',
            message: 'Authentication successful',
          };
        } catch (error) {
          return {
            status: 'Error',
            message: error.message,
          };
        }
      },
    },
  };
  ```
</CodeGroup>

## Using Credentials in Nodes

### Declaring Credentials

In your node's description:

```typescript theme={null}
description: INodeTypeDescription = {
  // ... other properties
  credentials: [
    {
      name: 'myServiceApi',
      required: true,
    },
    // Multiple credential options
    {
      name: 'myServiceOAuth2Api',
      required: true,
      displayOptions: {
        show: {
          authentication: ['oAuth2'],
        },
      },
    },
  ],
};
```

### Accessing Credentials

<Tabs>
  <Tab title="In Execute">
    ```typescript theme={null}
    async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
      const credentials = await this.getCredentials('myServiceApi');

      const apiKey = credentials.apiKey as string;
      const baseUrl = credentials.baseUrl as string;

      // Use credentials in request
      const response = await this.helpers.request({
        method: 'GET',
        url: `${baseUrl}/api/users`,
        headers: {
          'X-API-Key': apiKey,
        },
      });

      return [this.helpers.returnJsonArray(response)];
    }
    ```
  </Tab>

  <Tab title="With Authentication Helper">
    ```typescript theme={null}
    async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
      // Automatically applies authentication from credential config
      const response = await this.helpers.requestWithAuthentication.call(
        this,
        'myServiceApi',
        {
          method: 'GET',
          url: 'https://api.myservice.com/users',
        },
      );

      return [this.helpers.returnJsonArray(response)];
    }
    ```
  </Tab>

  <Tab title="In LoadOptions">
    ```typescript theme={null}
    methods = {
      loadOptions: {
        async getProjects(this: ILoadOptionsFunctions) {
          const credentials = await this.getCredentials('myServiceApi');

          const response = await this.helpers.request({
            method: 'GET',
            url: 'https://api.myservice.com/projects',
            headers: {
              'X-API-Key': credentials.apiKey as string,
            },
          });

          return response.map(project => ({
            name: project.name,
            value: project.id,
          }));
        },
      },
    };
    ```
  </Tab>
</Tabs>

## Conditional Credential Fields

Show/hide credential fields based on other fields:

```typescript theme={null}
properties: INodeProperties[] = [
  {
    displayName: 'Authentication',
    name: 'authentication',
    type: 'options',
    options: [
      {
        name: 'API Key',
        value: 'apiKey',
      },
      {
        name: 'OAuth2',
        value: 'oAuth2',
      },
    ],
    default: 'apiKey',
  },
  {
    displayName: 'API Key',
    name: 'apiKey',
    type: 'string',
    typeOptions: { password: true },
    displayOptions: {
      show: {
        authentication: ['apiKey'],
      },
    },
    default: '',
  },
  {
    displayName: 'Client ID',
    name: 'clientId',
    type: 'string',
    displayOptions: {
      show: {
        authentication: ['oAuth2'],
      },
    },
    default: '',
  },
];
```

## Real-World Example: AMQP Credentials

Here's the complete AMQP credential test from the source:

```typescript theme={null}
// In Amqp.node.ts
methods = {
  credentialTest: {
    async amqpConnectionTest(
      this: ICredentialTestFunctions,
      credential: ICredentialsDecrypted,
    ): Promise<INodeCredentialTestResult> {
      const credentials = credential.data as ICredentialDataDecryptedObject;
      const rhea = require('rhea');

      try {
        const connection = rhea.connect({
          hostname: credentials.hostname,
          port: credentials.port,
          username: credentials.username,
          password: credentials.password,
          transport: credentials.transportType,
        });

        // Wait for connection
        await new Promise((resolve, reject) => {
          connection.on('connection_open', () => {
            connection.close();
            resolve(true);
          });

          connection.on('disconnected', (context: any) => {
            reject(context.error || new Error('Connection failed'));
          });
        });

        return {
          status: 'OK',
          message: 'Connection successful!',
        };
      } catch (error) {
        return {
          status: 'Error',
          message: error.message,
        };
      }
    },
  },
};
```

## Security Best Practices

<Warning>
  Follow these security guidelines when implementing credentials.
</Warning>

<Steps>
  <Step title="Use Password Type">
    Always use `typeOptions: { password: true }` for sensitive fields:

    ```typescript theme={null}
    {
      displayName: 'API Secret',
      name: 'apiSecret',
      type: 'string',
      typeOptions: { password: true },
      default: '',
    }
    ```
  </Step>

  <Step title="Validate Credentials">
    Always implement a `test` request or custom test function to validate credentials.
  </Step>

  <Step title="Handle Errors Securely">
    Don't expose sensitive information in error messages:

    ```typescript theme={null}
    catch (error) {
      return {
        status: 'Error',
        message: 'Authentication failed. Please check your credentials.',
        // Don't include: error.message (may contain sensitive info)
      };
    }
    ```
  </Step>

  <Step title="Use HTTPS">
    Always use HTTPS for API endpoints in credential tests and authentication.
  </Step>
</Steps>

## Common Patterns

### Multi-Region Support

```typescript theme={null}
properties: INodeProperties[] = [
  {
    displayName: 'Region',
    name: 'region',
    type: 'options',
    options: [
      {
        name: 'US',
        value: 'us',
      },
      {
        name: 'EU',
        value: 'eu',
      },
      {
        name: 'Asia',
        value: 'asia',
      },
    ],
    default: 'us',
  },
  {
    displayName: 'API Key',
    name: 'apiKey',
    type: 'string',
    typeOptions: { password: true },
    default: '',
  },
];

authenticate: IAuthenticateGeneric = {
  type: 'generic',
  properties: {
    headers: {
      'X-API-Key': '={{$credentials.apiKey}}',
      'X-Region': '={{$credentials.region}}',
    },
  },
};
```

### Custom Domain Support

```typescript theme={null}
properties: INodeProperties[] = [
  {
    displayName: 'Domain',
    name: 'domain',
    type: 'string',
    default: 'https://api.example.com',
    placeholder: 'https://your-domain.example.com',
    description: 'The domain of your instance',
  },
  {
    displayName: 'API Token',
    name: 'apiToken',
    type: 'string',
    typeOptions: { password: true },
    default: '',
  },
];
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Testing" icon="flask" href="/node-development/testing">
    Learn how to test nodes and credentials
  </Card>

  <Card title="Node Structure" icon="diagram-project" href="/node-development/node-structure">
    Understand how to use credentials in nodes
  </Card>
</CardGroup>
