CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-safety

Scan dependencies for known vulnerabilities and licenses.

Overall
score

61%

Overview
Eval results
Files

configuration.mddocs/

Configuration and Policies

Safety CLI provides comprehensive configuration management through policy files, environment variables, and command-line options. The policy system allows centralized security configuration and consistent vulnerability handling across teams and environments.

Policy File System

Policy File Structure { .api }

Import Statements:

from safety.scan.main import load_policy_file, download_policy, resolve_policy  
from safety.util import SafetyPolicyFile, initialize_config_dirs
from safety_schemas.models import (
    ConfigModel, PolicyFileModel, PolicySource, Stage
)
from safety.constants import get_config_setting

PolicyFileModel { .api }

Description: Represents a Safety policy file with metadata and configuration.

from safety_schemas.models import PolicyFileModel, PolicySource

class PolicyFileModel:
    """Safety policy file representation with source tracking."""
    
    id: str                                     # Policy identifier (UUID for cloud policies)
    source: PolicySource                        # Policy source (local or cloud)
    location: Optional[Path]                    # Local file path (for local policies)
    config: ConfigModel                         # Parsed policy configuration

class PolicySource(Enum):
    """Policy file source types."""
    LOCAL = "local"                            # Local filesystem policy
    CLOUD = "cloud"                            # Platform-hosted policy

Policy File Loading { .api }

def load_policy_file(path: Path) -> Optional[PolicyFileModel]:
    """
    Load and validate a local policy file.
    
    Args:
        path (Path): Path to .safety-policy.yml file
        
    Returns:
        Optional[PolicyFileModel]: Parsed policy or None if invalid
        
    Raises:
        SafetyError: If policy file is malformed or unsupported version
    """

def download_policy(
    session: SafetyAuthSession,                 # Authenticated session
    project_id: str,                           # Project identifier
    stage: Stage,                              # Target stage
    branch: Optional[str]                      # Git branch name
) -> Optional[PolicyFileModel]:
    """
    Download policy from Safety platform.
    
    Args:
        session: Authenticated Safety session
        project_id: Project UUID from Safety platform
        stage: Environment stage for policy
        branch: Git branch for branch-specific policies
        
    Returns:
        Optional[PolicyFileModel]: Downloaded policy or None
        
    Raises:
        SafetyError: If download fails or policy is invalid
    """

def resolve_policy(
    policy_file_path: Optional[Path],           # Local policy file path
    session: SafetyAuthSession,                # Authenticated session
    project_config: Optional[Dict] = None       # Project configuration
) -> Optional[PolicyFileModel]:
    """
    Resolve policy with precedence: platform > local > default.
    
    Args:
        policy_file_path: Path to local policy file
        session: Authenticated session for platform policies
        project_config: Project configuration with ID and stage
        
    Returns:
        Optional[PolicyFileModel]: Resolved policy configuration
    """

Default Policy File Location { .api }

Safety CLI looks for policy files in the following order:

  1. Command-line specified: --policy-file path/to/policy.yml
  2. Current directory: ./.safety-policy.yml
  3. Platform policy: Downloaded based on project configuration
  4. Default configuration: Built-in safe defaults
# Default policy file locations
DEFAULT_POLICY_LOCATIONS = [
    "./.safety-policy.yml",                    # Current directory
    "./safety-policy.yml",                     # Alternative name
    "./.safety/policy.yml"                     # Safety config directory
]

Policy File Format

Complete Policy File Example { .api }

# .safety-policy.yml
# Safety Security and License Configuration

# Project association (for Safety platform integration)
project:
  id: "12345678-1234-1234-1234-123456789abc"  # Project UUID from Safety platform

organization:
  id: "org-12345"                             # Organization identifier
  name: "My Company"                          # Organization display name

# Security vulnerability configuration
security:
  # Ignore unpinned requirements (like "requests" or "django>=2.2")
  ignore-unpinned-requirements: true
  
  # CVSS severity threshold (0-10 scale)
  # 9 = Critical only, 7 = Critical & High, 4 = Critical, High & Medium
  ignore-cvss-severity-below: 7
  
  # Whether to ignore vulnerabilities with unknown CVSS scores
  ignore-cvss-unknown-severity: false
  
  # Continue execution even when vulnerabilities are found
  continue-on-vulnerability-error: false
  
  # Specific vulnerabilities to ignore (with optional expiration)
  ignore-vulnerabilities:
    25853:                                    # Vulnerability ID
      reason: "We don't use the vulnerable function"
      expires: "2024-12-31"                  # ISO date when ignore expires
    
    67890:
      reason: "False positive - not exploitable in our use case"
      expires: "2024-06-01"

