Skip to content
Skillpedia
Security35k · #5824

implementing-api-key-security-controls

Helps your agent create secure API keys. It prevents them from being stored insecurely and monitors for leaks. It's useful for protecting access to services.

What it does

This tool helps create and manage secure access keys for your systems. It ensures keys are hard to guess, not stored insecurely, and can be easily disabled or replaced.

When to use it

  • ✓When building a new system that needs secure server-to-server access.
  • ✓When you need to replace old access keys with new ones without service interruption.
  • ✓If you suspect an access key might have been exposed.

Example of what to ask your AI

“Generate a secure API key for my backend application, with read-only permissions and a 90-day expiration.”

Want more? Open the sections below.

How to use

The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.

Skill link

https://github.com/mukul975/Anthropic-Cybersecurity-Skills/blob/main/skills/implementing-api-key-security-controls/SKILL.md

Ready-to-paste message

Use this skill to help me: https://github.com/mukul975/Anthropic-Cybersecurity-Skills/blob/main/skills/implementing-api-key-security-controls/SKILL.md Read the SKILL.md file at that link and follow its instructions for my task.
How it works

The tool generates keys with high randomness and stores them encrypted. It also allows setting usage restrictions and monitoring if keys appear in insecure locations.

Installation

Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.

In the terminal (Claude Code, Codex, Cursor), in your project folder:

npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill implementing-api-key-security-controls

Or download just the file:

curl -L https://raw.githubusercontent.com/mukul975/Anthropic-Cybersecurity-Skills/main/skills/implementing-api-key-security-controls/SKILL.md -o SKILL.md
Technical content (original SKILL.md)

Original text by the author, straight from GitHub.

Implementing API Key Security Controls

When to Use

  • Designing secure API key generation with sufficient entropy and identifiable prefixes for leak detection
  • Implementing server-side API key hashing (never storing keys in plaintext) with SHA-256 or bcrypt
  • Building key rotation workflows that allow zero-downtime key replacement for API consumers
  • Configuring per-key scoping to limit each API key to specific endpoints, IP ranges, and rate limits
  • Setting up automated monitoring for API key leakage in GitHub repos, logs, and client-side code

Do not use API keys as the sole authentication mechanism for user-facing applications. API keys are best suited for server-to-server communication and developer access.

Prerequisites

  • Secure random number generator (os.urandom, secrets module) for key generation
  • Database with proper encryption at rest for storing hashed API keys
  • Redis or similar store for key-to-metadata caching and rate limiting
  • Secret scanning tools (GitHub secret scanning, truffleHog, gitleaks)
  • Monitoring and alerting infrastructure for key usage anomalies

Workflow

Step 1: Secure API Key Generation

import secrets
import hashlib
import hmac
import time
import json
from datetime import datetime, timedelta

class APIKeyManager:
    """Manages secure API key lifecycle: generation, storage, validation, rotation."""

    # Key format: prefix_base64random (e.g., sk_live_a1b2c3d4e5f6...)
    # Prefix identifies the key type and environment for leak detection
    KEY_PREFIXES = {
        "live_secret": "sk_live_",
        "test_secret": "sk_test_",
        "live_public": "pk_live_",
        "test_public": "pk_test_",
    }

    def __init__(self, db_connection, redis_connection):
        self.db = db_connection
        self.redis = redis_connection

    def generate_key(self, key_type="live_secret", owner_id=None, scopes=None,
                     rate_limit=None, ip_allowlist=None, expires_days=365):
        """Generate a new API key with metadata."""
        prefix = self.KEY_PREFIXES.get(key_type, "sk_live_")

        # Generate 32 bytes (256 bits) of randomness
        random_bytes = secrets.token_bytes(32)
        key_body = secrets.token_urlsafe(32)  # Base64url-encoded

        # Full API key that the client receives (shown only once)
        full_key = f"{prefix}{key_body}"

        # Hash the key for storage (never store the raw key)
        key_hash = hashlib.sha256(full_key.encode()).hexdigest()

        # Create a short key ID for reference (first 8 chars)
        key_id = f"{prefix}{key_body[:8]}..."

        # Store the hashed key with metadata
        key_metadata = {
            "key_hash": key_hash,
            "key_id": key_id,
            "key_type": key_type,
            "owner_id": owner_id,
            "scopes": scopes or ["read"],
            "rate_limit": rate_limit or {"requests": 1000, "window": 3600},
            "ip_allowlist": ip_allowlist or [],
            "created_at": datetime.utcnow().isoformat(),
            "expires_at": (datetime.utcnow() + timedelta(days=expires_days)).isoformat(),
            "last_used": None,
            "is_active": True,
            "usage_count": 0,
        }

        # Store in database
        self.db.execute(
            "INSERT INTO api_keys (key_hash, key_id, metadata) VALUES (?, ?, ?)",
            (key_hash, key_id, json.dumps(key_metadata))
        )

        # Cache in Redis for fast validation
        self.redis.setex(
            f"apikey:{key_hash}",
            86400,  # 24-hour cache TTL
            json.dumps(key_metadata)
        )

        return {
            "api_key": full_key,       # Show to user ONCE
            "key_id": key_id,          # For reference/management
            "scopes": key_metadata["scopes"],
            "expires_at": key_metadata["expires_at"],
        }

    def validate_key(self, api_key):
        """Validate an API key and return its metadata."""
        key_hash = hashlib.sha256(api_key.encode()).hexdigest()

        # Check Redis cache first
        cached = self.redis.get(f"apikey:{key_hash}")
        if cached:
            metadata = json.loads(cached)
        else:
            # Fall back to database
            row = self.db.execute(
                "SELECT metadata FROM api_keys WHERE key_hash = ?",
                (key_hash,)
            ).fetchone()
            if not row:
                return None, "invalid_key"
            metadata = json.loads(row[0])

…
FAQ

What is 'entropy'?

It's a measure of a key's randomness or unpredictability. The higher the entropy, the harder it is for someone to guess the key.

Why shouldn't I store keys in plaintext?

Storing keys in plaintext is very risky. If someone gains access to your database, they could see all the keys and misuse them.

What is 'key rotation'?

It's the process of replacing an old access key with a new one. This is done to maintain security, especially if the old key is compromised or nearing expiration.

Details

Original description by the author

Implements secure API key generation with sufficient entropy, server-side hashing (SHA-256/bcrypt) instead of plaintext storage, per-key scoping to endpoints/IPs/rate limits, zero-downtime rotation, and automated leak monitoring across GitHub repos, logs, and client-side code. Use when designing API key formats, building key rotation or revocation workflows, or protecting server-to-server API cred

repo: mukul975/Anthropic-Cybersecurity-Skills

Popularity

GitHub stars
35k
Ranking position
#5824
License
Apache-2.0
Updated
8/31/2026

Is this skill useful?

0

Sign in to vote.

Comments

  • …

More skills from this repository

Similar skills