home / skills / jeremylongshore / claude-code-plugins-plus-skills / perplexity-policy-guardrails

This skill enforces Perplexity policy and guardrails by applying ESLint rules, pre-commit hooks, and CI checks to improve code quality.

npx playbooks add skill jeremylongshore/claude-code-plugins-plus-skills --skill perplexity-policy-guardrails

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
6.5 KB
---
name: perplexity-policy-guardrails
description: |
  Implement Perplexity lint rules, policy enforcement, and automated guardrails.
  Use when setting up code quality rules for Perplexity integrations, implementing
  pre-commit hooks, or configuring CI policy checks for Perplexity best practices.
  Trigger with phrases like "perplexity policy", "perplexity lint",
  "perplexity guardrails", "perplexity best practices check", "perplexity eslint".
allowed-tools: Read, Write, Edit, Bash(npx:*)
version: 1.0.0
license: MIT
author: Jeremy Longshore <[email protected]>
---

# Perplexity Policy & Guardrails

## Overview
Automated policy enforcement and guardrails for Perplexity integrations.

## Prerequisites
- ESLint configured in project
- Pre-commit hooks infrastructure
- CI/CD pipeline with policy checks
- TypeScript for type enforcement

## ESLint Rules

### Custom Perplexity Plugin
```javascript
// eslint-plugin-perplexity/rules/no-hardcoded-keys.js
module.exports = {
  meta: {
    type: 'problem',
    docs: {
      description: 'Disallow hardcoded Perplexity API keys',
    },
    fixable: 'code',
  },
  create(context) {
    return {
      Literal(node) {
        if (typeof node.value === 'string') {
          if (node.value.match(/^sk_(live|test)_[a-zA-Z0-9]{24,}/)) {
            context.report({
              node,
              message: 'Hardcoded Perplexity API key detected',
            });
          }
        }
      },
    };
  },
};
```

### ESLint Configuration
```javascript
// .eslintrc.js
module.exports = {
  plugins: ['perplexity'],
  rules: {
    'perplexity/no-hardcoded-keys': 'error',
    'perplexity/require-error-handling': 'warn',
    'perplexity/use-typed-client': 'warn',
  },
};
```

## Pre-Commit Hooks

```yaml
# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: perplexity-secrets-check
        name: Check for Perplexity secrets
        entry: bash -c 'git diff --cached --name-only | xargs grep -l "sk_live_" && exit 1 || exit 0'
        language: system
        pass_filenames: false

      - id: perplexity-config-validate
        name: Validate Perplexity configuration
        entry: node scripts/validate-perplexity-config.js
        language: node
        files: '\.perplexity\.json$'
```

## TypeScript Strict Patterns

```typescript
// Enforce typed configuration
interface PerplexityStrictConfig {
  apiKey: string;  // Required
  environment: 'development' | 'staging' | 'production';  // Enum
  timeout: number;  // Required number, not optional
  retries: number;
}

// Disallow any in Perplexity code
// @ts-expect-error - Using any is forbidden
const client = new Client({ apiKey: any });

// Prefer this
const client = new PerplexityClient(config satisfies PerplexityStrictConfig);
```

## Architecture Decision Records

### ADR Template
```markdown
# ADR-001: Perplexity Client Initialization

## Status
Accepted

## Context
We need to decide how to initialize the Perplexity client across our application.

## Decision
We will use the singleton pattern with lazy initialization.

## Consequences
- Pro: Single client instance, connection reuse
- Pro: Easy to mock in tests
- Con: Global state requires careful lifecycle management

## Enforcement
- ESLint rule: perplexity/use-singleton-client
- CI check: grep for "new PerplexityClient(" outside allowed files
```

## Policy-as-Code (OPA)

```rego
# perplexity-policy.rego
package perplexity

# Deny production API keys in non-production environments
deny[msg] {
  input.environment != "production"
  startswith(input.apiKey, "sk_live_")
  msg := "Production API keys not allowed in non-production environment"
}

# Require minimum timeout
deny[msg] {
  input.timeout < 10000
  msg := sprintf("Timeout too low: %d < 10000ms minimum", [input.timeout])
}

# Require retry configuration
deny[msg] {
  not input.retries
  msg := "Retry configuration is required"
}
```

## CI Policy Checks

```yaml
# .github/workflows/perplexity-policy.yml
name: Perplexity Policy Check

on: [push, pull_request]

jobs:
  policy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Check for hardcoded secrets
        run: |
          if grep -rE "sk_(live|test)_[a-zA-Z0-9]{24,}" --include="*.ts" --include="*.js" .; then
            echo "ERROR: Hardcoded Perplexity keys found"
            exit 1
          fi

      - name: Validate configuration schema
        run: |
          npx ajv validate -s perplexity-config.schema.json -d config/perplexity/*.json

      - name: Run ESLint Perplexity rules
        run: npx eslint --plugin perplexity --rule 'perplexity/no-hardcoded-keys: error' src/
```

