Skip to content

Application Routing

The Productify Proxy uses custom Caddy plugins to route traffic to applications based on Manager configuration.

Overview

Application routing enables:

  • Manager Integration - Routes configured via Productify Manager
  • Application-Specific Middleware - Custom logic per application
  • Authentication Flow - OAuth2 before application access
  • Machine User Support - Bearer token validation for APIs

Productify Plugin

The custom productify Caddy plugin integrates with the Manager to route traffic.

Global Configuration

nginx
{
  productify {
    manager http://manager:8080
    token supersecrettoken
  }
}

Parameters:

  • manager - URL of the Productify Manager API
  • token - Authentication token for Manager API requests

Application Routing

nginx
route /* {
  authorize with pocketpolicy
  productify with 123
  reverse_proxy backend:8080
}

The productify with 123 directive:

  1. Validates the authenticated user
  2. Looks up application ID 123 in the Manager
  3. Applies application-specific routing logic
  4. Records metrics for the application

Authentication Integration

Before Authentication

Use productify_before_auth for pre-authentication logic:

nginx
route @auth {
  productify_before_auth with 123
  authenticate with pocketportal
}

This tracks users in the authentication flow.

After Authentication

Standard productify directive runs after authorization:

nginx
route /* {
  authorize with pocketpolicy
  productify with 123
  reverse_proxy backend:8080
}

Complete Example

nginx
{
  security {
    oauth identity provider generic {
      realm generic
      driver generic
      client_id ab098fe1-9bc0-4780-81c6-2ea17f49a3cb
      client_secret pU3ZrOyPTtd4A3ex16dBzBTlDrlxqfpU
      scopes openid email profile
      base_auth_url http://pocketid.localhost
      metadata_url http://pocketid.localhost/.well-known/openid-configuration
    }

    authentication portal pocketportal {
      crypto default token lifetime 3600
      enable identity provider generic
      cookie insecure on

      transform user {
        match realm generic
        action add role user
      }
    }

    authorization policy pocketpolicy {
      set auth url /auth/oauth2/generic
      allow roles user
      validate bearer header
      inject headers with claims
      enable strip token
    }
  }

  productify {
    manager http://172.17.0.1:8080
    token supersecrettoken
  }
}

http://app.localhost {
  @auth {
    path /auth/*
  }

  route @auth {
    productify_before_auth with 123
    authenticate with pocketportal
  }

  route /* {
    authorize with pocketpolicy
    productify with 123
    file_server {
      root /usr/share/caddy
      browse
    }
  }
}

Metrics

The Productify plugin exposes Prometheus metrics on port 2112:

Available Metrics

  • pfy_authentication_awaiting_users - Users currently on authentication page
  • pfy_total_requests - Total requests processed per application
  • pfy_response_time_seconds - Response time histogram per application

Query Metrics

bash
curl http://localhost:2112/metrics

Example output:

# HELP pfy_authentication_awating_users Currently on authentication page users
# TYPE pfy_authentication_awating_users gauge
pfy_authentication_awating_users{app="123"} 2

# HELP pfy_total_requests Total number of requests processed
# TYPE pfy_total_requests counter
pfy_total_requests{app="123"} 1543

# HELP pfy_response_time_seconds Response time in seconds
# TYPE pfy_response_time_seconds histogram
pfy_response_time_seconds_bucket{app="123",le="0.005"} 1234
pfy_response_time_seconds_bucket{app="123",le="0.01"} 1432

Manager API Integration

The proxy communicates with these Manager endpoints:

Application Lookup

GET /api/applications/{app_id}
Authorization: Bearer {token}

Returns application configuration and routing information.

Machine User Validation

POST /api/validate-machine-user
Authorization: Bearer {token}
Content-Type: application/json

{
  "token": "user-provided-token"
}

Validates bearer tokens for API access.

Multi-Application Setup

Different Applications

nginx
http://app1.localhost {
  route /* {
    authorize with pocketpolicy
    productify with 100
    reverse_proxy app1-backend:8080
  }
}

http://app2.localhost {
  route /* {
    authorize with pocketpolicy
    productify with 200
    reverse_proxy app2-backend:8080
  }
}

Path-Based Routing

nginx
http://apps.localhost {
  route /app1/* {
    authorize with pocketpolicy
    productify with 100
    uri strip_prefix /app1
    reverse_proxy app1-backend:8080
  }

  route /app2/* {
    authorize with pocketpolicy
    productify with 200
    uri strip_prefix /app2
    reverse_proxy app2-backend:8080
  }
}

See Also