npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@keyflow/credentials

v0.2.4

Published

A TypeScript package for securely accessing API keys and OAuth tokens stored in your Keyflow account.

Readme

@keyflow/credentials

A TypeScript package for securely accessing API keys and OAuth tokens stored in your Keyflow account.

Installation

npm install @keyflow/credentials

Quick Start

import { credentials } from '@keyflow/credentials';

// Get OpenAI credentials
const openaiCreds = await credentials.openai();

// Use the access token for API calls
const response = await fetch('https://api.openai.com/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${openaiCreds.access_token}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'gpt-3.5-turbo',
    messages: [{ role: 'user', content: 'Hello!' }],
  }),
});

Setup

Environment Variable

Set your Keyflow API key as an environment variable:

export KEYFLOW_API_KEY="your-keyflow-api-key-here"

Programmatic API Key

Alternatively, provide the API key directly:

const creds = await credentials.openai(undefined, {
  apiKey: 'your-keyflow-api-key'
});

API Reference

Basic Usage

import { credentials } from '@keyflow/credentials';

// Access any supported provider
const creds = await credentials.provider_name();

Method Signature

credentials.provider_name(name?, options?)

Parameters:

  • name (optional): String identifier for named credentials
  • options (optional): Configuration object with apiKey property

Returns: Promise resolving to:

{
  name: string;           // The credential name/identifier
  access_token: string;   // The main access token
  refresh_token?: string; // Optional refresh token (for OAuth providers)
}

Supported Providers

The package supports 35+ integrations:

  • AI/ML: openai, gemini, replicate, eleven_labs, groq, cohere, deepseek, perplexity, humanonic
  • Google Services: drive, gmail, google_docs, google_sheets, google_calendar, gcp
  • Communication: slack, discord, twilio, vapi
  • Productivity: notion, asana, airtable, typeform
  • Development: github, postgresql, supabase, turbopuffer
  • Social: twitter, linkedin, linkedin_cookies
  • Search/Data: serp, exa, apify
  • Other: microsoft, apify

Usage Examples

Basic Credential Access

import { credentials } from '@keyflow/credentials';

async function generateText(prompt: string) {
  try {
    const openaiCreds = await credentials.openai();

    const response = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${openaiCreds.access_token}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        model: 'gpt-3.5-turbo',
        messages: [{ role: 'user', content: prompt }],
      }),
    });

    const result = await response.json();
    return result.choices[0].message.content;
  } catch (error) {
    console.error('Text generation failed:', error);
    throw error;
  }
}

Named Credentials

Use named credentials when you have multiple accounts for the same service:

// Access different Slack workspaces
const workSlack = await credentials.slack('work-workspace');
const personalSlack = await credentials.slack('personal-workspace');

// Access different databases
const prodDB = await credentials.postgresql('production');
const devDB = await credentials.postgresql('development');

Multiple Provider Integration

import { credentials } from '@keyflow/credentials';

async function syncDataAcrossServices() {
  try {
    // Get credentials for multiple services
    const [notionCreds, airtableCreds, slackCreds] = await Promise.all([
      credentials.notion(),
      credentials.airtable(),
      credentials.slack(),
    ]);

    // Fetch data from Notion
    const notionResponse = await fetch('https://api.notion.com/v1/databases', {
      headers: {
        'Authorization': `Bearer ${notionCreds.access_token}`,
        'Notion-Version': '2022-06-28',
      },
    });

    // Process and sync to Airtable
    const notionData = await notionResponse.json();
    const airtableResponse = await fetch('https://api.airtable.com/v0/your-base/table', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${airtableCreds.access_token}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ records: processedData }),
    });

    // Send Slack notification
    await fetch('https://slack.com/api/chat.postMessage', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${slackCreds.access_token}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        channel: '#updates',
        text: 'Data sync completed successfully!',
      }),
    });

    return { success: true };
  } catch (error) {
    console.error('Data sync failed:', error);
    throw error;
  }
}

Google Sheets Integration

async function readSpreadsheet(spreadsheetId: string) {
  const googleCreds = await credentials.google_sheets();

  const response = await fetch(
    `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/Sheet1`,
    {
      headers: {
        'Authorization': `Bearer ${googleCreds.access_token}`,
      },
    }
  );

  if (!response.ok) {
    throw new Error(`Google Sheets API error: ${response.statusText}`);
  }

  const data = await response.json();
  return data.values;
}

Security Best Practices

✅ Do

// Use HTTPS for all API calls
fetch('https://api.service.com/endpoint', {
  headers: { Authorization: `Bearer ${creds.access_token}` }
});

// Log safely without exposing tokens
console.log('Successfully retrieved credentials for OpenAI');

// Handle errors appropriately
try {
  const creds = await credentials.openai();
} catch (error) {
  throw new Error('OpenAI integration required but not configured');
}

❌ Don't

// Never log actual credentials
console.log(`Token: ${creds.access_token}`); // SECURITY RISK

// Don't expose credentials in responses
return { token: creds.access_token, data: result }; // SECURITY RISK

// Don't store credentials in global variables
let savedToken = creds.access_token; // BAD PRACTICE

// Don't use HTTP for sensitive API calls
fetch('http://api.service.com/endpoint'); // INSECURE

Configuration

Setting Up Credentials in Keyflow

  1. Log into your Keyflow account
  2. Navigate to account settings
  3. Configure your integrations (OAuth apps, API keys, etc.)
  4. Optionally create named credentials for multiple accounts per service
  5. Use your Keyflow API key to access these credentials programmatically

Environment Variables

# Required: Your Keyflow API key
KEYFLOW_API_KEY="your-keyflow-api-key-here"

# Optional: Set to development for local testing
NODE_ENV="development"  # Uses localhost:8000 instead of production API

TypeScript Support

The package includes full TypeScript definitions:

import { credentials, CredentialProvider } from '@keyflow/credentials';

// Type-safe provider names
const provider: CredentialProvider = 'openai';
const creds = await credentials[provider]();

// Typed credential response
interface CredentialResponse {
  name: string;
  access_token: string;
  refresh_token?: string;
}

Troubleshooting

Common Issues

Missing API Key

Error: API key for Keyflow is missing

Solution: Set the KEYFLOW_API_KEY environment variable or provide it via options.

Credentials Not Found

Error: Couldn't get openai credential: 404 Not Found

Solution: Configure the OpenAI integration in your Keyflow account settings.

Unauthorized Access

Error: Couldn't get service credential: 401 Unauthorized

Solution: Check that your Keyflow API key is valid and has the necessary permissions.

Network Issues

Error: Failed to fetch

Solution: Ensure you have internet connectivity and the Keyflow API is accessible.

Debug Mode

Set NODE_ENV=development to use the local development API endpoint:

process.env.NODE_ENV = 'development';
const creds = await credentials.openai(); // Uses localhost:8000

Contributing

This package is part of the Keyflow SDK monorepo. Please refer to the main repository for contribution guidelines.

Support

For support, please contact the Keyflow team or refer to the main Keyflow documentation.