Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Feature Flags

ASecurity

Implement feature flags for progressive feature rollout using LaunchDarkly,

46,816 stars
0 votes
0 copies
0 views
Added 9/24/2026
ai-agentsjavascriptpythongojavabashsqlreactnodedjangodocker

Works with

cliapi

Security Analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned 9/24/2026

$npx -y skills add sickn33/antigravity-awesome-skills --skill feature-flags --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Feature Flags?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Feature Flags
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/sickn33-feature-flags-9ad093da/badge)](https://www.skillsdirectory.com/skills/sickn33-feature-flags-9ad093da)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: feature-flags
description: Implement feature flags for progressive feature rollout using LaunchDarkly,
  Unleash, or custom solutions.
category: devops
risk: critical
source: https://github.com/BagelHole/DevOps-Security-Agent-Skills
source_repo: BagelHole/DevOps-Security-Agent-Skills
source_type: community
date_added: '2026-09-20'
license: MIT
license_source: https://github.com/BagelHole/DevOps-Security-Agent-Skills/blob/main/LICENSE
compatibility: Requires the relevant platform CLIs (kubectl, helm, terraform, git,
  CI runners) and authorized access to the target environment. Docs-only; helper scripts
  and templates not bundled.
metadata:
  author: devops-skills
  version: '1.0'
---

# Feature Flags

Control feature releases and enable progressive rollout with feature flag systems.

## Prerequisites

- Application code access
- Feature flag service or self-hosted solution
- Basic understanding of deployment patterns

## Feature Flag Types

| Type | Purpose | Example |
|------|---------|---------|
| Release | Control feature visibility | New checkout flow |
| Experiment | A/B testing | Button color test |
| Ops | Runtime configuration | Rate limiting |
| Permission | User access control | Premium features |
| Kill Switch | Emergency disable | Third-party integration |

## LaunchDarkly

### SDK Setup (Node.js)

```javascript
const LaunchDarkly = require('launchdarkly-node-server-sdk');

const client = LaunchDarkly.init(process.env.LAUNCHDARKLY_SDK_KEY);

await client.waitForInitialization();

// Evaluate flag
const user = {
  key: 'user-123',
  email: 'user@example.com',
  custom: {
    plan: 'premium',
    company: 'acme'
  }
};

const showNewFeature = await client.variation('new-checkout', user, false);

if (showNewFeature) {
  // New feature code
} else {
  // Existing code
}
```

### React SDK

```javascript
import { withLDProvider, useFlags, useLDClient } from 'launchdarkly-react-client-sdk';

// Provider setup
export default withLDProvider({
  clientSideID: 'your-client-side-id',
  user: {
    key: 'user-123',
    email: 'user@example.com'
  }
})(App);

// Using flags in component
function FeatureComponent() {
  const { newCheckout, experimentVariant } = useFlags();
  const ldClient = useLDClient();

  // Track events
  const handleClick = () => {
    ldClient.track('checkout-started');
  };

  if (newCheckout) {
    return <NewCheckout onClick={handleClick} />;
  }
  return <OldCheckout onClick={handleClick} />;
}
```

### Targeting Rules

```yaml
# LaunchDarkly targeting configuration
flag: new-checkout
targeting:
  # Individual users
  targets:
    - variation: true
      values: ['user-123', 'user-456']
  
  # Rules
  rules:
    # Beta users
    - variation: true
      clauses:
        - attribute: email
          op: endsWith
          values: ['@company.com']
    
    # Premium plan
    - variation: true
      clauses:
        - attribute: plan
          op: in
          values: ['premium', 'enterprise']
    
    # Percentage rollout
    - variation: true
      rollout:
        variations:
          - variation: true
            weight: 20000  # 20%
          - variation: false
            weight: 80000  # 80%
  
  # Default
  fallthrough:
    variation: false
```

## Unleash

### Server Setup

```yaml
# docker-compose.yml
version: '3.8'

services:
  unleash:
    image: unleashorg/unleash-server:latest
    ports:
      - "4242:4242"
    environment:
      - DATABASE_URL=postgres://postgres:password@db/unleash
      - DATABASE_SSL=false
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=unleash
    volumes:
      - postgres-data:/var/lib/postgresql/data

volumes:
  postgres-data:
```

### SDK Setup (Node.js)

```javascript
const { initialize } = require('unleash-client');

const unleash = initialize({
  url: 'http://localhost:4242/api',
  appName: 'my-app',
  customHeaders: {
    Authorization: 'your-api-token'
  }
});

unleash.on('ready', () => {
  // Check feature
  const isEnabled = unleash.isEnabled('new-checkout');
  
  // With context
  const context = {
    userId: 'user-123',
    properties: {
      plan: 'premium'
    }
  };
  
  const isEnabledForUser = unleash.isEnabled('new-checkout', context);
  
  // Get variant
  const variant = unleash.getVariant('experiment-flag', context);
  console.log(variant.name); // 'control' or 'treatment'
});
```

### Activation Strategies

```yaml
# Standard strategies
strategies:
  - name: default
    # On/off for everyone
    
  - name: userWithId
    parameters:
      userIds: 'user-1,user-2,user-3'
    
  - name: gradualRolloutUserId
    parameters:
      percentage: 25
      groupId: 'new-feature'
    
  - name: gradualRolloutRandom
    parameters:
      percentage: 50
    
  - name: flexibleRollout
    parameters:
      rollout: 30
      stickiness: userId
      groupId: 'checkout-exp'
```

## Custom Implementation

### Database-Backed Flags

```python
# models.py
from django.db import models

class FeatureFlag(models.Model):
    name = models.CharField(max_length=100, unique=True)
    enabled = models.BooleanField(default=False)
    rollout_percentage = models.IntegerField(default=0)
    allowed_users = models.JSONField(default=list)
    rules = models.JSONField(default=dict)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

# service.py
import hashlib

class FeatureFlagService:
    def __init__(self):
        self._cache = {}
    
    def is_enabled(self, flag_name, user_id=None, context=None):
        flag = self._get_flag(flag_name)
        
        if not flag or not flag.enabled:
            return False
        
        # Check user allowlist
        if user_id and user_id in flag.allowed_users:
            return True
        
        # Check rules
        if context and self._evaluate_rules(flag.rules, context):
            return True
        
        # Check percentage rollout
        if flag.rollout_percentage > 0 and user_id:
            return self._is_in_rollout(flag_name, user_id, flag.rollout_percentage)
        
        return flag.rollout_percentage == 100
    
    def _is_in_rollout(self, flag_name, user_id, percentage):
        hash_input = f"{flag_name}:{user_id}"
        hash_value = int(hashlib.md5(hash_input.encode()).hexdigest(), 16)
        return (hash_value % 100) < percentage
    
    def _evaluate_rules(self, rules, context):
        for rule in rules.get('rules', []):
            if self._evaluate_rule(rule, context):
                return True
        return False
```

### Redis-Backed Flags

```python
import redis
import json

class RedisFeatureFlags:
    def __init__(self, redis_url):
        self.redis = redis.from_url(redis_url)
        self.prefix = 'feature_flag:'
    
    def set_flag(self, name, config):
        key = f"{self.prefix}{name}"
        self.redis.set(key, json.dumps(config))
    
    def is_enabled(self, name, user_id=None):
        key = f"{self.prefix}{name}"
        data = self.redis.get(key)
        
        if not data:
            return False
        
        config = json.loads(data)
        
        if not config.get('enabled', False):
            return False
        
        # User allowlist
        if user_id in config.get('users', []):
            return True
        
        # Percentage rollout
        percentage = config.get('percentage', 0)
        if percentage == 100:
            return True
        
        if percentage > 0 and user_id:
            return self._hash_user(name, user_id) < percentage
        
        return False
    
    def _hash_user(self, flag, user_id):
        import hashlib
        hash_input = f"{flag}:{user_id}"
        return int(hashlib.sha256(hash_input.encode()).hexdigest(), 16) % 100
```

## Testing with Feature Flags

### Unit Testing

```javascript
// Jest mocking
jest.mock('launchdarkly-node-server-sdk', () => ({
  init: jest.fn(() => ({
    waitForInitialization: jest.fn().mockResolvedValue(undefined),
    variation: jest.fn()
  }))
}));

describe('Checkout', () => {
  it('shows new checkout when flag enabled', async () => {
    const ldClient = require('launchdarkly-node-server-sdk').init();
    ldClient.variation.mockResolvedValue(true);
    
    const result = await renderCheckout(user);
    expect(result).toContain('NewCheckout');
  });
  
  it('shows old checkout when flag disabled', async () => {
    const ldClient = require('launchdarkly-node-server-sdk').init();
    ldClient.variation.mockResolvedValue(false);
    
    const result = await renderCheckout(user);
    expect(result).toContain('OldCheckout');
  });
});
```

### Integration Testing

```python
# pytest fixtures
import pytest

@pytest.fixture
def feature_flags():
    """Provide controllable feature flags for testing."""
    flags = {}
    
    class TestFlags:
        def set(self, name, value):
            flags[name] = value
        
        def is_enabled(self, name, **kwargs):
            return flags.get(name, False)
    
    return TestFlags()

def test_new_checkout(feature_flags):
    feature_flags.set('new-checkout', True)
    
    response = client.get('/checkout')
    assert 'new-checkout-form' in response.content
```


## Contents

- [Monitoring and Analytics](references/details.md)
- [Common Issues](references/details.md)
- [Best Practices](references/details.md)
- [Related Skills](references/details.md)

## When to Use This Skill

Use this skill when:
- Implementing gradual feature rollouts
- Enabling trunk-based development
- Running A/B tests and experiments
- Managing feature lifecycles
- Implementing kill switches for production

## Limitations

- Guidance executes against real environments: confirm target, blast radius, and rollback plan before applying anything.
- Never deploy to production without explicit approval. Docs-only import: upstream scripts and templates not bundled.

### Example

```bash
git status && git diff --stat
kubectl diff -f manifest.yaml
```

> Adapted from [BagelHole/DevOps-Security-Agent-Skills](https://github.com/BagelHole/DevOps-Security-Agent-Skills) (MIT); frontmatter, When to Use/Limitations, and safety boundaries added for upstream compliance. Docs-only import: helper scripts and templates not bundled.

Attribution

sickn33sickn33
View sourceSee grades on GitHubMore from sickn33 →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Terse caveman voice: answer first, fluff gone, every technical fact kept. Use for /caveman, "caveman mode", "talk like caveman", "be brief", "less tokens". Stays on until "stop caveman" or "normal mode".

1100021 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

698621 votes

Writing Skills

Create and manage Claude Code skills in HASH repository following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns), UserPromptSubmit hook, and the 500-line rule. Includes validation and debugging with SKILL_DEBUG. Examples include rust-error-stack, cargo-dep...

3931 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3421 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Amp, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Grok Build, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

741 votes
View all in ai-agents →