## Runtime Guardrails

```typescript
// Prevent dangerous operations in production
const BLOCKED_IN_PROD = ['deleteAll', 'resetData', 'migrateDown'];

function guardPerplexityOperation(operation: string): void {
  const isProd = process.env.NODE_ENV === 'production';

  if (isProd && BLOCKED_IN_PROD.includes(operation)) {
    throw new Error(`Operation '${operation}' blocked in production`);
  }
}

// Rate limit protection
function guardRateLimits(requestsInWindow: number): void {
  const limit = parseInt(process.env.PERPLEXITY_RATE_LIMIT || '100');

  if (requestsInWindow > limit * 0.9) {
    console.warn('Approaching Perplexity rate limit');
  }

  if (requestsInWindow >= limit) {
    throw new Error('Perplexity rate limit exceeded - request blocked');
  }
}
```

## Instructions

### Step 1: Create ESLint Rules
Implement custom lint rules for Perplexity patterns.

### Step 2: Configure Pre-Commit Hooks
Set up hooks to catch issues before commit.

### Step 3: Add CI Policy Checks
Implement policy-as-code in CI pipeline.

### Step 4: Enable Runtime Guardrails
Add production safeguards for dangerous operations.

## Output
- ESLint plugin with Perplexity rules
- Pre-commit hooks blocking secrets
- CI policy checks passing
- Runtime guardrails active

## Error Handling
| Issue | Cause | Solution |
|-------|-------|----------|
| ESLint rule not firing | Wrong config | Check plugin registration |
| Pre-commit skipped | --no-verify | Enforce in CI |
| Policy false positive | Regex too broad | Narrow pattern match |
| Guardrail triggered | Actual issue | Fix or whitelist |

## Examples

### Quick ESLint Check
```bash
npx eslint --plugin perplexity --rule 'perplexity/no-hardcoded-keys: error' src/
```

## Resources
- [ESLint Plugin Development](https://eslint.org/docs/latest/extend/plugins)
- [Pre-commit Framework](https://pre-commit.com/)
- [Open Policy Agent](https://www.openpolicyagent.org/)

## Next Steps
For architecture blueprints, see `perplexity-architecture-variants`.

Overview

This skill implements Perplexity-specific lint rules, policy-as-code checks, and automated guardrails to enforce safe integrations. It combines ESLint custom rules, pre-commit hooks, CI policy checks, TypeScript strict patterns, and runtime protections to reduce risk and maintain consistent best practices. Use it to prevent secrets leakage, enforce configuration schemas, and block dangerous operations in production.

How this skill works

The skill provides an ESLint plugin with rules that detect hardcoded API keys, require error handling, and enforce typed clients. Pre-commit hooks scan staged files for secrets and validate Perplexity configuration files. CI workflows run regex-based secret scans, JSON schema validation, ESLint checks, and OPA policy evaluation to catch policy violations before merge. Runtime guardrails block destructive operations and enforce rate limits based on environment variables.

When to use it

  • Adding Perplexity integrations to a codebase that must prevent secret leakage
  • Enforcing configuration schema and TypeScript typing for Perplexity clients
  • Blocking dangerous operations in production (deleteAll, migrateDown, etc.)
  • Implementing automated checks in pre-commit hooks and CI pipelines
  • Applying policy-as-code (OPA) rules to deployment configuration and CI

Best practices

  • Enable the custom eslint-plugin-perplexity and set no-hardcoded-keys to error
  • Use strict TypeScript interfaces for Perplexity configuration and avoid any
  • Add pre-commit hooks to catch secrets and validate .perplexity.json files locally
  • Integrate OPA policies into CI for environment-specific checks (timeouts, retries)
  • Enforce runtime guardrails for destructive operations and rate-limit thresholds

Example use cases

  • Prevent committing live Perplexity API keys by failing pre-commit and CI scans
  • Validate Perplexity config objects with TypeScript and AJV schema checks in CI
  • Reject pull requests where timeout or retry policy violates OPA rules
  • Block a production-deleting operation at runtime if NODE_ENV=production
  • Warn and then block requests when approaching or exceeding Perplexity rate limits

FAQ

What prereqs are required?

ESLint configured, pre-commit framework enabled, CI pipeline access, and TypeScript for strict typing.

How are hardcoded keys detected?

Via an ESLint rule that matches Perplexity key patterns and grep-based checks in pre-commit/CI.

Can OPA policies block merges?

Yes — CI runs OPA policy checks and fails the job when rules deny input, preventing merges.