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 APItoken- 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:
- Validates the authenticated user
- Looks up application ID
123in the Manager - Applies application-specific routing logic
- 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 pagepfy_total_requests- Total requests processed per applicationpfy_response_time_seconds- Response time histogram per application
Query Metrics
bash
curl http://localhost:2112/metricsExample 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"} 1432Manager 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
}
}