Security Model
Portal Connect Agent is a stateless proxy service that:
- Runs as a containerized application (Docker/Kubernetes)
- Establishes an outbound-only WebSocket connection to your Portal instance
- Proxies HTTP requests to internal services without storing data
- Authenticates using mutual TLS (mTLS) certificates
The Agent never listens for or accepts inbound connections, eliminating the inbound attack surface.
Transport Security
TLS Configuration
Protocol Version
- Uses Node.js 22 TLS defaults: TLS 1.2 and TLS 1.3
- TLS 1.3 preferred, with TLS 1.2 fallback for compatibility
- SSL 3.0, TLS 1.0, and TLS 1.1 explicitly disabled
WebSocket Security
- WebSocket Secure (WSS) over TLS for broker connection
- Enforces server certificate validation (
rejectUnauthorized: true) - Persistent connection with automatic reconnection and exponential backoff
Cipher Suites
- Uses Node.js 22 default cipher suite selection
- Prioritizes AEAD ciphers (AES-GCM, ChaCha20-Poly1305)
- Excludes weak ciphers (RC4, DES, 3DES, MD5)
- Forward secrecy enabled via ECDHE/DHE key exchange
Connection Settings
- HTTP/HTTPS connection pooling with keep-alive
- 30-second request timeout (configurable)
- 10-second WebSocket connection timeout
- Automatic decompression disabled to preserve data integrity
Authentication and Authorization
Mutual TLS (mTLS)
Certificate Requirements
- Algorithm: RSA (2048-4096 bits) or ECDSA (P-256, P-384 curves)
- Format: PEM-encoded X.509 certificates
- Maximum Lifespan: 180 days (enforced at startup validation)
Certificate Validation
- Automatic validation on Agent startup
- Validates certificate expiry, lifespan, algorithm, key size, and extensions
- Warns when certificate expires within 7 days (configurable threshold)
- Fails fast if certificates are invalid, expired, or missing
Certificate Lifecycle
- Certificates generated using Agent's built-in tool (
--generate-cert) - Customer registers certificate with Spotify (public cert only, private key never leaves network)
- Manual rotation required before 180-day expiration
Key Management
- Private keys remain within customer network perimeter
- Recommended file permissions:
400or600(owner read-only) - File-based secrets supported via
${VAR_NAME_FILE}environment variable substitution - Keys loaded from filesystem at startup (paths:
clientCertPath,clientKeyPath)
Route-Based Access Control
Authorization Model
- Agent explicitly registers allowed routes (URL patterns) with Portal
- Portal only forwards requests matching registered routes to Agent
- Supports exact match and wildcard patterns (e.g.,
https://api.github.com/*) - Route headers can inject authentication credentials for downstream services
Credential Handling
- Service credentials (API keys, tokens) configured at Agent level
- Environment variable substitution prevents hardcoded secrets in config files
- Credentials injected into outbound requests to internal services
- Portal never sees or stores internal service credentials
Data Handling and Privacy
Data in Transit
Encryption
- All data transmitted via TLS-encrypted WebSocket (WSS)
- Request and response bodies encrypted end-to-end between Portal and Agent
- Agent-to-internal-service connections use HTTPS where configured
- No cleartext transmission of sensitive data
Data Processing
- Agent operates as a stateless proxy - no persistent storage
- Requests and responses held in memory only during active processing
- Binary and compressed content preserved without decompression
- No caching of request or response data
Data Encoding
- UTF-8 encoding for text content
- Base64 encoding for binary and compressed content
- Automatic detection of content type and compression
- Preserves
Content-Encodingheaders for compressed responses
Data at Rest
Storage
- No persistent data storage - Agent is entirely stateless
- Configuration file stored on disk (contains routes, not credentials)
- Certificates stored on disk (required for mTLS)
- No request/response logging to disk (logged to stdout only)
Temporary Data
- Request/response buffers in memory during processing
- Memory cleared when processing completes or Agent restarts
- No swap or core dump file generation (depends on OS configuration)
Container Security
SBOM (Software Bill of Materials)
- Complete inventory of all packages, libraries, and dependencies in Docker images
- Generated automatically during CI/CD builds in SPDX JSON format using Anchore Syft
- Enables rapid vulnerability scanning - quickly identify if images contain packages with known CVEs
- Required for compliance with emerging regulations (NIST guidelines, EU Cyber Resilience Act)
- Stored as GitHub Actions artifacts and cryptographically signed attestations attached to images
- Use
cosign verify-attestationto view the SBOM of any deployed image - Critical for incident response: identify all affected images when a dependency vulnerability is disclosed
Image Signing
- All Docker images are cryptographically signed using Cosign (Sigstore) with key-based signing
- Provides proof of authenticity - verifies images were built by CI/CD pipeline and haven't been tampered with
- Prevents supply chain attacks: unauthorized or modified images fail signature verification
- Public key (
cosign.pub) is shared with teams for image verification before deployment - Signatures are stored alongside images in Google Artifact Registry
Base Image
Image Details
- Base:
node:22-alpine(Alpine Linux 3.x) - Official Node.js Docker images from Docker Hub
- SHA-256 digest pinning prevents tag mutation attacks
- Regular security updates applied via
apk upgrade --no-cache
User Configuration
- Runs as non-root user
- Minimal privileges
- File ownership set
- No sudo or privilege escalation capabilities
Container Hardening
Filesystem
- Configuration mounted read-only (
:roflag) - Certificates mounted read-only
- No write access to sensitive directories
- Application runs from
/appdirectory
Runtime Security
- No privileged mode required
- Minimal exposed ports: 9466 (metrics only, internal to network)
Network Security
Network Architecture
Outbound Connections
- Destination: Portal broker (e.g.,
wss://broker.${subdomain}.spotifyportal.com) - Protocol: WSS (WebSocket Secure over TLS)
- Port: 443 (HTTPS/WSS standard) or custom as configured
- Persistent connection maintained with heartbeat
- Connections to internal services as configured in routes
Inbound Connections
- None required for primary function - Agent never listens for connections
- Metrics endpoint (port 9466) accessible only within internal network
- No public internet exposure needed
Firewall Configuration
- Inbound: No changes required - Agent does not accept connections
- Outbound: Allow WSS to Portal broker URL
- Outbound: Allow HTTPS/HTTP to internal services in routes
This architecture ensures that your firewall configuration for incoming traffic remains unchanged, eliminating the inbound attack surface while still enabling Portal to access your internal services.