Sign inSign up

cohandv/port-authorizing

By cohandv

•Updated 11 months ago

Secure proxy for any service with authentication, authorization, and audit logging

Image
Networking
Security
1

3.1K

cohandv/port-authorizing repository overview

⁠Port Authorizing

📦 Docker Hub | 🔗 GitHub Repository⁠ | 📖 Documentation⁠ | 🐛 Issues⁠ | 🚀 Releases⁠

Secure proxy for any service with authentication, authorization, and audit logging.

Port Authorizing provides time-limited, audited access to any service (PostgreSQL, HTTP, TCP) with centralized authentication (OIDC/LDAP/SAML2), role-based access control, and protocol-specific filtering.

⁠📊 Protocol Maturity

ProtocolStatusFeatures
PostgreSQL✅ MatureFull authentication, query whitelisting, username validation, audit logging
HTTP/HTTPS✅ MatureTransparent proxying, authentication, full request/response handling
TCP🚧 BetaBasic proxying with authentication, limited protocol awareness

⁠🚀 Quick Start

⁠Run Server
docker run -d \
  -p 8080:8080 \
  -v $(pwd)/config.yaml:/app/config.yaml \
  --name port-authorizing \
  cohandv/port-authorizing:latest
⁠Verify Server
curl http://localhost:8080/api/health
⁠Use as Client

The Docker image can also be used as a CLI client:

# Login to server
docker run --rm -v ~/.port-auth:/home/portauth/.port-auth \
  cohandv/port-authorizing:latest \
  login -u admin -p password --api-url http://your-server:8080

# List available connections
docker run --rm -v ~/.port-auth:/home/portauth/.port-auth \
  cohandv/port-authorizing:latest \
  list --api-url http://your-server:8080

# Check version
docker run --rm cohandv/port-authorizing:latest --version

Note: Client mode requires network access to your Port Authorizing server and volume mount for storing the auth token.

⁠🐳 Docker Compose

version: '3.8'

services:
  port-authorizing:
    image: cohandv/port-authorizing:latest
    ports:
      - "8080:8080"
    volumes:
      - ./config.yaml:/app/config.yaml
      - ./data:/app/data
      - ./logs:/app/logs
    environment:
      - JWT_SECRET=${JWT_SECRET}
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/api/health"]
      interval: 30s
      timeout: 3s
      retries: 3

⁠📦 Available Tags

TagDescription
latestLatest stable release from main branch
v2.0.0Specific version (semantic versioning)
mainLatest build from main branch (development)

⁠🏗️ Multi-Architecture Support

Images are available for:

  • linux/amd64 (x86_64)
  • linux/arm64 (ARM64 / Apple Silicon)

Docker will automatically pull the correct architecture.

⁠⚙️ Configuration

⁠Minimum Config (config.yaml)
server:
  port: 8080

auth:
  jwt_secret: "change-this-secret"

  # Local users
  users:
    - username: admin
      password: admin123
      roles: [admin]

connections:
  - name: postgres-prod
    type: postgres
    host: postgres.internal
    port: 5432
    backend_username: app_user
    backend_password: app_pass
    tags:
      - env:production

policies:
  - name: admin-full
    roles: [admin]
    tags: [env:production]
    whitelist: [".*"]
⁠Environment Variables

Override config values with environment variables:

docker run -d \
  -p 8080:8080 \
  -v $(pwd)/config.yaml:/app/config.yaml \
  -e JWT_SECRET=your-secret-key \
  -e SERVER_PORT=8080 \
  cohandv/port-authorizing:latest

⁠🔐 OIDC Authentication (Keycloak)

auth:
  providers:
    - name: keycloak
      type: oidc
      enabled: true
      config:
        issuer: "https://keycloak.example.com/realms/myapp"
        client_id: "port-authorizing"
        client_secret: "${KEYCLOAK_CLIENT_SECRET}"
        redirect_url: "https://api.example.com/api/auth/oidc/callback"
        roles_claim: "roles"
        username_claim: "preferred_username"

⁠📖 Usage Examples

⁠1. Complete Stack with PostgreSQL
version: '3.8'

services:
  postgres:
    image: postgres:14
    environment:
      POSTGRES_PASSWORD: dbpass

  port-authorizing:
    image: cohandv/port-authorizing:latest
    ports:
      - "8080:8080"
    volumes:
      - ./config.yaml:/app/config.yaml
    depends_on:
      - postgres
⁠2. With Keycloak
version: '3.8'

services:
  keycloak:
    image: quay.io/keycloak/keycloak:23.0
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
    ports:
      - "8180:8080"
    command: start-dev

  port-authorizing:
    image: cohandv/port-authorizing:latest
    ports:
      - "8080:8080"
    volumes:
      - ./config.yaml:/app/config.yaml
    depends_on:
      - keycloak
