Skip to content

🔐 cli_security — Security Audit

This example demonstrates how to perform security auditing, platform requirement checks, and configuration validation on a local PHP project, covering all the common Composer CLI capabilities in security-compliance scenarios.

📌 Example Positioning

  • Learning objective: Master the SDK-wrapped security audit, platform-availability probing, composer.json/lock and schema validation, and config normalization flows.
  • Corresponding scenarios: security gates in CI pipelines, pre-release dependency vulnerability scanning, platform-requirement checks, and configuration-file legality checks.
  • Corresponding SDK methods: AuditWithJSON, HasVulnerabilities, GetHighSeverityVulnerabilities, GetAbandonedPackages, AuditWithoutDev, AuditWithFormat, CheckPlatform, GetPHPVersion, HasExtension, GetExtensions, IsPlatformAvailable, Validate, ValidateStrict, ValidateComposerLock, ValidateSchema, NormalizeComposerJson, CheckForSecurityVulnerabilities in the composer package.
  • Prerequisites: PHP 7.4+ and Composer 2.0+ installed locally; WorkingDir points to a real PHP project.

📜 Full Code

go
package cli_security

import (
	"fmt"
	"log"

	"github.com/scagogogo/composer-skills/pkg/composer"
)

// Example01Audit demonstrates how to perform a security audit
func Example01Audit() {
	c, err := composer.New(composer.DefaultOptions())
	if err != nil {
		log.Fatalf("Failed to create Composer instance: %v", err)
	}
	c.SetWorkingDir("/path/to/project")

	// 1. Run a security audit (JSON structured result)
	fmt.Println("1. Running security audit...")
	result, err := c.AuditWithJSON()
	if err != nil {
		log.Printf("Security audit failed: %v", err)
	} else {
		fmt.Printf("Found %d vulnerabilities\n", result.Found)
	}

	// 2. Check whether vulnerabilities exist (boolean judgment)
	fmt.Println("\n2. Checking for vulnerabilities...")
	hasVuln, err := c.HasVulnerabilities()
	if err != nil {
		log.Printf("Failed to check for vulnerabilities: %v", err)
	} else if hasVuln {
		fmt.Println("⚠️ Security vulnerabilities found!")
	} else {
		fmt.Println("✅ No security vulnerabilities found")
	}

	// 3. Get high-severity vulnerabilities
	fmt.Println("\n3. Getting high-severity vulnerabilities...")
	highSeverity, err := c.GetHighSeverityVulnerabilities()
	if err != nil {
		log.Printf("Failed to get high-severity vulnerabilities: %v", err)
	} else {
		fmt.Printf("High-severity vulnerability count: %d\n", len(highSeverity))
		for _, v := range highSeverity {
			fmt.Printf("  - %s: %s\n", v.Title, v.Link)
		}
	}

	// 4. Get abandoned packages
	fmt.Println("\n4. Getting abandoned packages...")
	abandoned, err := c.GetAbandonedPackages()
	if err != nil {
		log.Printf("Failed to get abandoned packages: %v", err)
	} else {
		fmt.Printf("Abandoned package count: %d\n", len(abandoned))
		for _, v := range abandoned {
			fmt.Printf("  - %s: %s\n", v.Package, v.Title)
		}
	}

	// 5. Audit without dev dependencies
	fmt.Println("\n5. Auditing without dev dependencies...")
	output, err := c.AuditWithoutDev()
	if err != nil {
		log.Printf("Audit failed: %v", err)
	} else {
		fmt.Println(output)
	}

	// 6. Audit (summary format)
	fmt.Println("\n6. Auditing (summary format)...")
	output, err = c.AuditWithFormat("summary")
	if err != nil {
		log.Printf("Audit failed: %v", err)
	} else {
		fmt.Println(output)
	}
}