# License compliance configuration  
license:
  # Ignore license issues for unpinned requirements
  ignore-unpinned-requirements: true
  
  # Allowed licenses (whitelist approach)
  allowed-licenses:
    - "MIT"
    - "BSD-3-Clause"
    - "Apache-2.0"
    - "ISC"
    
  # Prohibited licenses (blacklist approach)
  prohibited-licenses:
    - "GPL-3.0"
    - "AGPL-3.0"
    
  # Continue execution despite license issues
  continue-on-license-error: false

# Alerting configuration (for GitHub/GitLab integration)
alert:
  security:
    github-issue:
      # CVSS severity threshold for alerts
      ignore-cvss-severity-below: 6
      ignore-cvss-unknown-severity: false
      
      # Add severity labels to issues
      label-severity: true
      
      # Custom labels for security issues
      labels:
        - "security"
        - "vulnerability"
      
      # Auto-assign users to security issues
      assignees:
        - "security-team"
        - "dev-lead"
      
      # Prefix for issue titles
      issue-prefix: "[Security Alert] "

# Scan configuration
scan:
  # Maximum depth for dependency tree scanning
  max-depth: 10
  
  # File patterns to exclude from scanning
  exclude:
    - "test_*"
    - "*/tests/*"
    - ".venv/*"
    - "node_modules/*"
  
  # Auto-remediation settings
  auto-remediation:
    enabled: true
    max-fixes: 5                              # Maximum automatic fixes to apply
    
  # Output preferences
  output:
    detailed: true                            # Include detailed vulnerability information
    show-source: true                         # Show where vulnerabilities were found

Policy Validation { .api }

from safety.cli import validate

def validate_policy_file(name: str, version: str, path: Path) -> bool:
    """
    Validate policy file syntax and configuration.
    
    CLI Usage:
        safety validate policy_name 1.0 --path ./policies/
    
    Args:
        name (str): Policy name identifier
        version (str): Policy version string
        path (Path): Directory containing policy file
        
    Returns:
        bool: True if policy is valid
        
    Raises:
        ValidationError: If policy contains errors
        SafetyError: If policy file cannot be parsed
    """

Configuration Models

ConfigModel { .api }

Description: Central configuration model that represents parsed policy settings.

from safety_schemas.models import ConfigModel

class ConfigModel:
    """Central configuration for Safety CLI operations."""
    
    # Core settings
    telemetry_enabled: bool = True             # Enable usage telemetry
    
    # Vulnerability filtering
    ignore_vulnerabilities: List[str] = []     # Vulnerability IDs to ignore
    ignore_unpinned_requirements: bool = False # Skip unpinned dependencies
    ignore_cvss_severity_below: Optional[float] = None  # CVSS threshold
    ignore_cvss_unknown_severity: bool = False # Ignore unknown severity
    continue_on_vulnerability_error: bool = False  # Continue on vulnerabilities
    
    # License filtering  
    allowed_licenses: List[str] = []           # Permitted licenses
    prohibited_licenses: List[str] = []        # Forbidden licenses
    continue_on_license_error: bool = False    # Continue on license issues
    
    # Auto-remediation
    auto_remediation_enabled: bool = False     # Enable automatic fixes
    auto_remediation_limit: Optional[int] = None  # Maximum fixes to apply
    
    # Scan configuration
    max_depth: int = 10                        # Dependency tree depth
    exclude_patterns: List[str] = []           # File exclusion patterns
    
    # Output preferences
    detailed_output: bool = False              # Include detailed information
    show_source: bool = True                   # Show vulnerability sources

Configuration Methods:

@classmethod
def parse_policy_file(cls, raw_report: Path) -> "ConfigModel":
    """
    Parse YAML policy file into configuration model.
    
    Args:
        raw_report (Path): Path to policy YAML file
        
    Returns:
        ConfigModel: Parsed configuration
        
    Raises:
        ValidationError: If YAML is invalid
        SafetyError: If policy version is unsupported
    """

def save_policy_file(self, path: Path) -> None:
    """
    Save configuration as YAML policy file.
    
    Args:
        path (Path): Output file path
        
    Raises:
        IOError: If file cannot be written
    """

@classmethod
def from_v30(cls, obj) -> "ConfigModel":
    """
    Create configuration from v3.0 policy format.
    
    Args:
        obj: v3.0 format policy object
        
    Returns:
        ConfigModel: Converted configuration
    """

Environment Configuration

Environment Variables { .api }

Safety CLI behavior can be configured through environment variables:

# Authentication and API
SAFETY_API_KEY                    # Default API key for authentication
SAFETY_API_BASE_URL              # Override API base URL
SAFETY_PLATFORM_URL             # Safety platform URL

