DEV Community

Cover image for Do You Really Know Where Your API Keys End Up? A Security Guide for Fintech Developers
uma victor for Flutterwave Engineering

Posted on

Do You Really Know Where Your API Keys End Up? A Security Guide for Fintech Developers

As fintech developers, our API keys function as master keys to a bank vault. One small mistake can give attackers direct access to process payments, access sensitive data, or worse. However, the truth is that most API key leaks do not originate from sophisticated attacks; instead, they stem from simple oversights in our development workflow.

After reading this guide, you’ll know where your API keys may be exposed and how to effectively protect them. We'll look at some real-world examples, offer practical solutions, and explore how to move beyond only API keys for better security.

How Do API Keys Get Leaked?

How API keys get leaked

When you work with API keys, it’s not hard to make a mistake and leak your keys. There are a number of ways this can happen in your development pipeline. Let’s look at some common places you can mistakenly expose your API keys:

Let's look at a typical scenario. You're building a payment integration:

    const paymentApi = new PaymentAPI({
      apiKey: 'prod_api_test_7653',
      secretKey: 'seck_live_67890'  // mistakenly added API key in your code
    });
Enter fullscreen mode Exit fullscreen mode

If you do this in your codebase, your app will run without a problem locally, but as soon as you push your local changes to GitHub, your API key becomes public for anyone to access. While you can potentially remove it later and rewrite Git history, you have already exposed your keys in that initial push.

What Happens When Your API Key Leaks?

When you make the mistake of leaking your API keys, you immediately become at risk of some really fast bots that constantly scan for leaked API keys and can spot and exploit them within minutes. Even with checks in place like GitHub's secret scanning, which can notify you, it's important to act immediately. These automated bots look for specific patterns that match API keys.

API Key Exposed timeline

Once the bots find your keys, bad actors move in quickly. They'll start testing what they can do with your key, such as processing payments, accessing data, and other capabilities your API allows. You'll eventually notice something's wrong: unusual API calls, unexpected charges, or weird errors. But by then, you're already playing defense. You'll revoke the key, assess the damage, and have some uncomfortable conversations with your team and possibly your customers.

A compromised API key can lead to a serious data breach in your organization, but you can prevent data breaches by securing your API keys properly, which is what you’ll learn in the next section.

API Key Security: A Practical Guide

Let’s look at some practical ways you can secure our API keys. One of the most fundamental ways to protect your API keys is by using environment variables. Environment variables are dynamic named values that can affect how running processes behave on a computer.

Think of them as placeholders outside your code that hold sensitive information. Instead of hardcoding your API keys directly into your application code, you store them in these variables, and your application reads them when it starts. This keeps your sensitive keys out of your source code.

Let’s rewrite our earlier example so it’s more secure using environment variables:

    // Load keys from environment variables
    const paymentApi = new PaymentAPI({
      apiKey: process.env.PAYMENT_API_KEY,
      secretKey: process.env.PAYMENT_SECRET_KEY
    });

    // Add validation
    if (!process.env.PAYMENT_SECRET_KEY) {
      throw new Error('Payment secret key not configured');
    }
Enter fullscreen mode Exit fullscreen mode

API Key Management Best Practices
Using environment variables is an important first step, but you can improve on it by following some security best practices. Think of this as your full security checklist for handling your API keys. We'll cover practices like regular key rotation, centralized secrets management, and continuous monitoring.

Step 1. Use Environment Variables

  • Keep a .env.example file in your repo with dummy values.
  • Add your .env files to your .gitignore file.
  • Validate environment variables on your application startup.

Validate environment variables on your application startup

Here's how to set up environment variables in a Node.js project (you have to install dotenv):

    // Install dotenv
    // npm install dotenv

    // In your app's entry point
    require('dotenv').config();

    // Validate required variables
    const requiredEnvVars = [
      'PAYMENT_API_KEY',
      'PAYMENT_SECRET_KEY'
    ];

    for (const envVar of requiredEnvVars) {
      if (!process.env[envVar]) {
        console.error(`Missing required environment variable: ${envVar}`);
        process.exit(1);
      }
    }
Enter fullscreen mode Exit fullscreen mode

Step 2. Implementing Key Rotation
Key rotation is the practice of regularly replacing your API keys with new ones. This minimizes the window of opportunity for an attacker if a key is compromised. You should regularly rotate your API keys as a proactive security measure.

Note that implementing key rotation depends on whether your API provider supports this functionality through an API or a manual regeneration process.

If supported, consider these practices:

  • Create a key rotation schedule (e.g., every 30 days).
  • Use automated rotation tools when possible.
  • Keep an audit log of key changes.

API key rotation cycle

Here's how to implement key rotation with Node.js:

    class KeyManager {
      constructor() {
        this.currentKey = process.env.CURRENT_API_KEY;
        this.previousKey = process.env.PREVIOUS_API_KEY;
        this.rotationDate = new Date(process.env.KEY_ROTATION_DATE);
      }

      needsRotation() {
        const daysSinceRotation = 
          (Date.now() - this.rotationDate) / (1000 * 60 * 60 * 24);
        return daysSinceRotation > 30;
      }

      async rotatekeys() {
        // Rotate keys with your payment provider
        const newKey = await paymentProvider.createNewKey();

        // Update environment variables
        this.previousKey = this.currentKey;
        this.currentKey = newKey;
        this.rotationDate = new Date();

        // Log the rotation for audit purposes
        console.log(`Key rotated on ${this.rotationDate}`);
      }
    }
Enter fullscreen mode Exit fullscreen mode

Flutterwave allows developers to select an expiration period for the current keys when generating new API keys. This ensures that applications have time to be updated before the old keys stop working, avoiding potential service interruptions.