// Example02PlatformCheck demonstrates how to check platform requirements
func Example02PlatformCheck() {
	c, err := composer.New(composer.DefaultOptions())
	if err != nil {
		log.Fatalf("Failed to create Composer instance: %v", err)
	}
	c.SetWorkingDir("/path/to/project")

	// 1. Check platform requirements
	fmt.Println("1. Checking platform requirements...")
	platformInfo, err := c.CheckPlatform()
	if err != nil {
		log.Printf("Failed to check platform requirements: %v", err)
	} else {
		for _, info := range platformInfo {
			status := "✅"
			if !info.Available {
				status = "❌"
			}
			fmt.Printf("  %s %s %s\n", status, info.Name, info.Version)
		}
	}

	// 2. Get the PHP version
	fmt.Println("\n2. Getting PHP version...")
	phpVersion, err := c.GetPHPVersion()
	if err != nil {
		log.Printf("Failed to get PHP version: %v", err)
	} else {
		fmt.Printf("PHP version: %s\n", phpVersion)
	}

	// 3. Check whether an extension is available
	fmt.Println("\n3. Checking whether an extension is available...")
	hasExt, err := c.HasExtension("mbstring")
	if err != nil {
		log.Printf("Failed to check extension: %v", err)
	} else if hasExt {
		fmt.Println("✅ mbstring extension is installed")
	} else {
		fmt.Println("❌ mbstring extension is not installed")
	}

	// 4. Get the list of installed extensions
	fmt.Println("\n4. Getting the list of installed extensions...")
	extensions, err := c.GetExtensions()
	if err != nil {
		log.Printf("Failed to get extension list: %v", err)
	} else {
		fmt.Printf("%d extensions installed\n", len(extensions))
	}

	// 5. Check whether a specific platform is available
	fmt.Println("\n5. Checking whether a specific platform is available...")
	available, err := c.IsPlatformAvailable("php", "8.1.0")
	if err != nil {
		log.Printf("Failed to check platform availability: %v", err)
	} else if available {
		fmt.Println("✅ PHP 8.1.0 is available")
	} else {
		fmt.Println("❌ PHP 8.1.0 is not available")
	}
}

// Example03Validation demonstrates how to validate project configuration
func Example03Validation() {
	c, err := composer.New(composer.DefaultOptions())
	if err != nil {
		log.Fatalf("Failed to create Composer instance: %v", err)
	}
	c.SetWorkingDir("/path/to/project")

	// 1. Validate composer.json
	fmt.Println("1. Validating composer.json...")
	err = c.Validate()
	if err != nil {
		fmt.Printf("❌ composer.json validation failed: %v\n", err)
	} else {
		fmt.Println("✅ composer.json validation passed")
	}

	// 2. Strict validation
	fmt.Println("\n2. Strictly validating composer.json...")
	output, err := c.ValidateStrict()
	if err != nil {
		fmt.Printf("Validation failed: %v\n", err)
	} else {
		fmt.Println(output)
	}

	// 3. Validate composer.lock
	fmt.Println("\n3. Validating composer.lock...")
	output, err = c.ValidateComposerLock()
	if err != nil {
		fmt.Printf("Validation failed: %v\n", err)
	} else {
		fmt.Println(output)
	}

	// 4. Validate the schema
	fmt.Println("\n4. Validating the schema...")
	output, err = c.ValidateSchema()
	if err != nil {
		fmt.Printf("Validation failed: %v\n", err)
	} else {
		fmt.Println(output)
	}

	// 5. Normalize composer.json
	fmt.Println("\n5. Normalizing composer.json...")
	output, err = c.NormalizeComposerJson()
	if err != nil {
		fmt.Printf("Normalization failed: %v\n", err)
	} else {
		fmt.Println(output)
	}

	// 6. Check for security vulnerabilities (comprehensive judgment)
	fmt.Println("\n6. Checking for security vulnerabilities...")
	output, hasVuln, err := c.CheckForSecurityVulnerabilities()
	if err != nil {
		fmt.Printf("Check failed: %v\n", err)
	} else if hasVuln {
		fmt.Printf("⚠️ Security vulnerabilities found:\n%s\n", output)
	} else {
		fmt.Println("✅ No security vulnerabilities found")
	}
}

🧠 Code Walkthrough

Creating the instance and setting the working directory

🔧 All three functions create the instance with composer.New(composer.DefaultOptions()) and then use SetWorkingDir to specify the path of the PHP project to audit. All subsequent commands execute the composer binary in that directory.

Security Audit (Example01Audit)