# Database and caching  
SAFETY_DB_DIR                    # Custom database directory
SAFETY_DB_MIRROR                 # Vulnerability database mirror URL
SAFETY_CACHE_DIR                 # Custom cache directory

# Proxy configuration
SAFETY_PROXY_PROTOCOL           # Proxy protocol (http/https)
SAFETY_PROXY_HOST               # Proxy hostname
SAFETY_PROXY_PORT               # Proxy port number
SAFETY_PROXY_TIMEOUT            # Proxy timeout in seconds
SAFETY_PROXY_REQUIRED           # Require proxy (true/false)

# Behavior and output
SAFETY_OS_DESCRIPTION           # Override OS detection
SAFETY_PURE_YAML               # Use pure YAML parser
SAFETY_COLOR                    # Enable/disable color output
SAFETY_NO_EMOJI                 # Disable emoji in output

# CI/CD and automation
SAFETY_AUDIT_AND_MONITOR       # Enable audit mode
SAFETY_CONTINUE_ON_ERROR        # Continue on vulnerabilities
SAFETY_EXIT_CODE               # Override exit code behavior

Environment Variable Access:

from safety.constants import get_config_setting

# Get configuration setting with fallback
api_key = get_config_setting("SAFETY_API_KEY", default=None)
proxy_host = get_config_setting("SAFETY_PROXY_HOST", default="")
cache_dir = get_config_setting("SAFETY_CACHE_DIR", default="~/.cache/safety")

Configuration Directories { .api }

from safety.util import initialize_config_dirs

def initialize_config_dirs() -> None:
    """
    Initialize Safety configuration directories.
    
    Creates necessary directories for:
    - User configuration (~/.config/safety/)
    - System configuration (/etc/safety/)
    - Cache directory (~/.cache/safety/)
    - Authentication tokens
    """

Default Configuration Locations:

# Linux/macOS
~/.config/safety/               # User configuration
~/.cache/safety/                # User cache
/etc/safety/                    # System configuration

# Windows
%APPDATA%\safety\               # User configuration
%LOCALAPPDATA%\safety\          # User cache
%PROGRAMDATA%\safety\           # System configuration

Policy Generation

Policy File Generation { .api }

from safety.cli import generate_policy_file, generate_installation_policy

def generate_policy_file(name: str, path: Path) -> None:
    """
    Generate default policy file template.
    
    CLI Usage:
        safety generate policy my-project --path ./config/
    
    Args:
        name (str): Project name for policy
        path (Path): Directory to create policy file
        
    Creates:
        - .safety-policy.yml with default configuration
        - Comments explaining each setting
        - Example ignore configurations
    """

def generate_installation_policy(
    name: str, 
    path: Path, 
    minimum_cvss_severity: str = "critical"
) -> None:
    """
    Generate installation policy for package management.
    
    CLI Usage:
        safety generate installation_policy my-project --minimum-cvss-severity high
    
    Args:
        name (str): Project name
        path (Path): Output directory
        minimum_cvss_severity (str): Minimum severity level
        
    Creates:
        - Installation policy with security constraints
        - Package source restrictions
        - Vulnerability tolerance settings
    """

Policy Templates { .api }

Safety provides policy templates for common use cases:

# Basic security policy
BASIC_SECURITY_POLICY = {
    "security": {
        "ignore-cvss-severity-below": 7,
        "ignore-cvss-unknown-severity": False,
        "continue-on-vulnerability-error": False
    }
}

# Strict security policy
STRICT_SECURITY_POLICY = {
    "security": {
        "ignore-cvss-severity-below": 0,      # No tolerance for any severity
        "ignore-cvss-unknown-severity": False,
        "continue-on-vulnerability-error": False,
        "ignore-unpinned-requirements": False
    }
}

# CI/CD friendly policy
CICD_POLICY = {
    "security": {
        "ignore-cvss-severity-below": 7,
        "continue-on-vulnerability-error": True, # Don't fail builds
        "ignore-unpinned-requirements": True     # Allow flexible deps
    }
}

Advanced Configuration

Multi-Stage Policies { .api }

Safety supports different policies for different environments:

# production.safety-policy.yml
security:
  ignore-cvss-severity-below: 0               # Strict in production
  continue-on-vulnerability-error: false
  auto-remediation:
    enabled: false                            # No auto-fixes in prod

# development.safety-policy.yml  
security:
  ignore-cvss-severity-below: 4               # More tolerant in dev
  continue-on-vulnerability-error: true
  auto-remediation:
    enabled: true
    max-fixes: 10

Organization-Wide Policies { .api }

Platform-hosted policies provide centralized management:

# Download organization policy
from safety.scan.main import download_policy

policy = download_policy(
    session=authenticated_session,
    project_id="my-project-uuid",
    stage=Stage.PRODUCTION,
    branch="main"
)

if policy:
    print(f"Using organization policy: {policy.id}")
    config = policy.config

Policy Inheritance { .api }

Policy resolution follows inheritance hierarchy:

  1. Platform Organization Policy (highest priority)
  2. Platform Project Policy
  3. Local Policy File (--policy-file or .safety-policy.yml)
  4. Default Configuration (built-in defaults)
# Policy resolution with inheritance
def resolve_effective_policy(
    local_policy_path: Optional[Path],
    session: SafetyAuthSession,
    project_config: Dict
) -> ConfigModel:
    """
    Resolve effective policy with inheritance.
    
    Returns merged configuration considering:
    - Organization defaults
    - Project overrides  
    - Local customizations
    - Command-line options
    """

Configuration Validation

Policy File Validation { .api }

from safety.util import SafetyPolicyFile

class SafetyPolicyFile(click.ParamType):
    """Click parameter type for policy file validation."""
    
    name = "policy_file"
    
    def convert(self, value, param, ctx) -> Optional[Path]:
        """
        Validate and convert policy file parameter.
        
        Args:
            value: Policy file path string
            param: Click parameter context
            ctx: Click context
            
        Returns:
            Optional[Path]: Validated policy file path
            
        Raises:
            click.BadParameter: If policy file is invalid
        """

Configuration Debugging { .api }

# Debug configuration resolution
import logging

logging.getLogger("safety.scan.main").setLevel(logging.DEBUG)

# Enable debug output for policy loading
safety scan --debug  # Shows policy resolution process

Usage Examples

Basic Policy Setup

# Generate default policy file
safety generate policy my-project

# Validate policy file  
safety validate my-project 1.0 --path .

# Use custom policy file
safety scan --policy-file ./config/security-policy.yml

Programmatic Configuration

from safety_schemas.models import ConfigModel
from pathlib import Path

# Create custom configuration
config = ConfigModel(
    ignore_cvss_severity_below=7,
    continue_on_vulnerability_error=False,
    auto_remediation_enabled=True,
    auto_remediation_limit=5
)

# Save as policy file
config.save_policy_file(Path(".safety-policy.yml"))

# Load and modify existing policy
policy_path = Path(".safety-policy.yml")
if policy_path.exists():
    config = ConfigModel.parse_policy_file(policy_path)
    config.ignore_cvss_severity_below = 4  # Make more permissive
    config.save_policy_file(policy_path)

Environment-Based Configuration

import os
from safety.constants import get_config_setting

# Environment-specific settings
if os.getenv("CI"):
    # CI/CD environment
    os.environ["SAFETY_CONTINUE_ON_ERROR"] = "true"
    os.environ["SAFETY_IGNORE_CVSS_SEVERITY_BELOW"] = "7"
else:
    # Development environment  
    os.environ["SAFETY_AUTO_REMEDIATION_ENABLED"] = "true"
    os.environ["SAFETY_DETAILED_OUTPUT"] = "true"

# Apply configuration
config = ConfigModel(
    continue_on_vulnerability_error=get_config_setting("SAFETY_CONTINUE_ON_ERROR", False),
    ignore_cvss_severity_below=float(get_config_setting("SAFETY_IGNORE_CVSS_SEVERITY_BELOW", 0)),
    detailed_output=get_config_setting("SAFETY_DETAILED_OUTPUT", False)
)

Organization Policy Management

from safety.auth.cli_utils import build_client_session
from safety.scan.main import download_policy
from safety_schemas.models import Stage

# Authenticate and download organization policy
session = build_client_session()

# Download production policy
prod_policy = download_policy(
    session=session,
    project_id="project-uuid",
    stage=Stage.PRODUCTION,
    branch="main"
)

# Download development policy
dev_policy = download_policy(
    session=session, 
    project_id="project-uuid",
    stage=Stage.DEVELOPMENT,
    branch="develop"
)

# Compare policies
if prod_policy and dev_policy:
    prod_config = prod_policy.config
    dev_config = dev_policy.config
    
    print(f"Production CVSS threshold: {prod_config.ignore_cvss_severity_below}")
    print(f"Development CVSS threshold: {dev_config.ignore_cvss_severity_below}")

This comprehensive configuration and policy documentation covers all aspects of Safety CLI's configuration system, enabling organizations to implement consistent security policies across their development lifecycle and deployment environments.

Install with Tessl CLI

npx tessl i tessl/pypi-safety

docs

authentication.md

cli-commands.md

configuration.md

errors.md

formatters.md

index.md

models.md

programmatic.md

scanning.md

tile.json