Installation and Setup
This guide walks you through installing and configuring the Portal Connect Agent.
Overview
Installing Portal Connect involves:
- Generating a client mTLS certificate for authentication
- Creating a configuration file with your routes
- Deploying the Agent container
- Verifying the connection and registration
Time to complete: 15-30 minutes
Before You Begin
Ensure you have completed the prerequisites:
- Docker installed and running
- Internal service URLs identified
- Network access verified
Step 1: Generate mTLS Certificates
Portal Connect uses mTLS for secure authentication. Generate your client certificate using the Agent's built-in tool.
Pull the Agent Image
First, obtain the Portal Connect Agent Docker image:
docker pull \
europe-west1-docker.pkg.dev/spc-global-admin/spotify-portal-connect/portal-connect-agent:latest
Generate Certificates
Run the certificate generation command:
# Create a directory for certificates
mkdir -p ./certs
# Generate certificates
docker run --rm \
-v $(pwd)/certs:/tmp/certs \
europe-west1-docker.pkg.dev/spc-global-admin/spotify-portal-connect/portal-connect-agent:latest \
--generate-cert
This creates two files in the ./certs directory:
portal-connect-client-<timestamp>.crt- Client certificate (public)portal-connect-client-<timestamp>.key- Private key (private)
Secure Your Private Key
Set appropriate permissions on the private key:
chmod 400 ./certs/portal-connect-client-<timestamp>.key
Never share or commit the portal-connect-client-<timestamp>.key file. Treat it as a secret.
Register Your Certificate with Spotify
Visit the Support Center and submit a new ticket asking to register your Portal Connect certificate. Under Attachments, upload your portal-connect-client-<timestamp>.crt file (public certificate only). Spotify will use this file to register your certificate. Note that the private key should never leave your infrastructure.
Certificates are valid for only 180 days. Repeat step 1 before the certificate expires, delivering the new certificate to Spotify first, before deploying the new key and certificate to your agents.
Step 2: Create Configuration File
Create a YAML configuration file named app-config.yaml:
Basic Configuration
agent:
# WebSocket URL (provided by Spotify)
brokerUrl: wss://broker.${subdomain}.spotifyportal.com
# Routes to external services
routes:
- https://api.github.com/*
- https://internal-api.company.com/v1/*
# mTLS authentication
mtls:
clientCertPath: /certs/portal-connect-client-<timestamp>.crt
clientKeyPath: /certs/portal-connect-client-<timestamp>.key
Configuration with Headers
If your external services require authentication, add headers per route:
agent:
brokerUrl: wss://broker.${subdomain}.spotifyportal.com
routes:
'https://api.github.com/*':
headers:
authorization: 'Bearer ${GITHUB_TOKEN}'
'https://internal-api.company.com/v1/*':
headers:
x-api-key: '${INTERNAL_API_KEY}'
x-forwarded-by: 'portal-connect-agent'
mtls:
clientCertPath: /certs/portal-connect-client-<timestamp>.crt
clientKeyPath: /certs/portal-connect-client-<timestamp>.key
- Reference environment variables with
${VAR_NAME} - For file-based secrets, use
${VAR_NAME_FILE}to read from a file path
Configuration File Location
Save the app-config.yaml file in a secure location accessible to Docker:
./portal-connect/
├── app-config.yaml
└── certs/
├── portal-connect-client-<timestamp>.crt
└── portal-connect-client-<timestamp>.key
Step 3: Deploy the Agent
You can deploy the Agent using Docker run, Docker Compose, or orchestration platforms like Kubernetes.
Option A: Docker Run
Deploy using a simple docker run command:
docker run -d \
--name portal-connect-agent \
-v $(pwd)/app-config.yaml:/app/config/app-config.yaml:ro \
-v $(pwd)/certs:/certs:ro \
-e CONFIG_PATH=/app/config/app-config.yaml \
-e GITHUB_TOKEN="your-github-token" \
-e INTERNAL_API_KEY="your-api-key" \
-p 9466:9466 \
--restart unless-stopped \
europe-west1-docker.pkg.dev/spc-global-admin/spotify-portal-connect/portal-connect-agent:latest
Parameters explained:
--name- Container name for easy reference-v- Mount configuration file and certificates (read-only)-e CONFIG_PATH- Path to configuration file inside container-e GITHUB_TOKEN- Environment variable for token substitution-p 9466:9466- Expose metrics port (optional)--restart unless-stopped- Automatic restart policy
Option B: Docker Compose
Create a docker-compose.yml file:
version: '3.8'
services:
portal-connect-agent:
image: europe-west1-docker.pkg.dev/spc-global-admin/spotify-portal-connect/portal-connect-agent:latest
container_name: portal-connect-agent
restart: unless-stopped
volumes:
- ./app-config.yaml:/app/config/app-config.yaml:ro
- ./certs:/certs:ro
environment:
- CONFIG_PATH=/app/config/app-config.yaml
- GITHUB_TOKEN=${GITHUB_TOKEN}
- INTERNAL_API_KEY=${INTERNAL_API_KEY}
ports:
- '9466:9466'
Create a .env file for environment variables:
GITHUB_TOKEN=your-github-token
INTERNAL_API_KEY=your-api-key
Deploy with Docker Compose:
docker-compose up -d
Option C: Kubernetes
Create a Kubernetes deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: portal-connect-agent
spec:
replicas: 1
selector:
matchLabels:
app: portal-connect-agent
template:
metadata:
labels:
app: portal-connect-agent
spec:
containers:
- name: agent
image: europe-west1-docker.pkg.dev/spc-global-admin/spotify-portal-connect/portal-connect-agent:latest
env:
- name: CONFIG_PATH
value: /app/config/app-config.yaml
- name: GITHUB_TOKEN
valueFrom:
secretKeyRef:
name: portal-connect-secrets
key: github-token
volumeMounts:
- name: config
mountPath: /app/config
readOnly: true
- name: certs
mountPath: /certs
readOnly: true
ports:
- containerPort: 9466
name: metrics
volumes:
- name: config
configMap:
name: portal-connect-config
- name: certs
secret:
secretName: portal-connect-certs
Create the ConfigMap and Secrets:
# Create ConfigMap for configuration
kubectl create configmap portal-connect-config \
--from-file=app-config.yaml=./app-config.yaml
# Create Secret for certificates
kubectl create secret generic portal-connect-certs \
--from-file=portal-connect-client-<timestamp>.crt=./certs/portal-connect-client-<timestamp>.crt \
--from-file=portal-connect-client-<timestamp>.key=./certs/portal-connect-client-<timestamp>.key
# Create Secret for API credentials
kubectl create secret generic portal-connect-secrets \
--from-literal=github-token='your-github-token' \
--from-literal=internal-api-key='your-api-key'
# Deploy
kubectl apply -f deployment.yaml
Step 4: Verify the Deployment
Check Agent Logs
View the Agent logs to confirm successful startup:
# Docker
docker logs portal-connect-agent
# Docker Compose
docker-compose logs -f portal-connect-agent
# Kubernetes
kubectl logs -f deployment/portal-connect-agent
Expected log messages:
Agent starting...
Loading configuration from /app/config/app-config.yaml
Validating mTLS certificates...
mTLS certificates validated successfully
Connecting to broker at wss://broker.${subdomain}.spotifyportal.com
WebSocket connected
Registering routes...
Registration completed successfully
Check Metrics
Query the metrics endpoint to verify the Agent is healthy:
curl http://localhost:9466/metrics
Look for metrics indicating:
- WebSocket connection state:
agent_websocket_connected{} 1 - Registered routes count
- No connection errors
Troubleshooting Installation
Certificate Validation Fails
Error message: mTLS certificate validation failed
Solutions:
- Verify certificate files exist at the specified paths
- Check file permissions (should be readable by container user)
- Ensure certificates are valid and not expired
- Verify certificates are in PEM format
Cannot Connect to Broker
Error message: Failed to connect to broker or WebSocket connection failed
Solutions:
- Verify broker URL is correct in configuration
- Check network connectivity to the broker URL
- Ensure firewall allows outbound WSS connections (the Agent only needs outbound access)
- Verify client certificate is registered with Spotify
- Check that your Portal instance is operational (contact Spotify support)
This is an outbound connection from the Agent. You should NOT need to configure any inbound firewall rules.
Configuration File Not Found
Error message: Configuration file not found or ENOENT
Solutions:
- Verify volume mount path is correct
- Check
CONFIG_PATHenvironment variable matches mounted path - Ensure configuration file has correct filename
- Check file permissions allow read access
Container Exits Immediately
Solutions:
- Check logs:
docker logs portal-connect-agent - Verify configuration file syntax:
docker run --rm -v $(pwd)/app-config.yaml:/config.yaml <image> --validate-config /config.yaml - Check all required environment variables are set
- Ensure certificates are mounted correctly