fortly-cli
v1.0.5
Published
Fortly CLI — Automated web security scanner with AI-powered vulnerability detection
Maintainers
Readme
Why Fortly?
Most security scanners are either too complex to set up, too slow, or produce noisy results full of false positives. Fortly is different:
- One command to scan — no config files, no setup wizards, no Docker required
- AI-powered analysis — reduces false positives by validating findings with intelligent heuristics
- Built for developers — integrates into your workflow with CI/CD support, SARIF output, and exit codes
- Fast — concurrent crawling with configurable threads, depth, and timeout
- Two modes — run scans locally or offload to the Fortly cloud engine
Installation
# Install globally
npm install -g fortly-cli
# Or run without installing
npx fortly-cli scan https://example.comRequires Node.js >= 18
Quick Start
# Scan a target
fortly scan https://myapp.com
# Deep scan with more threads
fortly scan https://myapp.com --depth 5 --threads 10
# Generate an HTML report
fortly scan https://myapp.com --format html --output ./reports
# Cloud mode (faster, more comprehensive)
fortly config set api-key ft_sk_your_key_here
fortly scan https://myapp.com --cloud
# CI/CD — fail the build if score is below 70
fortly scan https://staging.myapp.com --ci --fail-threshold 70Commands
fortly scan <target>
Run a security scan against a target URL.
fortly scan https://myapp.com [options]| Option | Default | Description |
|---|---|---|
| -d, --depth <n> | 3 | Maximum crawl depth |
| -t, --timeout <ms> | 10000 | Request timeout in milliseconds |
| --threads <n> | 5 | Number of concurrent requests |
| -f, --format <type> | terminal | Output format: terminal, json, html, both, sarif |
| -o, --output <dir> | ./fortly-reports | Directory for saved reports |
| --fail-threshold <n> | — | Minimum score (0-100). Exit code 1 if below |
| --cloud | false | Use the Fortly cloud engine |
| --api-key <key> | — | API key for cloud mode (overrides stored config) |
| --no-ai | — | Disable AI-powered detection |
| --ci | false | CI mode: minimal JSON output + GitHub Actions annotations |
| -v, --verbose | false | Verbose logging |
Examples:
# Quick scan with terminal output
fortly scan https://myapp.com
# Full scan with HTML + JSON reports saved to disk
fortly scan https://myapp.com --depth 5 --threads 10 --format both --output ./security-reports
# SARIF output for GitHub Code Scanning
fortly scan https://myapp.com --format sarif --output ./results
# Strict CI scan — fail if score is below 80
fortly scan https://staging.myapp.com --ci --fail-threshold 80 --cloud --api-key ft_sk_abc123fortly report <path>
View a previously saved scan report in the terminal.
fortly report ./fortly-reports/scan-2026-03-17.json
fortly report ./fortly-reports/scan-2026-03-17.json --format json| Option | Default | Description |
|---|---|---|
| -f, --format <type> | terminal | Output format: terminal or json |
fortly config <action> [key] [value]
Manage persistent CLI configuration.
# Save your API key
fortly config set api-key ft_sk_your_key_here
# Check stored values
fortly config get api-key
fortly config list
# Reset everything
fortly config reset| Action | Description |
|---|---|
| set <key> <value> | Store a configuration value |
| get <key> | Retrieve a configuration value |
| list | Show all stored values (sensitive keys are masked) |
| reset | Clear all configuration |
Cloud Mode
Cloud mode offloads scanning to the Fortly cloud engine for faster, deeper analysis without consuming local resources.
Getting your API Key
- Sign up at fortly.io
- Navigate to Settings > API Keys
- Click Generate New Key
- Copy the key (starts with
ft_sk_)
Using Cloud Mode
# Option 1: Store the key permanently
fortly config set api-key ft_sk_your_key_here
fortly scan https://myapp.com --cloud
# Option 2: Pass the key inline
fortly scan https://myapp.com --cloud --api-key ft_sk_your_key_here
# Option 3: Use an environment variable
export FT_API_KEY=ft_sk_your_key_here
fortly scan https://myapp.com --cloudAPI key resolution order:
--api-keyflag (highest priority)FT_API_KEYenvironment variable- Stored config (
fortly config set api-key)
Cloud API
The cloud engine exposes a REST API at https://api.fortly.io:
| Endpoint | Method | Description |
|---|---|---|
| /api/v2/scans | POST | Create a new scan |
| /api/v2/scans/{scanId} | GET | Get scan status and results |
The CLI handles polling automatically (every 5 seconds, up to 5 minutes).
CI/CD Integration
Fortly is designed to run in any CI/CD pipeline. Use --ci for machine-readable output and --fail-threshold to enforce security gates.
GitHub Actions
name: Security Scan
on: [push, pull_request]
jobs:
fortly:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Fortly Scan
run: |
npx fortly-cli scan ${{ vars.TARGET_URL }} \
--ci \
--cloud \
--api-key ${{ secrets.FORTLY_API_KEY }} \
--fail-threshold 70 \
--format sarif \
--output ./results
- name: Upload SARIF to GitHub Security
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: ./resultsGitHub Actions annotations: When
--ciis enabled and theGITHUB_ACTIONSenvironment variable is detected, Fortly automatically emits::error::,::warning::, and::notice::annotations that appear directly in your PR.
GitLab CI
security_scan:
image: node:22
script:
- npx fortly-cli scan $TARGET_URL --ci --cloud --api-key $FORTLY_API_KEY --fail-threshold 70 --format json --output ./results
artifacts:
paths:
- results/
when: alwaysAzure Pipelines
- script: |
npx fortly-cli scan $(TARGET_URL) \
--ci \
--cloud \
--api-key $(FORTLY_API_KEY) \
--fail-threshold 70 \
--format json \
--output $(Build.ArtifactStagingDirectory)/fortly
displayName: "Fortly Security Scan"
- publish: $(Build.ArtifactStagingDirectory)/fortly
artifact: fortly-report
condition: always()Jenkins
stage('Security Scan') {
steps {
sh 'npx fortly-cli scan $TARGET_URL --ci --cloud --api-key $FORTLY_API_KEY --fail-threshold 70 --format json --output ./fortly-report'
}
post {
always {
archiveArtifacts artifacts: 'fortly-report/**', allowEmptyArchive: true
}
}
}CI Output Format
In --ci mode, Fortly outputs a single JSON line to stdout:
{
"score": 72,
"grade": "C",
"target": "https://myapp.com",
"vulnerabilities": 14,
"critical": 0,
"high": 2,
"medium": 5,
"low": 4,
"info": 3,
"duration": 45200
}Output Formats
| Format | Flag | Description |
|---|---|---|
| Terminal | --format terminal | Rich colored output with tables, progress bar, and severity badges (default) |
| JSON | --format json | Machine-readable JSON report |
| HTML | --format html | Standalone HTML report with charts and details |
| Both | --format both | JSON + HTML |
| SARIF | --format sarif | SARIF 2.1.0 for GitHub Code Scanning and other SARIF-compatible tools |
Terminal Output
The terminal reporter displays:
- Security score (0-100) with color-coded progress bar
- Letter grade (A+ through F)
- Severity breakdown table (Critical, High, Medium, Low, Info)
- Top 10 findings with severity badges, titles, types, and affected URLs
- CWE references when available
- Scan duration
SARIF Integration
SARIF reports integrate directly with GitHub Code Scanning:
fortly scan https://myapp.com --format sarif --output ./sarif-resultsUpload to GitHub with the upload-sarif action:
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: ./sarif-resultsVulnerabilities will appear in the Security tab of your repository.
Configuration
Configuration is stored persistently using the OS-native config directory:
| OS | Path |
|---|---|
| macOS | ~/Library/Preferences/fortly-nodejs/config.json |
| Linux | ~/.config/fortly-nodejs/config.json |
| Windows | %APPDATA%\fortly-nodejs\config.json |
Available Settings
| Key | Description | Example |
|---|---|---|
| api-key | API key for cloud scanning | ft_sk_abc123... |
| default-threshold | Default fail threshold | 70 |
# Store your API key securely
fortly config set api-key ft_sk_your_key_here
# Set a default threshold for all scans
fortly config set default-threshold 70
# View all settings (sensitive values are masked)
fortly config list
# Reset to defaults
fortly config resetEnvironment Variables
| Variable | Description |
|---|---|
| FT_API_KEY | API key for cloud mode (alternative to --api-key or stored config) |
| GITHUB_ACTIONS | Auto-detected; enables GitHub Actions annotations in CI mode |
Scan Engine
Local Mode (default)
Fortly runs its scan engine locally with the following defaults:
| Parameter | Default | Description |
|---|---|---|
| Max crawl depth | 3 | How deep to follow links |
| Max requests | 500 | Maximum HTTP requests per scan |
| Concurrent threads | 5 | Parallel requests |
| Request timeout | 10,000ms | Per-request timeout |
| Delay between requests | 100ms | Rate limiting |
| Retry attempts | 2 | Retries on failed requests |
| Follow redirects | true | Follow HTTP redirects |
| AI analysis | enabled | AI-powered vulnerability validation |
| AI max calls | 80 | Maximum AI analysis calls per scan |
| Excluded paths | /logout, /signout | Paths never crawled |
What Gets Scanned
Fortly covers a broad range of vulnerability classes:
- Injection — SQL injection, command injection, template injection
- XSS — Reflected, stored, and DOM-based cross-site scripting
- Authentication — Weak credentials, session management, OAuth misconfigurations
- Access Control — IDOR, privilege escalation, missing authorization
- Security Misconfiguration — Missing headers, exposed debug endpoints, default credentials
- Cryptographic Failures — Weak TLS, insecure cookies, exposed secrets
- SSRF — Server-side request forgery
- Open Redirects — Unvalidated redirects and forwards
- Information Disclosure — Stack traces, version leakage, directory listing
- CORS — Misconfigured cross-origin policies
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Scan completed successfully (score >= threshold if set) |
| 1 | Scan failed, error occurred, or score below --fail-threshold |
Use exit codes to enforce security gates in CI/CD:
fortly scan https://myapp.com --fail-threshold 70 || echo "Security gate failed!"Examples
Scan a staging environment before deploying
fortly scan https://staging.myapp.com --depth 5 --threads 10 --fail-threshold 80Generate a report for compliance review
fortly scan https://myapp.com --cloud --format both --output ./compliance-reportsIntegrate into a pre-commit hook
# .husky/pre-push
fortly scan https://localhost:3000 --ci --fail-threshold 60Scan with SARIF and upload to GitHub
fortly scan https://myapp.com --format sarif --output ./sarif
gh api repos/{owner}/{repo}/code-scanning/sarifs -X POST -F sarif=@./sarif/report.sarifView a saved report
fortly report ./fortly-reports/scan-2026-03-17.jsonSecurity
- API keys are stored encrypted in the OS-native config directory
- Sensitive values are masked in
fortly config listoutput - Fortly never sends scan results to third parties (local mode)
- Cloud mode transmits only the target URL; results are encrypted in transit
License
MIT - Copyright 2026 Fortly
