diff --git a/pkg/cli/cmd/assets.go b/pkg/cli/cmd/assets.go index c700ce9..d460990 100644 --- a/pkg/cli/cmd/assets.go +++ b/pkg/cli/cmd/assets.go @@ -50,9 +50,12 @@ ASSET TYPES: • DOMAIN - DNS domains ASSET STATUS: - • MONITORED - Active monitoring and scanning - • UNMONITORED - Discovered but not actively tested - • ARCHIVED - No longer in use + • MONITORED - Active monitoring and scanning + • DEPRECATED - Deprecated asset (kept for tracking) + • OUT_OF_SCOPE - Excluded from scope + • PERMANENT - Permanent asset status + • THIRD_PARTY - Third-party owned/managed asset + • FALSE_POSITIVE - Incorrectly flagged asset status COMMON WORKFLOWS: • List all monitored assets: @@ -79,7 +82,7 @@ the APIs, applications, and infrastructure being monitored by Escape. FILTER OPTIONS: -t, --types Filter by asset types (WEBAPP, REST_API, GRAPHQL_API, etc.) - --statuses Filter by monitoring status (MONITORED, UNMONITORED, ARCHIVED) + --statuses Filter by monitoring status (DEPRECATED, FALSE_POSITIVE, MONITORED, OUT_OF_SCOPE, PERMANENT, THIRD_PARTY) -s, --search Free-text search across asset names and URLs -m, --manually-created Filter assets created manually vs auto-discovered @@ -261,12 +264,12 @@ Permanently delete an asset from your inventory. This will also remove: • Issue findings linked to this asset • Activity logs and events -⚠️ WARNING: This action is IRREVERSIBLE! +WARNING: This action is IRREVERSIBLE! ALTERNATIVES TO DELETION: Instead of deleting, consider: - • Archiving: Use 'escape-cli assets update --status ARCHIVED' - • Unmonitoring: Use 'escape-cli assets update --status UNMONITORED' + • Changing status: Use 'escape-cli assets update --status ' + (valid STATUS values: DEPRECATED, FALSE_POSITIVE, MONITORED, OUT_OF_SCOPE, PERMANENT, THIRD_PARTY) WHEN TO DELETE: • Test/temporary assets no longer needed @@ -316,21 +319,16 @@ and framework classification. Use this to maintain accurate asset inventory. UPDATABLE FIELDS: -d, --description Human-readable description -f, --framework Asset framework/type classification - -s, --status Monitoring status (MONITORED, UNMONITORED, ARCHIVED) + -s, --status Monitoring status (DEPRECATED, FALSE_POSITIVE, MONITORED, OUT_OF_SCOPE, PERMANENT, THIRD_PARTY) --owners Asset owners (email addresses) -t, --tag-ids Tag IDs for organization -STATUS TRANSITIONS: - • MONITORED → UNMONITORED Stop active scanning - • UNMONITORED → MONITORED Resume security testing - • Any → ARCHIVED Mark as decommissioned - USE CASES: • Update asset description for clarity • Change monitoring status • Assign ownership for accountability • Add tags for organization and filtering - • Archive deprecated APIs`, + • Mark assets as DEPRECATED / OUT_OF_SCOPE`, Example: ` # Update asset description escape-cli assets update --description "Production REST API" @@ -341,10 +339,10 @@ USE CASES: escape-cli assets update --owners "security@example.com,devops@example.com" # Add tags for organization - escape-cli assets update --tag-ids "tag-prod,tag-critical" + escape-cli assets update --tag-ids "00000000-0000-0000-0000-000000000000,00000000-0000-0000-0000-000000000001" - # Archive decommissioned asset - escape-cli assets update --status ARCHIVED --description "Deprecated - removed 2025-10-01" + # Mark deprecated asset + escape-cli assets update --status DEPRECATED --description "Deprecated - removed 2025-10-01" # Update multiple fields at once escape-cli assets update \ diff --git a/pkg/cli/cmd/audit.go b/pkg/cli/cmd/audit.go index 181532a..c63c5e7 100644 --- a/pkg/cli/cmd/audit.go +++ b/pkg/cli/cmd/audit.go @@ -68,17 +68,15 @@ FILTER OPTIONS: # Export for compliance reporting escape-cli audit list --date-from 2025-01-01T00:00:00Z -o json > audit-report-jan2025.json`, RunE: func(cmd *cobra.Command, _ []string) error { - logs, next, err := escape.ListAuditLogs( - cmd.Context(), - "", - &escape.ListAuditLogsFilters{ - DateFrom: auditCmdDateFrom, - DateTo: auditCmdDateTo, - ActionType: auditCmdEventType, - Actor: auditCmdActor, - Search: auditCmdSearch, - }, - ) + filters := &escape.ListAuditLogsFilters{ + DateFrom: auditCmdDateFrom, + DateTo: auditCmdDateTo, + ActionType: auditCmdEventType, + Actor: auditCmdActor, + Search: auditCmdSearch, + } + + logs, next, err := escape.ListAuditLogs(cmd.Context(), "", filters) if err != nil { return fmt.Errorf("unable to list audits: %w", err) } @@ -99,15 +97,7 @@ FILTER OPTIONS: }) for next != nil && *next != "" { - logs, next, err = escape.ListAuditLogs( - cmd.Context(), - *next, - &escape.ListAuditLogsFilters{ - DateFrom: auditCmdDateFrom, - DateTo: auditCmdDateTo, - ActionType: auditCmdEventType, - }, - ) + logs, next, err = escape.ListAuditLogs(cmd.Context(), *next, filters) if err != nil { return fmt.Errorf("unable to list audits: %w", err) } diff --git a/pkg/cli/cmd/events.go b/pkg/cli/cmd/events.go index a818f58..358a937 100644 --- a/pkg/cli/cmd/events.go +++ b/pkg/cli/cmd/events.go @@ -30,15 +30,15 @@ and understanding test behavior. EVENT LEVELS: • ERROR - Scan errors and failures - • WARN - Warnings and potential issues + • WARNING - Warnings and potential issues • INFO - General informational messages • DEBUG - Detailed debugging information EVENT STAGES: - • DISCOVERY - API endpoint discovery - • EXECUTION - Active security testing - • ANALYSIS - Results processing - • REPORTING - Report generation`, + • AGENT_ACTION - Agent action + • AGENT_REASONING - Agent reasoning + • CONFIGURATION - Configuration + • EXECUTION - Execution`, } var eventsListCmd = &cobra.Command{ @@ -55,7 +55,7 @@ FILTER OPTIONS: -a, --asset-id Filter by asset ID -i, --issue-id Filter by issue ID --stage Filter by execution stage - -l, --levels Filter by level (ERROR, WARN, INFO, DEBUG) + -l, --levels Filter by level (ERROR, WARNING, INFO, DEBUG) --has-attachments Show only events with attachments`, Example: ` # List recent events escape-cli events list @@ -95,7 +95,7 @@ FILTER OPTIONS: events, next, err = escape.ListEvents(cmd.Context(), *next, filters) if err != nil { - return fmt.Errorf("unable to list profiles: %w", err) + return fmt.Errorf("unable to list events: %w", err) } out.Table(events, func() []string { res := []string{"ID\tCREATED AT\tLEVEL\tSTAGE\tTITLE"} diff --git a/pkg/cli/cmd/issues.go b/pkg/cli/cmd/issues.go index 44d3dad..cf45e88 100644 --- a/pkg/cli/cmd/issues.go +++ b/pkg/cli/cmd/issues.go @@ -37,12 +37,11 @@ discovered during security scans. Each issue represents a specific security conc that should be reviewed and remediated. ISSUE LIFECYCLE: - 1. OPEN - Newly discovered, needs review - 2. MANUAL_REVIEW - Under investigation - 3. IN_PROGRESS - Actively being fixed - 4. RESOLVED - Fixed and verified - 5. FALSE_POSITIVE - Not a real issue - 6. ACCEPTED_RISK - Acknowledged but not fixing + 1. OPEN - Newly discovered, needs review + 2. MANUAL_REVIEW - Under investigation + 3. RESOLVED - Fixed and verified + 4. FALSE_POSITIVE - Not a real issue + 5. IGNORED - Ignored / excluded from tracking COMMON WORKFLOWS: • List high-priority issues: @@ -52,7 +51,7 @@ COMMON WORKFLOWS: $ escape-cli issues list --asset-id • Update issue status as you fix them: - $ escape-cli issues update --status IN_PROGRESS + $ escape-cli issues update --status MANUAL_REVIEW • Track issue history: $ escape-cli issues list-activities `, @@ -69,7 +68,7 @@ filtering options to find exactly the issues you need to review or remediate. FILTER OPTIONS: --severity Filter by severity: CRITICAL, HIGH, MEDIUM, LOW, INFO - --status Filter by status: OPEN, MANUAL_REVIEW, IN_PROGRESS, RESOLVED + --status Filter by status: FALSE_POSITIVE, IGNORED, MANUAL_REVIEW, OPEN, RESOLVED -p, --profile-id Filter by profile ID -a, --asset-id Filter by asset ID -d, --domain Filter by domain name @@ -138,7 +137,7 @@ ID CREATED AT SEVERITY STATUS NAME for next != nil && *next != "" { issues, next, err = escape.ListIssues(cmd.Context(), *next, filters) if err != nil { - return fmt.Errorf("unable to list profiles: %w", err) + return fmt.Errorf("unable to list issues: %w", err) } out.Table(issues, func() []string { res := []string{"ID\tCREATED AT\tSEVERITY\tSTATUS\tNAME\tASSET\tLINK"} @@ -227,19 +226,16 @@ Change the status of a security issue as you progress through remediation. Status updates create an audit trail and help teams track security work. AVAILABLE STATUSES: - OPEN - Newly discovered, awaiting review - MANUAL_REVIEW - Under investigation by security team - IN_PROGRESS - Actively being fixed by developers - RESOLVED - Fixed and verified - FALSE_POSITIVE - Determined not to be a real issue - ACCEPTED_RISK - Acknowledged but not fixing (with justification) - REOPENED - Previously resolved but found again + OPEN - Newly discovered, awaiting review + MANUAL_REVIEW - Under investigation by security team + RESOLVED - Fixed and verified + FALSE_POSITIVE - Determined not to be a real issue + IGNORED - Ignored / excluded from tracking WORKFLOW EXAMPLE: 1. New issue discovered: OPEN 2. Security team reviews: MANUAL_REVIEW - 3. Assigned to developers: IN_PROGRESS - 4. Fix deployed and tested: RESOLVED + 3. Fix deployed and tested: RESOLVED TRACKING: All status changes are logged in the issue's activity history. @@ -247,17 +243,17 @@ TRACKING: Example: ` # Mark issue under review escape-cli issues update --status MANUAL_REVIEW - # Mark as in progress when fixing - escape-cli issues update --status IN_PROGRESS - # Mark as resolved after fixing escape-cli issues update --status RESOLVED # Mark as false positive escape-cli issues update --status FALSE_POSITIVE + + # Ignore an issue + escape-cli issues update --status IGNORED # Bulk update issues from a list - cat issue_ids.txt | xargs -I {} escape-cli issues update {} --status IN_PROGRESS`, + cat issue_ids.txt | xargs -I {} escape-cli issues update {} --status MANUAL_REVIEW`, RunE: func(cmd *cobra.Command, args []string) error { issueID := args[0] if err := cmd.MarkFlagRequired("status"); err != nil { diff --git a/pkg/cli/cmd/locations.go b/pkg/cli/cmd/locations.go index 50096f5..d3e2588 100644 --- a/pkg/cli/cmd/locations.go +++ b/pkg/cli/cmd/locations.go @@ -89,9 +89,19 @@ ID NAME SSH PUBLIC KE return fmt.Errorf("failed to list locations: %w", err) } out.Table(locations, func() []string { - res := []string{} + res := []string{"ID\tNAME\tTYPE\tENABLED\tLINK"} for _, location := range locations { - res = append(res, fmt.Sprintf("%s\t%s\t%s\t%t", location.GetId(), location.GetName(), location.GetType(), location.GetEnabled())) + res = append( + res, + fmt.Sprintf( + "%s\t%s\t%s\t%t\t%s", + location.GetId(), + location.GetName(), + location.GetType(), + location.GetEnabled(), + location.GetLinks().LocationOverview, + ), + ) } return res }) diff --git a/pkg/cli/cmd/root.go b/pkg/cli/cmd/root.go index 9606d3b..d2167e1 100644 --- a/pkg/cli/cmd/root.go +++ b/pkg/cli/cmd/root.go @@ -30,45 +30,72 @@ var asciiLogo = ` var asciiHeader = "Escape CLI V3" +func getHelpTemplate(colorEnabled bool) string { + logo := asciiLogo + header := asciiHeader + if colorEnabled { + logo = "\x1b[38;2;6;226;183m" + asciiLogo + "\x1b[0m" + header = "\x1b[38;2;6;226;183m" + asciiHeader + "\x1b[0m" + } + + return logo + "\n" + header + ` + +{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}} + +{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}{{if .HasAvailableSubCommands}} + +Command Categories: + Scanning: scans - Run security scans and view results + Security: issues - Manage security vulnerabilities + Monitoring: problems - View scan problems and failures + Configuration: profiles - Configure scan targets and settings + Assets: assets - Manage your API inventory + Infrastructure: locations - Deploy private scanning locations + Organization: audit - Review activity logs and events + Customization: custom-rules, tags - Extend and organize +{{end}}{{if .HasAvailableLocalFlags}} + +Flags: +{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}} + +Global Flags: +{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasExample}} + +Examples: +{{.Example}}{{end}}{{if .HasAvailableSubCommands}} + +Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}} + +Environment Variables: + ESCAPE_API_KEY - Your API key for authentication + ESCAPE_COLOR_DISABLED - Disable colored output (set to \"true\") + + CI/CD Auto-Detection (commit information): + - GitHub Actions: GITHUB_SHA, GITHUB_REF_NAME, GITHUB_ACTOR + - GitLab CI: CI_COMMIT_SHA, CI_COMMIT_REF_NAME, GITLAB_USER_EMAIL + - CircleCI: CIRCLE_SHA1, CIRCLE_BRANCH, CIRCLE_USERNAME + +For additional information, see: https://docs.escape.tech/documentation/tooling/cli +` +} + var rootCmd = &cobra.Command{ Use: "escape-cli", - Short: asciiLogo + "\n" + asciiHeader, - Long: `Escape CLI - Your Gateway to Comprehensive API Security Testing + Short: "Escape CLI - Comprehensive API Security Testing Platform", + Long: `Escape CLI - Comprehensive API Security Testing Platform Escape is the most advanced API security platform, helping you discover, test, and secure your APIs with cutting-edge DAST (Dynamic Application Security Testing) capabilities. -🎯 WHAT YOU CAN DO: - • Start security scans on your REST, GraphQL, and Web APIs +Use this CLI to: + • Start security scans on REST, GraphQL, and Web APIs • Monitor and track security issues across your API ecosystem • Manage security profiles, assets, and test configurations • Review audit logs and security events • Deploy private scanning locations for internal APIs -📚 GETTING STARTED: - 1. First time? Check your version: - $ escape-cli version - - 2. List your API profiles: - $ escape-cli profiles list - - 3. Start a security scan: - $ escape-cli scans start --watch - - 4. Review discovered issues: - $ escape-cli issues list --severity HIGH,CRITICAL - -💡 PRO TIPS: - • Use -v for verbose logging (-vv for debug, -vvv for trace) - • Output in JSON or YAML with -o json or -o yaml - • Most list commands support powerful filtering options - • Use --watch flag when starting scans for real-time updates - -🔗 RESOURCES: - • Documentation: https://docs.escape.tech/documentation/tooling/cli - • API Reference: https://public.escape.tech/v3 - • Support: https://escape.tech/contact`, +For more information, see: https://docs.escape.tech/documentation/tooling/cli`, PersistentPreRunE: func(c *cobra.Command, _ []string) error { version.WarnIfNotLatestVersion(c.Context()) @@ -109,36 +136,10 @@ capabilities. func init() { rootCmd.PersistentFlags().CountVarP(&rootCmdVerbose, "verbose", "v", "verbose output: -v (info), -vv (debug), -vvv (trace), -vvvv (http debug)") rootCmd.PersistentFlags().StringVarP(&rootCmdOutputStr, "output", "o", "pretty", "output format: pretty (human-readable tables), json (machine-readable), yaml (configuration files)") - rootCmd.SetUsageTemplate(rootCmd.UsageTemplate() + ` -COMMAND CATEGORIES: - Scanning: scans - Run security scans and view results - Security: issues - Manage security vulnerabilities - Monitoring: problems - View scan problems and failures - Configuration: profiles - Configure scan targets and settings - Assets: assets - Manage your API inventory - Infrastructure: locations - Deploy private scanning locations - Organization: audit - Review activity logs and events - Customization: custom-rules, tags - Extend and organize - -ENVIRONMENT VARIABLES: - ESCAPE_APPLICATION_URL - Escape platform URL (default: https://public.escape.tech) - ESCAPE_API_KEY - Your API key for authentication - NO_COLOR - Disable colored output (set to any value) - HTTP_PROXY, HTTPS_PROXY - Configure proxy settings - - CI/CD Auto-Detection (commit information): - - GitHub Actions: GITHUB_SHA, GITHUB_REF_NAME, GITHUB_ACTOR - - GitLab CI: CI_COMMIT_SHA, CI_COMMIT_REF_NAME, GITLAB_USER_EMAIL - - CircleCI: CIRCLE_SHA1, CIRCLE_BRANCH, CIRCLE_USERNAME - -For additional information, see the documentation: -https://docs.escape.tech/documentation/tooling/cli -`) isColorDisabled := env.GetColorPreference() - if !isColorDisabled { - rootCmd.Short = "\x1b[38;2;6;226;183m" + asciiLogo + "\x1b[0m" + "\n" + "\x1b[38;2;6;226;183m" + asciiHeader + "\x1b[0m" - } + helpTemplate := getHelpTemplate(!isColorDisabled) + rootCmd.SetHelpTemplate(helpTemplate) } // Execute the CLI diff --git a/pkg/cli/cmd/scans.go b/pkg/cli/cmd/scans.go index 273add0..de51d52 100644 --- a/pkg/cli/cmd/scans.go +++ b/pkg/cli/cmd/scans.go @@ -66,7 +66,7 @@ FILTER OPTIONS: -p, --profile-id Filter by one or more profile IDs -s, --status Filter by scan status (RUNNING, FINISHED, FAILED, CANCELED) -k, --kind Filter by scanner type (BLST_REST, BLST_GRAPHQL, FRONTEND_DAST) - -i, --initiator Filter by who started the scan (MANUAL, API, SCHEDULED, CI) + -i, --initiator Filter by who started the scan (CI, MANUAL, SCHEDULED) --after Show scans created after this date (RFC3339 format) --before Show scans created before this date (RFC3339 format) --ignored Filter by ignored status (true/false) diff --git a/pkg/cli/out/table.go b/pkg/cli/out/table.go index c841777..a89d521 100644 --- a/pkg/cli/out/table.go +++ b/pkg/cli/out/table.go @@ -18,7 +18,6 @@ const ( var isColorDisabled bool -// DisableColor disables color output called if the ESCAPE_NO_COLOR environment variable is set func DisableColor() { isColorDisabled = true }