⁠3. Client Usage

The same image can run as a client:

# Login (opens browser for OIDC)
docker run --rm -it \
  --network host \
  -v ~/.port-auth:/root/.port-auth \
  cohandv/port-authorizing:latest \
  login --api-url http://localhost:8080

# List connections
docker run --rm -it \
  --network host \
  -v ~/.port-auth:/root/.port-auth \
  cohandv/port-authorizing:latest \
  list --api-url http://localhost:8080

# Connect to service (PostgreSQL example)
docker run --rm -it \
  --network host \
  -v ~/.port-auth:/root/.port-auth \
  cohandv/port-authorizing:latest \
  connect postgres-prod -l 5433 --api-url http://localhost:8080

Or install the binary locally:

# Extract binary from image
docker create --name temp cohandv/port-authorizing:latest
docker cp temp:/usr/local/bin/port-authorizing ./port-authorizing
docker rm temp

# Use locally
./port-authorizing login
./port-authorizing connect postgres-prod -l 5433

⁠🔒 Security Features

  • ✅ Multi-provider authentication - OIDC, LDAP, SAML2, local users
  • ✅ Role-based access control - Different permissions per role
  • ✅ Query whitelisting - Regex-based SQL filtering
  • ✅ Credential hiding - Users never see backend passwords
  • ✅ Time-limited access - Connections expire automatically
  • ✅ Full audit logging - Every action logged with user identity
  • ✅ Username enforcement - Prevents user impersonation

⁠📊 Common Use Cases

⁠Temporary Production Database Access

Give developers read-only access to production for debugging:

policies:
  - name: developer-readonly-prod
    roles: [developer]
    tags: [env:production]
    whitelist:
      - "^SELECT.*"
      - "^EXPLAIN.*"

Connect:

# Developer logs in via OIDC
port-authorizing login

# Gets 30-minute connection to prod
port-authorizing connect postgres-prod -l 5433

# Can only run SELECT queries
psql -h localhost -p 5433 -U alice -d myapp
⁠Different Access Per Environment
policies:
  # Full access to test
  - name: dev-full-test
    roles: [developer]
    tags: [env:test]
    whitelist: [".*"]

  # Read-only in production
  - name: dev-readonly-prod
    roles: [developer]
    tags: [env:production]
    whitelist: ["^SELECT.*"]
⁠Audit All Database Access

All queries are logged with user identity:

{
  "timestamp": "2025-10-04T15:30:00Z",
  "username": "alice",
  "action": "postgres_query",
  "resource": "postgres-prod",
  "metadata": {
    "query": "SELECT * FROM users WHERE id = 1",
    "allowed": true,
    "connection_id": "abc123"
  }
}

⁠🔧 Configuration Reference

⁠Server Settings
server:
  port: 8080                        # API port
  max_connection_duration: 2h       # Max connection time
⁠Logging
logging:
  audit_log_path: "/app/logs/audit.log"  # Audit log location
  enable_llm_analysis: false              # Optional LLM analysis
⁠Connections
connections:
  - name: postgres-prod              # Connection name
    type: postgres                    # Type: postgres, http, tcp
    host: db.internal                 # Backend host
    port: 5432                        # Backend port
    duration: 30m                     # Connection timeout
    tags:                             # Tags for policy matching
      - env:production
      - team:platform
    backend_username: app_user        # Real DB credentials
    backend_password: "${DB_PASS}"    # From environment
    backend_database: myapp

⁠📝 Health Check

The container includes a built-in health check:

docker inspect --format='{{.State.Health.Status}}' port-authorizing

Manual check:

curl http://localhost:8080/api/health
# Response: {"status":"healthy"}

⁠🐛 Troubleshooting

⁠Container won't start
# Check logs
docker logs port-authorizing

# Common issues:
# - Invalid config.yaml
# - Port 8080 already in use
# - Missing volume mounts
⁠Can't connect to backend database
# Test from container
docker exec port-authorizing wget -O- http://backend-db:5432

# Check network
docker network inspect bridge
⁠Authentication fails
# Verify OIDC configuration
curl http://localhost:8080/api/health

# Check issuer is reachable
curl https://keycloak.example.com/realms/myapp/.well-known/openid-configuration

⁠📚 Full Documentation

⁠📄 License

[Your License]

⁠🤝 Contributing

Issues and PRs welcome! See GitHub repository⁠

⁠💬 Support


Image Size: ~30MB (Alpine-based) Base Image: alpine:latest Build: Multi-stage with Go 1.21 Security: Runs as non-root user

Tag summary

Content type

Image

Digest

sha256:d6f2ae50c…

Size

17.8 MB

Last updated

11 months ago

docker pull cohandv/port-authorizing