') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - thyldrm/codethreat-appsec-cli · GitHub
Skip to content

Repository files navigation

CodeThreat CLI

Command-line interface for CodeThreat security scanning platform. Enables CI/CD integration and automated security scanning workflows.

Installation

npm install -g @codethreat/appsec-cli

Or run directly with npx:

npx @codethreat/appsec-cli --help

Quick Start

1. Environment Setup

Option A: Using Environment Variables

# Set environment variables (Fish shell)set -gx CT_API_KEY "your_api_key_here"set -gx CT_SERVER_URL "http://localhost:3000"# For development# Or for Bash/Zshexport CT_API_KEY="your_api_key_here"export CT_SERVER_URL="http://localhost:3000"

Option B: Using Setup Script

# Copy and edit .env file
cp .env.example .env
# Edit .env file with your settings# Load environment (Fish shell)source setup-env.fish
# Load environment (Bash/Zsh) source setup-env.sh

Option C: Using CLI Login

# Interactive login
codethreat auth login --api-key <your-api-key> --server-url <server-url>

2. Authentication

# Validate authentication
codethreat auth validate
# Check authentication status
codethreat auth status

2. Import Repository

# Import from Git URL
codethreat repo import https://github.com/user/repo.git
# Import with custom settings
codethreat repo import https://github.com/user/repo.git \
--name "My Repo" \
--types sast,sca,secrets \
--auto-scan

3. Run Security Scan

# Asynchronous scan
codethreat scan run <repository-id> --types sast,sca
# Synchronous scan (wait for completion)
codethreat scan run <repository-id> --types sast,sca --wait --timeout 30m
# CI/CD friendly scan
codethreat scan run <repository-id> \
--types sast,sca,secrets \
--wait \
--format sarif \
--output security.sarif

4. Export Results

# Export as SARIF for GitHub Security tab
codethreat scan results <scan-id> --format sarif --output security.sarif
# Export as JUnit for GitLab CI/CD
codethreat scan results <scan-id> --format junit --output results.xml
# Export as CSV for analysis
codethreat scan results <scan-id> --format csv --severity critical,high

Commands

Authentication (auth)

  • auth login - Login with API key
  • auth validate - Validate current authentication
  • auth logout - Clear stored credentials
  • auth status - Show authentication status

Repository Management (repo)

  • repo import <url> - Import repository from Git URL
  • repo list - List imported repositories
  • repo status <id> - Get repository status and scan information

Scanning (scan)

  • scan run <repo-id> - Run security scan
  • scan status <scan-id> - Get scan status and progress
  • scan results <scan-id> - Export scan results
  • scan list - List recent scans

Organization (org)

  • org list - List available organizations
  • org select <id> - Select default organization
  • org config <id> - Get organization configuration and limits

Configuration (config)

  • config show - Show current configuration
  • config set <key> <value> - Set configuration value
  • config init - Initialize configuration file

Configuration

Configuration File (.codethreat.yml)

# Server configurationserver_url: "https://app.codethreat.com"# Or your server URLorganization_id: "your-org-id"# Default scan settingsdefault_scan_types: ["sast", "sca", "secrets"]default_branch: "main"default_timeout: 1800# 30 minutesdefault_poll_interval: 10# 10 seconds# Output settingsdefault_format: "json"output_dir: "./codethreat-results"# CI/CD behaviorfail_on_critical: truefail_on_high: falsemax_violations: 50# CLI behaviorverbose: falsecolors: true

Environment Variables

Core Configuration:

  • CT_API_KEY - CodeThreat API key (recommended for CI/CD)
  • CT_SERVER_URL - CodeThreat server URL
  • CT_ORG_ID - Default organization ID

Server URLs for Different Environments:

  • CT_PRODUCTION_URL - Production server URL
  • CT_STAGING_URL - Staging server URL
  • CT_DEVELOPMENT_URL - Development server URL

