Skip to main content

Authentication Overview

Authentication in Activepieces pieces is handled by the PieceAuth module from @activepieces/pieces-framework. It provides type-safe authentication methods that integrate seamlessly with the platform.

Authentication Types

Activepieces supports four authentication methods:

OAuth2

Industry-standard OAuth 2.0 protocol

Secret Text

API keys and tokens

Custom Auth

Multiple custom fields

Basic Auth

Username and password

OAuth2 Authentication

OAuth2 is the most common authentication method for modern APIs. It allows users to grant access without sharing credentials.

Basic OAuth2 Setup

import { PieceAuth } from '@activepieces/pieces-framework';

export const slackAuth = PieceAuth.OAuth2({
  displayName: 'Connection',
  description: 'Connect your Slack workspace',
  authUrl: 'https://slack.com/oauth/v2/authorize',
  tokenUrl: 'https://slack.com/api/oauth.v2.access',
  required: true,
  scope: ['chat:write', 'channels:read', 'users:read'],
});

OAuth2 Configuration

authUrl
string
required
The OAuth provider’s authorization URL where users grant permissions
tokenUrl
string
required
The endpoint to exchange authorization code for access token
scope
string[]
required
Array of permission scopes to request from the OAuth provider
required
boolean
default:"true"
Whether authentication is required for all actions/triggers
pkce
boolean
Enable PKCE (Proof Key for Code Exchange) for enhanced security
authorizationMethod
OAuth2AuthorizationMethod
How to send the access token:
  • HEADER (default): In Authorization header
  • BODY: In request body
grantType
OAuth2GrantType
OAuth2 grant type:
  • AUTHORIZATION_CODE (default)
  • CLIENT_CREDENTIALS

OAuth2 with Additional Props

Some OAuth providers require additional parameters during authentication:
export const githubAuth = PieceAuth.OAuth2({
  displayName: 'Connection',
  authUrl: 'https://github.com/login/oauth/authorize',
  tokenUrl: 'https://github.com/login/oauth/access_token',
  required: true,
  scope: ['repo', 'user'],
  // Additional properties shown to users
  props: {
    baseUrl: Property.ShortText({
      displayName: 'Base URL',
      description: 'GitHub instance URL (for Enterprise)',
      required: false,
      defaultValue: 'https://api.github.com',
    }),
  },
});

Using OAuth2 in Actions

import { createAction, Property } from '@activepieces/pieces-framework';
import { slackAuth } from '../auth';

export const sendMessage = createAction({
  auth: slackAuth,
  name: 'send_message',
  displayName: 'Send Message',
  description: 'Send a message to a Slack channel',
  props: {
    channel: Property.ShortText({
      displayName: 'Channel',
      required: true,
    }),
    text: Property.LongText({
      displayName: 'Message',
      required: true,
    }),
  },
  async run(context) {
    // Access token is available in context.auth
    const token = context.auth.access_token;
    
    // Additional OAuth data
    const teamId = context.auth.data.team_id;
    
    // Make API calls with the token
    const response = await fetch('https://slack.com/api/chat.postMessage', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        channel: context.propsValue.channel,
        text: context.propsValue.text,
      }),
    });
    
    return response.json();
  },
});

Secret Text (API Key)

The simplest authentication method for APIs that use API keys or tokens.

Basic Setup

import { PieceAuth } from '@activepieces/pieces-framework';

export const openaiAuth = PieceAuth.SecretText({
  displayName: 'API Key',
  description: 'Enter your OpenAI API key',
  required: true,
});

With Validation

export const apiKeyAuth = PieceAuth.SecretText({
  displayName: 'API Key',
  description: 'Your service API key',
  required: true,
  validate: async ({ auth }) => {
    try {
      // Test the API key
      const response = await fetch('https://api.example.com/validate', {
        headers: {
          'Authorization': `Bearer ${auth}`,
        },
      });
      
      if (response.ok) {
        return {
          valid: true,
        };
      }
      
      return {
        valid: false,
        error: 'Invalid API key',
      };
    } catch (error) {
      return {
        valid: false,
        error: 'Failed to validate API key',
      };
    }
  },
});

Using Secret Text in Actions

export const createCompletion = createAction({
  auth: openaiAuth,
  name: 'create_completion',
  displayName: 'Create Completion',
  props: {
    prompt: Property.LongText({
      displayName: 'Prompt',
      required: true,
    }),
  },
  async run(context) {
    // Access API key directly from context.auth
    const apiKey = context.auth;
    
    const response = await fetch('https://api.openai.com/v1/completions', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        model: 'gpt-3.5-turbo',
        prompt: context.propsValue.prompt,
      }),
    });
    
    return response.json();
  },
});