🛡️ AuditWithJSON returns a structured result; the Found field directly gives the vulnerability count, suitable for programmatic judgment. HasVulnerabilities further compresses the result into a boolean — the simplest decision form for a CI gate.

⚠️ GetHighSeverityVulnerabilities and GetAbandonedPackages are semantic filters the SDK applies on top of the audit output: the former filters high-severity entries and includes Title/Link, and the latter flags abandoned packages — convenient for generating alert lists.

🎯 AuditWithoutDev skips require-dev dependencies, simulating the real production exposure surface; AuditWithFormat("summary") switches the output format for terminal-friendly display.

Platform Requirement Checks (Example02PlatformCheck)

🖥️ CheckPlatform lists the availability of the PHP version and all extensions in one shot; info.Available determines whether ✅ or ❌ is shown.

🔎 GetPHPVersion and HasExtension/GetExtensions provide more granular queries; IsPlatformAvailable("php", "8.1.0") is used to precisely judge whether the target version meets the bar before deployment.

Configuration Validation (Example03Validation)

Validate is the default check, and ValidateStrict enables strict mode; both treat composer.json legality as a deployment precondition.

🔒 ValidateComposerLock validates the lock file's consistency with composer.json, ValidateSchema validates field formats, and NormalizeComposerJson can also auto-normalize the formatting output.

🚨 CheckForSecurityVulnerabilities returns both the text output and a boolean flag (output, hasVuln, err) — a composite "validation + vulnerability" check, best suited as the final deployment gate.

▶️ How to Run

bash
# Run from the repository root
cd /home/cc11001100/github/scagogogo/composer-skills

# Run the entire cli_security example package (requires PHP and Composer installed locally)
go run examples/cli_security/01_audit_platform_validate.go

💡 Please replace /path/to/project in the code with a real PHP project path; if Composer is not installed locally, the SDK triggers the auto-install flow.

📚 SDK Methods Involved

Method NamePackageDoc Link
AuditWithJSONcomposer/sdk/composer/methods/audit-with-json
HasVulnerabilitiescomposer/sdk/composer/methods/has-vulnerabilities
GetHighSeverityVulnerabilitiescomposer/sdk/composer/methods/get-high-severity-vulnerabilities
GetAbandonedPackagescomposer/sdk/composer/methods/get-abandoned-packages
AuditWithoutDevcomposer/sdk/composer/methods/audit-without-dev
AuditWithFormatcomposer/sdk/composer/methods/audit-with-format
CheckPlatformcomposer/sdk/composer/methods/check-platform
GetPHPVersioncomposer/sdk/composer/methods/get-php-version
HasExtensioncomposer/sdk/composer/methods/has-extension
GetExtensionscomposer/sdk/composer/methods/get-extensions
IsPlatformAvailablecomposer/sdk/composer/methods/is-platform-available
Validatecomposer/sdk/composer/methods/validate-strict
ValidateStrictcomposer/sdk/composer/methods/validate-strict
ValidateComposerLockcomposer/sdk/composer/methods/validate-composer-lock
ValidateSchemacomposer/sdk/composer/methods/validate-schema
NormalizeComposerJsoncomposer/sdk/composer/methods/normalize-composer-json
CheckForSecurityVulnerabilitiescomposer/sdk/composer/methods/check-for-security-vulnerabilities

🚀 Going Further

  • 📈 CI gate-ification: chain HasVulnerabilities and Validate into pipeline steps that block deployment on any vulnerability or validation failure, and pair it with the security_monitor idea to hook up alerting channels.
  • 🧾 Vulnerability persistence: write AuditWithJSON's structured result into a database and track vulnerability-fix progress over time, rather than relying solely on terminal output.
  • 🔁 Scheduled patrol: pair cron with periodic calls to GetHighSeverityVulnerabilities to respond to newly disclosed CVEs as early as possible.
  • 🧪 Platform pre-flight: use IsPlatformAvailable to validate the target runtime version before container build, avoiding discovering missing extensions only after release.
  • 🧰 Normalization pipeline: bring NormalizeComposerJson into a pre-commit hook to unify the team's composer.json formatting style and reduce needless diffs.

Released under the MIT License