Skip to main content

k6/secrets

The k6/secrets module provides a secure way to access sensitive information like API keys, passwords, and tokens in your k6 tests without hardcoding them in your scripts.
Never hardcode secrets directly in your test scripts. Use the secrets module with external secret sources to keep sensitive data secure.

Overview

The secrets module integrates with k6’s secret sources system, allowing you to retrieve secrets from external providers at runtime.

Usage

Basic Example

import secrets from "k6/secrets";

export default async function () {
  // Get a secret from the default secret source
  const apiKey = await secrets.get("API_KEY");
  console.log("Retrieved API key");
  
  // Use the secret in your test
  const response = http.get("https://api.example.com/data", {
    headers: {
      "Authorization": `Bearer ${apiKey}`
    }
  });
}

Running with Secret Sources

To use secrets, you need to specify a secret source when running k6:
k6 run --secret-source=file=secrets.json script.js

API

get()

Retrieves a secret from the default secret source.
key
string
required
The identifier/name of the secret to retrieve
Returns: Promise<string> - A promise that resolves to the secret value
import secrets from "k6/secrets";
import http from "k6/http";

export default async function () {
  const token = await secrets.get("auth_token");
  
  http.post("https://api.example.com/login", null, {
    headers: { "X-Auth-Token": token }
  });
}

source()

Accesses a specific named secret source.
sourceName
string
required
The name of the secret source to use
Returns: Secret source object with get() method
import secrets from "k6/secrets";

export default async function () {
  // Access a specific secret source
  const prodSecrets = secrets.source("production");
  const apiKey = await prodSecrets.get("API_KEY");
  
  const devSecrets = secrets.source("development");
  const devKey = await devSecrets.get("DEV_API_KEY");
}

Secret Sources

k6 supports multiple secret source types:

File Secret Source

Store secrets in a JSON file: secrets.json:
{
  "API_KEY": "your-api-key-here",
  "DATABASE_PASSWORD": "your-password-here",
  "JWT_SECRET": "your-jwt-secret"
}
Usage:
k6 run --secret-source=file=secrets.json script.js

Environment Variable Secret Source

Use environment variables as secrets:
export K6_SECRET_API_KEY="your-api-key"
k6 run --secret-source=env script.js

Multiple Secret Sources

You can use multiple secret sources:
k6 run \
  --secret-source=file=prod-secrets.json \
  --secret-source=file=shared-secrets.json \
  script.js

Real-World Example

From the k6 source examples:
// k6 run --secret-source=file=file.secret secrets.test.js
import secrets from "k6/secrets";

export default async () => {
  // Get secret from a source with the provided identifier
  const my_secret = await secrets.get("cool");
  console.log(my_secret);
  
  // Get another secret
  await secrets.get("else");
  console.log(my_secret);
}

Complete Integration Example

import http from "k6/http";
import secrets from "k6/secrets";
import { check } from "k6";

export default async function () {
  // Retrieve secrets
  const apiKey = await secrets.get("stripe_api_key");
  const webhookSecret = await secrets.get("webhook_secret");
  
  // Use in API calls
  const response = http.post(
    "https://api.stripe.com/v1/customers",
    {
      email: "[email protected]",
      description: "Test customer"
    },
    {
      headers: {
        "Authorization": `Bearer ${apiKey}`,
        "Content-Type": "application/x-www-form-urlencoded"
      }
    }
  );
  
  check(response, {
    "customer created": (r) => r.status === 200
  });
}

Best Practices

Never commit secrets to version control. Add your secret files to .gitignore and use environment-specific configurations.
Use different secrets for different environments. Maintain separate secret files for development, staging, and production.
Secrets are loaded per VU. Each virtual user will make separate calls to retrieve secrets. Consider caching secrets if you need to optimize performance.

Security Considerations

  1. File permissions: Ensure secret files have restricted permissions (e.g., chmod 600 secrets.json)
  2. No logging: Avoid logging secret values to console or files
  3. Environment separation: Use different secrets for each environment
  4. Rotation: Regularly rotate your secrets
  5. Access control: Limit who can access secret files and sources

Error Handling

import secrets from "k6/secrets";

export default async function () {
  try {
    const secret = await secrets.get("my_secret");
    // Use the secret
  } catch (error) {
    console.error("Failed to retrieve secret:", error);
    // Handle the error appropriately
  }
}

Build docs developers (and LLMs) love