🔐 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,CheckForSecurityVulnerabilitiesin thecomposerpackage. - Prerequisites: PHP 7.4+ and Composer 2.0+ installed locally;
WorkingDirpoints to a real PHP project.
📜 Full Code
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
# 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/projectin the code with a real PHP project path; if Composer is not installed locally, the SDK triggers the auto-install flow.
📚 SDK Methods Involved
🚀 Going Further
- 📈 CI gate-ification: chain
HasVulnerabilitiesandValidateinto 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
GetHighSeverityVulnerabilitiesto respond to newly disclosed CVEs as early as possible. - 🧪 Platform pre-flight: use
IsPlatformAvailableto validate the target runtime version before container build, avoiding discovering missing extensions only after release. - 🧰 Normalization pipeline: bring
NormalizeComposerJsoninto a pre-commit hook to unify the team's composer.json formatting style and reduce needless diffs.