This article applies to: Self-Hosted

The pglombardo/pwpush-public-gateway container is a feature-limited version of the full pglombardo/pwpush container, designed to be hosted publicly and only deliver pushes to end users while keeping your internal infrastructure secure.

Overview

The public gateway container implements feature segmentation - a security strategy that reduces the attack surface by limiting functionality to only what’s needed for push delivery. This allows you to:

  • Host publicly: Deploy the gateway container in a public-facing environment (cloud, DMZ, etc.)
  • Keep internal: Run the full application container internally for your team
  • Share database: Both containers connect to the same database
  • Reduce risk: Limit what attackers can access if the public gateway is compromised

Use Cases

The public gateway is ideal for organizations that:

  • Need to share pushes with external users (customers, partners, vendors)
  • Want to isolate public-facing infrastructure from internal systems
  • Require enhanced security through feature segmentation
  • Need to scale public push delivery independently from internal operations

What’s Included vs Excluded

✅ Included (Public Gateway can do):

  • View push contents (passwords, text, URLs, files)
  • Access passphrase-protected pushes
  • Delete/expire pushes (if enabled)
  • Health check endpoint (/up)

❌ Excluded (Public Gateway cannot do):

  • Create new pushes
  • User login and registration
  • Administration dashboard (/admin)
  • API endpoints
  • File uploads
  • Push management features
  • Configuration changes

