Scan dependencies for known vulnerabilities and licenses.
Overall
score
61%
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.
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_settingDescription: 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 policydef 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
"""Safety CLI looks for policy files in the following order:
--policy-file path/to/policy.yml./.safety-policy.yml# Default policy file locations
DEFAULT_POLICY_LOCATIONS = [
"./.safety-policy.yml", # Current directory
"./safety-policy.yml", # Alternative name
"./.safety/policy.yml" # Safety config directory
]# .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 foundfrom 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
"""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 sourcesConfiguration 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
"""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 behaviorEnvironment 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")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 configurationfrom 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
"""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
}
}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: 10Platform-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.configPolicy resolution follows inheritance hierarchy:
# 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
"""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
"""# 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# 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.ymlfrom 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)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)
)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-safetydocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10