Skip to main content

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:
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

PropertyTypeDescription
namestringInternal identifier (camelCase)
displayNamestringName shown in UI
documentationUrlstringLink to documentation
propertiesINodeProperties[]Credential input fields
authenticateobjectAuthentication configuration
testobjectCredential test request

Basic Authentication Examples

Simple API key authentication:
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',
    },
  };
}

OAuth2 Credentials

OAuth2 credentials require additional configuration:
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:
test: ICredentialTestRequest = {
  request: {
    baseURL: 'https://api.myservice.com',
    url: '/v1/auth/verify',
    method: 'GET',
  },
};

Using Credentials in Nodes

Declaring Credentials

In your node’s description:
description: INodeTypeDescription = {
  // ... other properties
  credentials: [
    {
      name: 'myServiceApi',
      required: true,
    },
    // Multiple credential options
    {
      name: 'myServiceOAuth2Api',
      required: true,
      displayOptions: {
        show: {
          authentication: ['oAuth2'],
        },
      },
    },
  ],
};

Accessing Credentials

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)];
}

Conditional Credential Fields

Show/hide credential fields based on other fields:
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:
// 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

Follow these security guidelines when implementing credentials.
1

Use Password Type

Always use typeOptions: { password: true } for sensitive fields:
{
  displayName: 'API Secret',
  name: 'apiSecret',
  type: 'string',
  typeOptions: { password: true },
  default: '',
}
2

Validate Credentials

Always implement a test request or custom test function to validate credentials.
3

Handle Errors Securely

Don’t expose sensitive information in error messages:
catch (error) {
  return {
    status: 'Error',
    message: 'Authentication failed. Please check your credentials.',
    // Don't include: error.message (may contain sensitive info)
  };
}
4

Use HTTPS

Always use HTTPS for API endpoints in credential tests and authentication.

Common Patterns

Multi-Region Support

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

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

Testing

Learn how to test nodes and credentials

Node Structure

Understand how to use credentials in nodes