Note: The public gateway returns a 404 error for the root path (/) and other non-push routes. Users must access pushes via their secret URLs (e.g., https://gateway.example.com/p/abc123).

Benefits

  1. Improved Security: By hosting the public-facing push gateway in a separate container, you reduce the attack surface of your internal infrastructure. Even if the public gateway is compromised, attackers cannot:
    • Create new pushes
    • Access the admin dashboard
    • Use the API
    • Register new users
    • Modify application configuration
  2. Network Segmentation: Isolate public-facing components from internal systems, making it more difficult for attackers to move laterally into your internal network.

  3. Flexibility: The public gateway can be hosted in a public cloud, on-premises DMZ, or hybrid environment, giving you deployment flexibility.

  4. Scalability: Scale the public gateway independently to handle increased external traffic without affecting internal system performance.

  5. Compliance: Helps meet security requirements for separating public and internal infrastructure.

Security Considerations

The pglombardo/pwpush-public-gateway container employs feature segmentation, a well-established security strategy that reduces the attack surface by dividing a system into isolated segments. This approach is commonly used in networking, services, and applications to prevent unauthorized access, lateral movement and limit the spread of malware.

The concept of segmentation is not new, and numerous papers and resources have been published on the topic. For example:

  1. Design Secure Network Segmentation Approach - SANS Institute 2021
  2. Secure Network Design: Micro Segmentation - SANS Institute 2021
  3. Implement Network Segmentation and Encryption in Cloud Environments - NSA 2024

The pglombardo/pwpush-public-gateway container is an additional layer of security for your organization, helping to protect against potential threats and vulnerabilities.

Deployment Architecture

The public gateway container (pglombardo/pwpush-public-gateway) is designed to be hosted externally, facing your end users, while the full application container (pglombardo/pwpush) is hosted internally for your team’s use.

Architecture Diagram

The following diagram illustrates a typical deployment:

Download .drawio File

Typical Deployment Flow

  1. Internal Team uses the full pglombardo/pwpush container to create pushes
  2. Pushes are stored in a shared database (PostgreSQL or SQLite3 with shared volume)
  3. External users receive push URLs pointing to the public gateway
  4. Public gateway (pglombardo/pwpush-public-gateway) serves push content to external users
  5. Both containers read from the same database to access push data

Configuration

Environment Variables

Important: Except for PWP__OVERRIDE_BASE_URL, the public gateway container should use the same configuration as your internal pwpush container. This ensures both containers connect to the same database and have consistent application settings.

Required Configuration

Both containers must share:

  • Database connection (DATABASE_URL) - Same database for both containers
  • Encryption key (PWPUSH_MASTER_KEY) - Same key to decrypt push data
  • Application settings - Same settings.yml or environment variables

Public Gateway Specific

The public gateway container should set:

PWP__OVERRIDE_BASE_URL: 'https://gateway.example.com'

This ensures push URLs generated by the internal container point to the public gateway URL.

Docker Compose Example

Here’s an example docker-compose.yml for a dual-container setup:

services:
  # Internal full application (for your team)
  pwpush-internal:
    image: docker.io/pglombardo/pwpush:stable
    restart: unless-stopped
    environment:
      DATABASE_URL: postgres://pwpush_user:pwpush_passwd@postgres:5432/pwpush_db
      PWPUSH_MASTER_KEY: 'your-encryption-key-here'
      PWP__OVERRIDE_BASE_URL: 'https://gateway.example.com'
      # ... other configuration ...
    depends_on:
      - postgres

  # Public gateway (for external users)
  pwpush-gateway:
    image: docker.io/pglombardo/pwpush-public-gateway:stable
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    environment:
      DATABASE_URL: postgres://pwpush_user:pwpush_passwd@postgres:5432/pwpush_db
      PWPUSH_MASTER_KEY: 'your-encryption-key-here'
      PWP__OVERRIDE_BASE_URL: 'https://gateway.example.com'
      TLS_DOMAIN: 'gateway.example.com'
      # ... same configuration as internal container ...

  # Shared database
  postgres:
    image: postgres:15
    environment:
      POSTGRES_USER: pwpush_user
      POSTGRES_PASSWORD: pwpush_passwd
      POSTGRES_DB: pwpush_db
    volumes:
      - postgres-data:/var/lib/postgresql/data

volumes:
  postgres-data:

Note: In this example, the internal container doesn’t expose ports externally. Access it through your internal network or VPN.

Database Configuration

Both containers must connect to the same database to share push data. You have two options:

PostgreSQL is the recommended database for public gateway deployments because:

  • Multiple containers can easily connect to the same database
  • Better performance for concurrent access
  • No file system sharing required
  • Supports distributed deployments

Simply set the same DATABASE_URL for both containers:

# Both containers use the same DATABASE_URL
DATABASE_URL: postgres://pwpush_user:pwpush_passwd@postgres:5432/pwpush_db

SQLite3 with Shared Volume

If using SQLite3, both containers must share the same database file via a Docker volume:

services:
  pwpush-internal:
    image: docker.io/pglombardo/pwpush:stable
    volumes:
      - shared-db:/opt/PasswordPusher/db
    environment:
      DATABASE_URL: sqlite3:///opt/PasswordPusher/db/production.sqlite3

  pwpush-gateway:
    image: docker.io/pglombardo/pwpush-public-gateway:stable
    volumes:
      - shared-db:/opt/PasswordPusher/db
    environment:
      DATABASE_URL: sqlite3:///opt/PasswordPusher/db/production.sqlite3

volumes:
  shared-db:

Warning: SQLite3 has limitations with concurrent writes. For production deployments with the public gateway, PostgreSQL is strongly recommended.

Best Practices

Version Management

Always use the same Docker tag for both containers to ensure compatibility:

pwpush-internal:
  image: docker.io/pglombardo/pwpush:stable  # Use same tag

pwpush-gateway:
  image: docker.io/pglombardo/pwpush-public-gateway:stable  # Use same tag

Configuration Synchronization

Both containers should use the same configuration:

  • Same settings.yml file (if using custom file) OR
  • Same environment variables
  • Same DATABASE_URL
  • Same PWPUSH_MASTER_KEY
  • Same application settings

Exception: PWP__OVERRIDE_BASE_URL should point to the public gateway URL in both containers.

Security Hardening

  1. Network isolation: Keep the internal container on a private network
  2. Firewall rules: Only expose the public gateway ports (80/443) externally
  3. TLS/SSL: Always use HTTPS for the public gateway (TLS_DOMAIN)
  4. Secrets management: Use Docker secrets or external secret management for keys
  5. Regular updates: Keep both containers updated to the same version

Monitoring

  • Monitor both containers independently
  • Set up alerts for container health
  • Monitor database connection status
  • Track push delivery success rates

Troubleshooting

Common Issues

Pushes not accessible via public gateway:

  • Verify both containers connect to the same database
  • Check that PWP__OVERRIDE_BASE_URL is set correctly
  • Ensure the encryption key (PWPUSH_MASTER_KEY) is identical in both containers
  • Verify the push URL points to the public gateway domain

Users getting logged out:

  • Set SECRET_KEY_BASE to the same value in both containers
  • This ensures session cookies remain valid across both containers

Database connection errors:

  • For PostgreSQL: Verify network connectivity between containers
  • For SQLite3: Check volume mount permissions and ensure the volume is shared
  • Verify DATABASE_URL is identical in both containers

Version mismatches:

  • Ensure both containers use the same Docker tag (e.g., both :stable or both :v1.44.0)
  • Different versions may have incompatible database schemas or features

Configuration differences:

  • Compare environment variables between containers
  • Ensure all application settings match (except PWP__OVERRIDE_BASE_URL)

Docker Images

Both images support the same tags (stable, latest, vX.X.X). Always use matching tags for both containers.

See Also

Updated: