Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions .github/workflows/pmg-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,15 @@ jobs:
test -d node_modules/lodash
cd .. && rm -rf npm-test

- name: Test NPM - Experimental Proxy Mode
- name: Test NPM - Proxy Mode
run: |
echo "Testing NPM with experimental proxy-based interception..."
echo "Testing NPM with proxy-based interception..."
mkdir npm-proxy-test && cd npm-proxy-test
pmg npm init -y

echo "Testing proxy mode single package installation..."
pmg --experimental-proxy-mode npm install express@5.2.1
pmg --experimental-proxy-mode npm install lodash@4.17.21
pmg npm install express@5.2.1
pmg npm install lodash@4.17.21

# Verification: packages installed via proxy mode
test -d node_modules/express
Expand All @@ -119,15 +119,15 @@ jobs:

echo "Testing proxy mode manifest installation..."
rm -rf node_modules package-lock.json
pmg --experimental-proxy-mode npm install
pmg npm install

# Verification: manifest install via proxy mode works
test -f package-lock.json
test -d node_modules/express
test -d node_modules/lodash

echo "Testing proxy mode with scoped package..."
pmg --experimental-proxy-mode npm install @types/node@18.0.0
pmg npm install @types/node@18.0.0

# Verification: scoped package installed via proxy
test -d node_modules/@types
Expand All @@ -136,7 +136,7 @@ jobs:

echo "Testing proxy mode dry-run (should not create files)..."
rm -rf node_modules package-lock.json
pmg --experimental-proxy-mode --dry-run npm install
pmg --dry-run npm install

# Verification: dry-run doesn't create files even in proxy mode
test ! -d node_modules
Expand Down Expand Up @@ -378,7 +378,7 @@ jobs:
mkdir safedep-test-pkg-test && cd safedep-test-pkg-test
pmg npm init -y
# Attempt to install safedep-test-pkg - should fail
if pmg --experimental-proxy-mode npm --no-cache --prefer-online i safedep-test-pkg@0.1.3; then
if pmg npm --no-cache --prefer-online i safedep-test-pkg@0.1.3; then
echo "ERROR: safedep-test-pkg was not blocked!"
exit 1
else
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ uv pip install <package-name>
## Features