Custom Authentication

Custom auth allows you to define multiple fields for complex authentication requirements.

Basic Setup

import { PieceAuth, Property } from '@activepieces/pieces-framework';

export const customAuth = PieceAuth.CustomAuth({
  displayName: 'Connection',
  description: 'Enter your credentials',
  props: {
    apiKey: Property.ShortText({
      displayName: 'API Key',
      required: true,
    }),
    apiSecret: PieceAuth.SecretText({
      displayName: 'API Secret',
      required: true,
    }),
    environment: Property.StaticDropdown({
      displayName: 'Environment',
      required: true,
      options: {
        options: [
          { label: 'Production', value: 'production' },
          { label: 'Sandbox', value: 'sandbox' },
        ],
      },
    }),
  },
  required: true,
});

Real-World Example: AWS Credentials

export const awsAuth = PieceAuth.CustomAuth({
  displayName: 'AWS Credentials',
  description: 'Configure AWS credentials',
  props: {
    accessKeyId: Property.ShortText({
      displayName: 'Access Key ID',
      description: 'AWS Access Key ID',
      required: true,
    }),
    secretAccessKey: PieceAuth.SecretText({
      displayName: 'Secret Access Key',
      description: 'AWS Secret Access Key',
      required: true,
    }),
    region: Property.StaticDropdown({
      displayName: 'Region',
      description: 'AWS Region',
      required: true,
      options: {
        options: [
          { label: 'US East (N. Virginia)', value: 'us-east-1' },
          { label: 'US West (Oregon)', value: 'us-west-2' },
          { label: 'EU (Ireland)', value: 'eu-west-1' },
          // ... more regions
        ],
      },
    }),
  },
  required: true,
});

Using Custom Auth in Actions

export const uploadToS3 = createAction({
  auth: awsAuth,
  name: 'upload_to_s3',
  displayName: 'Upload to S3',
  props: {
    bucket: Property.ShortText({
      displayName: 'Bucket',
      required: true,
    }),
    file: Property.File({
      displayName: 'File',
      required: true,
    }),
  },
  async run(context) {
    // Access all auth fields
    const { accessKeyId, secretAccessKey, region } = context.auth;
    
    // Use AWS SDK with credentials
    const s3Client = new S3Client({
      region: region,
      credentials: {
        accessKeyId: accessKeyId,
        secretAccessKey: secretAccessKey,
      },
    });
    
    // Upload file
    const command = new PutObjectCommand({
      Bucket: context.propsValue.bucket,
      Key: context.propsValue.file.filename,
      Body: context.propsValue.file.data,
    });
    
    return await s3Client.send(command);
  },
});

Basic Authentication

Traditional username and password authentication.
export const basicAuth = PieceAuth.BasicAuth({
  displayName: 'Credentials',
  description: 'Enter your username and password',
  required: true,
});

Using Basic Auth

export const fetchData = createAction({
  auth: basicAuth,
  name: 'fetch_data',
  displayName: 'Fetch Data',
  props: {},
  async run(context) {
    // Access username and password
    const { username, password } = context.auth;
    
    // Create Basic Auth header
    const credentials = Buffer.from(`${username}:${password}`).toString('base64');
    
    const response = await fetch('https://api.example.com/data', {
      headers: {
        'Authorization': `Basic ${credentials}`,
      },
    });
    
    return response.json();
  },
});

Auth Type Comparison

Best for:
  • Modern cloud services
  • Services with user-level permissions
  • When you need refresh tokens
Pros:
  • Most secure
  • No credential sharing
  • Granular permissions
  • Token refresh support
Cons:
  • More complex setup
  • Requires OAuth app registration
  • Users must authorize

Best Practices

Implement validation logic to test credentials during setup:
validate: async ({ auth }) => {
  try {
    // Test the credentials
    const response = await testConnection(auth);
    return { valid: true };
  } catch (error) {
    return {
      valid: false,
      error: 'Invalid credentials',
    };
  }
}
For OAuth2, request only the permissions you need:
// Good: Minimal scopes
scope: ['read:user', 'write:repo']

// Bad: Too broad
scope: ['admin', 'delete_everything']
Implement proper error handling for expired tokens:
try {
  const response = await makeApiCall(token);
} catch (error) {
  if (error.status === 401) {
    // Token expired, show helpful error
    throw new Error('Token expired. Please reconnect.');
  }
  throw error;
}
Help users understand what credentials they need:
PieceAuth.SecretText({
  displayName: 'API Key',
  description: 'Find your API key at https://example.com/settings/api',
  required: true,
})

Next Steps

Create Actions

Use authentication in your actions

Properties Guide

Learn about property types for auth fields