Step 3. Use a Secrets Manager
Environment variables have some limitations in production environments. Consider using a specialized secrets manager such as AWS Secrets Manager, Google Secret Manager, HashiCorp Vault, or Azure Key Vault.

These solutions offer several advantages over plain environment variables. You get automatic credential rotation, detailed access control for your team members, complete audit logs showing who accessed what and when, and encryption that protects your secrets even if someone breaches your storage. Though configuring a secrets manager requires more up-front work compared to environment variables, the security benefits make it worth using for any serious production environment.

Here's how to use AWS Secrets Manager in Node.js:

    // Install AWS SDK
    const AWS = require('aws-sdk');
    const secretsManager = new AWS.SecretsManager();

    async function getApiKey() {
      const data = await secretsManager.getSecretValue({
        SecretId: 'payment/api-key'
      }).promise();

      const secret = JSON.parse(data.SecretString);
      return secret.apiKey;
    }
Enter fullscreen mode Exit fullscreen mode

Step 4. Monitor Key Usage

  • Set up alerts for unusual API activity.
  • Track which services use which keys.
  • Log all key access attempts.

Even with environment variables, secrets managers, and monitoring, you may still face limitations when your application scales or requires more nuanced permissions. For more complex applications, you’ll need to move from simple key-based authentication towards something more secure, which you will learn in the next section.

Moving Beyond API Keys: OAuth and Token-Based Auth

OAuth is primarily an authorization framework that allows users to grant a third-party application limited access to their data on another service (without sharing their credentials).

While API keys work well for simple integrations, you need a different solution for more complex situations. Utilize OAuth when you need:

  • Fine-grained access control
  • User-specific permissions
  • Temporary access tokens
  • Ability to revoke access without replacing keys

Here's a basic OAuth implementation:

    const express = require('express');
    const app = express();

    app.get('/auth', async (req, res) => {
      const { code } = req.query;

      // Exchange auth code for access token
      const response = await fetch('https://api.payment.com/oauth/token', {
        method: 'POST',
        body: JSON.stringify({
          code,
          client_id: process.env.CLIENT_ID,
          client_secret: process.env.CLIENT_SECRET,
          grant_type: 'authorization_code'
        })
      });

      const { access_token, refresh_token } = await response.json();

      // Store tokens securely
      // Use access_token for API calls instead of static key
    });
Enter fullscreen mode Exit fullscreen mode

OAuth vs. API Keys: A Comparison

Feature API keys OAuth
Implementation complexity Low Medium-High
Security Basic Advanced
Access control All-or-nothing Granular
Token lifespan Long-lived Short-lived
Revocation Must change key Can revoke individual tokens
User context None Available

Understanding different authentication methods is important, but let's also look at how specific platforms like Flutterwave add extra layers of security to protect your API keys.

How Flutterwave Keeps API Secure

Flutterwave takes API security seriously and has incorporated numerous safety features into its system to prevent costly mistakes for developers. The initial safety feature of Flutterwave is the presence of separate Test and Live modes. These different modes allow you to fully test your integration without risking real money.

flutterwave dashboard

The API keys are also distinct, meaning test keys always contain the _TEST prefix (like FLWPUBK_TEST-32193bba8dab84e3d9c4525c85ea7a12-X).

Flutterwave provides three types of keys, and each serves a different function:

  • Secret key: The most important key that has the capability to do anything with your account (it should never be made public).
  • Public key: Generated for use in client-side code, such as the Inline payment form.
  • Encryption key: This is only used with direct card charge endpoints.

To help make production environments more secure, Flutterwave also has a process that lets you rotate your keys, which requires email verification through a 7-digit authentication code. You can select how long your old keys will be functional when you generate new API keys. This gives you time to update your application before the old keys can no longer be used.

Flutterwave includes several other security measures, like letting you revoke all old keys immediately and generate new ones if you’re worried that your key has been compromised. Flutterwave provides developers with built-in fraud analysis tools that help detect suspicious activity, providing an additional layer of defense in case of an API key exploit. You can utilise IP whitelisting, allowing API calls only from specified IP addresses, significantly reducing the attack surface and ensuring API key access is limited to authorized users.

Take Action Today

You can begin taking the following actions today to ensure your API keys are secure:

  1. Remove any exposed API keys and rotate compromised API keys immediately.
  2. Set up proper environment variables or a secrets manager.
  3. Create a key rotation schedule.

For a quick audit, try these Git commands to find potentially exposed keys in your code repositories:

    # Search for common API key patterns
    git grep -i "api[_-]key"
    git grep -i "secret[_-]key"
    git grep -i "bearer"

    # Search Git history
    git log -p | grep -i "api[_-]key"
Enter fullscreen mode Exit fullscreen mode

Prevention Tools

There are many solutions to avoid API key leaks:

Wrapping Up

Understanding where you expose your API keys, keeping them secure, rotating them frequently, and looking into enhancements for authentication, such as OAuth, can greatly minimize your chances of being hacked.

Keep in mind that every API key is a potential target for attack. Take the time now to implement proper security practices by rotating your keys regularly, using secrets management tools, and monitoring for suspicious activities. These simple steps prevent you from serious issues, including financial losses.

Sign up for Flutterwave today to access our secure API environment with built-in key rotation, webhooks, and IP whitelisting features.

Top comments (3)

Collapse
 
warwait profile image
Parker Waiters

Super helpful advice—security starts with the basics!

Collapse
 
theoephraim profile image
Theo Ephraim

check out dmno.dev
It helps keep secrets out of plaintext env files, as well as prevents leaked secrets, both at build and runtime!

Collapse
 
carrotcake123 profile image
carrotcake

Thnks for this informative blog.