- Malicious package identification using [SafeDep Cloud](https://docs.safedep.io/cloud/malware-analysis) with realtime threat detection
- Deep dependency analysis and transitive dependency resolution
- Proxy based dependency analysis and resolution
- Fast and efficient package verification
- Defense in depth using OS native sandboxing
- Seamless integration with existing package managers
Expand Down
6 changes: 3 additions & 3 deletions cmd/executors/npx.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func executeNpxFlow(ctx context.Context, args []string) error {
return fmt.Errorf("failed to create dependency resolver: %w", err)
}

if config.IsProxyModeEnabled() {
return flows.ProxyFlow(packageExecutor, packageResolver).Run(ctx, args, parsedCommand)
if !config.IsProxyModeEnabled() {
return flows.Common(packageExecutor, packageResolver).Run(ctx, args, parsedCommand)
}

return flows.Common(packageExecutor, packageResolver).Run(ctx, args, parsedCommand)
return flows.ProxyFlow(packageExecutor, packageResolver).Run(ctx, args, parsedCommand)
}
6 changes: 3 additions & 3 deletions cmd/executors/pnpx.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func executePnpxFlow(ctx context.Context, args []string) error {
return fmt.Errorf("failed to create dependency resolver: %w", err)
}

if config.IsProxyModeEnabled() {
return flows.ProxyFlow(packageExecutor, packageResolver).Run(ctx, args, parsedCommand)
if !config.IsProxyModeEnabled() {
return flows.Common(packageExecutor, packageResolver).Run(ctx, args, parsedCommand)
}

return flows.Common(packageExecutor, packageResolver).Run(ctx, args, parsedCommand)
return flows.ProxyFlow(packageExecutor, packageResolver).Run(ctx, args, parsedCommand)
}
6 changes: 3 additions & 3 deletions cmd/npm/bun.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func executeBunFlow(ctx context.Context, args []string) error {
return fmt.Errorf("failed to create dependency resolver: %w", err)
}

if config.IsProxyModeEnabled() {
return flows.ProxyFlow(packageManager, packageResolver).Run(ctx, args, parsedCommand)
if !config.IsProxyModeEnabled() {
return flows.Common(packageManager, packageResolver).Run(ctx, args, parsedCommand)
}

return flows.Common(packageManager, packageResolver).Run(ctx, args, parsedCommand)
return flows.ProxyFlow(packageManager, packageResolver).Run(ctx, args, parsedCommand)
}
6 changes: 3 additions & 3 deletions cmd/npm/npm.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func executeNpmFlow(ctx context.Context, args []string) error {
return fmt.Errorf("failed to create dependency resolver: %w", err)
}

if config.IsProxyModeEnabled() {
return flows.ProxyFlow(packageManager, packageResolver).Run(ctx, args, parsedCommand)
if !config.IsProxyModeEnabled() {
return flows.Common(packageManager, packageResolver).Run(ctx, args, parsedCommand)
}

return flows.Common(packageManager, packageResolver).Run(ctx, args, parsedCommand)
return flows.ProxyFlow(packageManager, packageResolver).Run(ctx, args, parsedCommand)
}
6 changes: 3 additions & 3 deletions cmd/npm/pnpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ func executePnpmFlow(ctx context.Context, args []string) error {
return fmt.Errorf("failed to create dependency resolver: %w", err)
}

if config.IsProxyModeEnabled() {
return flows.ProxyFlow(packageManager, packageResolver).Run(ctx, args, parsedCommand)
if !config.IsProxyModeEnabled() {
return flows.Common(packageManager, packageResolver).Run(ctx, args, parsedCommand)
}

return flows.Common(packageManager, packageResolver).Run(ctx, args, parsedCommand)
return flows.ProxyFlow(packageManager, packageResolver).Run(ctx, args, parsedCommand)
}
6 changes: 3 additions & 3 deletions cmd/npm/yarn.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func executeYarnFlow(ctx context.Context, args []string) error {
return fmt.Errorf("failed to create dependency resolver: %w", err)
}

if config.IsProxyModeEnabled() {
return flows.ProxyFlow(packageManager, packageResolver).Run(ctx, args, parsedCommand)
if !config.IsProxyModeEnabled() {
return flows.Common(packageManager, packageResolver).Run(ctx, args, parsedCommand)
}

return flows.Common(packageManager, packageResolver).Run(ctx, args, parsedCommand)
return flows.ProxyFlow(packageManager, packageResolver).Run(ctx, args, parsedCommand)
}
3 changes: 2 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,9 @@ func DefaultConfig() RuntimeConfig {
Paranoid: false,
EventLogRetentionDays: 7,
SkipEventLogging: false,
ExperimentalProxyMode: false,
ExperimentalProxyMode: true,
TrustedPackages: []TrustedPackage{},
ProxyMode: true,
Sandbox: SandboxConfig{
Enabled: false,
EnforceAlways: false,
Expand Down
8 changes: 4 additions & 4 deletions config/config.template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@ include_dev_dependencies: false
paranoid: false

# Skip event logging. Default is false.
# When event logging is enabled, all events will be logged to file. These events are useful for audit
# When skip event logging is enabled (false), all events will be logged to file. These events are useful for audit
# trail and incident response on systems using PMG. Set this config to true to skip event logging.
skip_event_logging: false

# Event log retention days. Default is 7.
# This is the number of days to retain event logs.
event_log_retention_days: 7

# Proxy mode. Default is false.
# When enabled, PMG uses an experimental proxy-based interception approach instead of the
# Proxy mode. Default is true.
# PMG uses an proxy-based interception approach instead of the
# default guard-based analysis. The proxy intercepts package manager requests in real-time
# and analyzes packages as they are downloaded. This is an experimental feature and may not
# work in all environments.
proxy_mode: false
proxy_mode: true

# Trusted packages are packages that are trusted by the user and will be ignored by the security guardrails.
# This is useful for packages that are known to be safe and are used in the application.
Expand Down
Loading