Default Settings:

  • CT_DEFAULT_SCAN_TYPES - Default scan types (comma-separated)
  • CT_DEFAULT_BRANCH - Default branch name
  • CT_DEFAULT_FORMAT - Default output format
  • CT_TIMEOUT - Default scan timeout in seconds
  • CT_POLL_INTERVAL - Default polling interval in seconds

CI/CD Behavior:

  • CT_FAIL_ON_CRITICAL - Fail build on critical findings (true/false)
  • CT_FAIL_ON_HIGH - Fail build on high severity findings (true/false)
  • CT_MAX_VIOLATIONS - Maximum allowed violations before failing

CLI Behavior:

  • CT_VERBOSE - Enable verbose output (true/false)
  • CT_COLORS - Enable colored output (true/false)
  • CT_OUTPUT_DIR - Default output directory

CLI Information (for customization):

  • CLI_NAME - CLI application name
  • CLI_VERSION - CLI version
  • CLI_DESCRIPTION - CLI description
  • SUPPORTED_FORMATS - Supported export formats (comma-separated)
  • SUPPORTED_PROVIDERS - Supported Git providers (comma-separated)

CI/CD Integration

GitHub Actions

Use the official CodeThreat GitHub Action for the best experience:

name: Security Scanon:
push:
branches: [main, develop]pull_request:
branches: [main]jobs:
security:
name: CodeThreat Security Scanruns-on: ubuntu-latestpermissions:
security-events: write # Required for SARIF uploadcontents: readactions: readsteps:
- name: Checkout Codeuses: actions/checkout@v4
- name: CodeThreat Security Scanuses: CodeThreat/codethreat-appsec-github-action@v1with:
# Requiredapi-key: ${{ secrets.CODETHREAT_API_KEY }}server-url: ${{ secrets.CODETHREAT_SERVER_URL }}github-token: ${{ secrets.GITHUB_TOKEN }}# Optional - customize as neededscan-types: 'sast,sca,secrets'fail-on-critical: truefail-on-high: falsetimeout: 30# GitHub Security tab integrationupload-sarif: trueoutput-format: 'sarif'

Alternative: Manual CLI Installation

name: Security Scan (Manual CLI)on: [push, pull_request]jobs:
security:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- name: Install CodeThreat CLIrun: npm install -g @codethreat/appsec-cli
- name: Run Security Scanenv:
CT_API_KEY: ${{ secrets.CODETHREAT_API_KEY }}CT_SERVER_URL: ${{ secrets.CODETHREAT_SERVER_URL }}run: | REPO_ID=$(codethreat repo import ${{ github.repositoryUrl }} --format json | jq -r '.repository.id') codethreat scan run $REPO_ID --wait --format sarif --output security.sarif - name: Upload SARIFuses: github/codeql-action/upload-sarif@v3if: always()with:
sarif_file: security.sarif

Exit Codes

  • 0 - Success
  • 1 - General error
  • 2 - Authentication error
  • 3 - Permission error
  • 4 - Scan failed with critical/high violations (based on configuration)

Examples

Basic Workflow

# 1. Login
codethreat auth login --api-key ct_1234567890abcdef
# 2. Import repository
codethreat repo import https://github.com/myorg/myapp.git
# 3. Run scan
codethreat scan run repo-123 --types sast,sca --wait
# 4. Export results
codethreat scan results scan-456 --format sarif

CI/CD Workflow

# One-liner for CI/CD
REPO_ID=$(codethreat repo import $REPO_URL --format json | jq -r '.repository.id')&& \
codethreat scan run $REPO_ID --wait --format sarif --output security.sarif

Advanced Usage

# Scan with custom timeout and polling
codethreat scan run repo-123 \
--types sast,sca,secrets \
--wait \
--timeout 45m \
--poll-interval 15s \
--format junit \
--output results.xml
# Export filtered results
codethreat scan results scan-456 \
--format csv \
--severity critical,high \
--types sast \
--output critical-sast.csv

Support

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages