API keys act as digital gatekeepers, authenticating interactions between online services by confirming that requests come from authorized sources. They're critical for enabling secure communication between applications, services, and APIs. Unfortunately, attackers understand their value all too well and often target these keys.
A single leaked key can grant attackers extensive access to your sensitive business information. The consequences of such a security lapse can range from significant financial losses to severe reputational damage. Given these high stakes, developers must prioritize robust API key security practices to prevent unauthorized access to their applications.
In brief:
Understanding common API key security mistakes helps developers avoid costly security breaches.
Developers have multiple reliable approaches for securely storing API keys. Strapi recommends the following methods to safeguard your credentials effectively.
Environment variables are dynamic values stored outside the application's code. Developers commonly use them to handle API keys securely. They prevent exposing sensitive information directly in source files, allowing the application to access keys at runtime while keeping them hidden from unauthorized users and separate from version-controlled codebases.
To use environment variables for storing API keys:
1setx OPENAI_API_KEY "<yourkey>"
1echo "export OPENAI_API_KEY='<yourkey>'" >> ~/.zshrc
2source ~/.zshrc
For Node.js applications, you can use the dotenv
package:
1require('dotenv').config();
2const apiKey = process.env.API_KEY;
For Python applications, use the python-dotenv
package:
1from dotenv import load_dotenv
2import os
3
4load_dotenv()
5api_key = os.getenv("API_KEY")
Remember to add your .env
file to .gitignore
to prevent accidental commits of sensitive information.
You can use configuration management tools (e.g., Ansible) to store, deploy, and manage API keys securely. These tools encrypt secrets, limit access to authorized users, and track any changes. This reduces security risks and keeps keys safe and consistent across all environments.
These tools connect to your application through SDKs or APIs so you can retrieve secrets when needed.
You can use a backend proxy to keep API keys away from client-side code.
Here's how it works:
This approach ensures clients never see your API keys.
Here's a simplified example using Node.js and Express:
1const express = require('express');
2const axios = require('axios');
3const app = express();
4
5const API_KEY = process.env.API_KEY;
6const EXTERNAL_API_URL = 'https://api.example.com';
7
8app.get('/api/data', async (req, res) => {
9 try {
10 const response = await axios.get(`${EXTERNAL_API_URL}/data`, {
11 headers: { 'Authorization': `Bearer ${API_KEY}` }
12 });
13 res.json(response.data);
14 } catch (error) {
15 res.status(500).json({ error: 'An error occurred' });
16 }
17});
18
19app.listen(3000, () => console.log('Proxy server running on port 3000'));
You can use a Secrets Manager or a Dedicated Vault – specialized tools, such as HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault – explicitly designed for the secure storage, management, and retrieval of sensitive information, like API keys.
To use AWS Secrets Manager:
1import boto3
2
3def get_secret():
4 client = boto3.client('secretsmanager')
5 response = client.get_secret_value(SecretId='your-secret-name')
6 return response['SecretString']
7
8api_key = get_secret()
This approach provides centralized management across your infrastructure. You can use powerful features like automatic rotation and granular access controls to strength your API key security.
Choose the storage method that best matches your project's size, security requirements, and organizational setup. Each of these approaches is significantly better than hardcoding keys in your source code and is crucial in learning how to store API keys securely.
A comprehensive API key security strategy requires rotation, permission controls, and vigilant monitoring.
Think of key rotation like changing your passwords—it limits how long a stolen key remains useful.
Assign API keys the minimal permissions required for their specific tasks to mitigate risks.
Effective monitoring and detailed logs allow rapid detection and response to unauthorized key use.
For example, tools like Strapi audit logs provide detailed information about actions within the application, including content type modifications, user activities, and changes to roles and permissions. Each log entry includes details such as the action type, date and time, user involved, and can also show the user's IP address, request body, and response body for thorough tracking and analysis.
The latest Strapi 5 release has significantly improved security features and API handling capabilities. As detailed in the Strapi v5 documentation, the new version includes an Audit Log for tracking API actions, best practices for API security, robust vulnerability management, strong encryption and data management protocols, and secure development practices.\
Strapi provides you with API tokens that allow users to authenticate REST and GraphQL API queries.
Strapi allows the use of environment variables for sensitive information:
.env
file in your Strapi project's root directory:1API_KEY=your_api_key_here
2DATABASE_PASSWORD=your_database_password
.env
to your .gitignore
file to prevent accidental commits:1echo ".env" >> .gitignore
config/server.js
or config/database.js
), reference these environment variables using the env
function:1module.exports = ({ env }) => ({
2 host: env('HOST', '0.0.0.0'),
3 port: env.int('PORT', 1337),
4 app: {
5 keys: env.array('APP_KEYS'),
6 },
7 apiToken: {
8 salt: env('API_TOKEN_SALT'),
9 },
10});
When connecting to external APIs from Strapi, create a dedicated service:
1// services/externalApi.js
2const axios = require('axios');
3
4module.exports = {
5 async makeApiCall() {
6 const apiKey = process.env.EXTERNAL_API_KEY;
7 const response = await axios.get('https://api.example.com/data', {
8 headers: {
9 'Authorization': `Bearer ${apiKey}`
10 }
11 });
12 return response.data;
13 }
14};
1// controllers/customController.js
2module.exports = {
3 async getData(ctx) {
4 const { externalApi } = strapi.services;
5 const data = await externalApi.makeApiCall();
6 ctx.send(data);
7 }
8};
When working with Strapi, especially in cloud environments like managing API keys in Strapi Cloud, it's important to manage API keys securely.
Securing API keys requires consistent attention throughout their lifecycle. Implementing secure storage, limited permissions, regular rotation, and active monitoring helps build a reliable security posture.
Begin with practical steps, such as removing API keys from source code and implementing scheduled key rotations. Gradually enhance security by incorporating automated management and detailed monitoring solutions.
Ready to implement enterprise-grade API key security? Try Strapi v5 with its enhanced API token management, granular permissions system, and robust audit logging. Secure your headless CMS and protect your digital assets with Strapi's comprehensive security features.