This guide covers Cloud Foundry's security features including security groups, network policies, SSH access control, and environment variable security.
Cloud Foundry provides multiple layers of security:
- Network Security - Security groups and network policies
- Access Control - SSH restrictions and authentication
- Data Protection - Environment variable encryption
- Audit Trail - Comprehensive event logging
- Isolation - Container and namespace separation
Security groups control outbound network traffic from applications and staging containers.
Define allowed outbound connections:
POST /v3/security_groups
{
"name": "public-networks",
"rules": [
{
"protocol": "tcp",
"destination": "0.0.0.0/0",
"ports": "443",
"description": "Allow HTTPS to any destination"
},
{
"protocol": "tcp",
"destination": "10.0.0.0/8",
"ports": "5432",
"description": "Allow PostgreSQL to internal network"
},
{
"protocol": "udp",
"destination": "8.8.8.8",
"ports": "53",
"description": "Allow DNS queries to Google DNS"
},
{
"protocol": "icmp",
"destination": "0.0.0.0/0",
"type": 8,
"code": 0,
"description": "Allow ICMP ping"
}
],
"metadata": {
"labels": {
"purpose": "public-access"
}
}
}
- protocol:
tcp
,udp
,icmp
, orall
- destination: IP address, CIDR range, or IP range
- ports: Single port, range (e.g., "8080-8090"), or comma-separated list
- type/code: For ICMP protocol only
- log: Enable logging (default: false)
- description: Human-readable description
// CIDR notation
{ "destination": "192.168.1.0/24" }
// IP range
{ "destination": "192.168.1.1-192.168.1.254" }
// Single IP
{ "destination": "192.168.1.1" }
// Multiple ports
{ "ports": "80,443,8080-8090" }
Applied during app staging:
# Bind globally (platform-wide)
POST /v3/security_groups/{guid}/relationships/staging_spaces
{
"data": []
}
Applied to running applications:
# Bind globally
POST /v3/security_groups/{guid}/relationships/running_spaces
{
"data": []
}
Bind to specific spaces:
# Staging
POST /v3/security_groups/{guid}/relationships/staging_spaces
{
"data": [
{ "guid": "space-guid-1" },
{ "guid": "space-guid-2" }
]
}
# Running
POST /v3/security_groups/{guid}/relationships/running_spaces
Cloud Foundry typically includes default groups:
- dns - Allow DNS resolution
- public_networks - Internet access
- private_networks - RFC1918 ranges (often restricted)
- Platform defaults (lowest priority)
- Organization security groups
- Space security groups (highest priority)
All rules are additive (allow-list based).
Network policies control app-to-app communication within Cloud Foundry.
Allow communication between apps:
POST /networking/v1/external/policies
{
"policies": [
{
"source": {
"id": "source-app-guid"
},
"destination": {
"id": "destination-app-guid",
"protocol": "tcp",
"ports": {
"start": 8080,
"end": 8080
}
}
}
]
}
- source.id: Source app GUID
- destination.id: Destination app GUID
- protocol:
tcp
orudp
- ports: Port range (start and end)
Enable internal communication:
- Apps must use internal routes
- Network policy must exist
- Apps discover each other via internal DNS
Example internal URL:
http://backend.apps.internal:8080
-
Microservices Communication
{ "policies": [{ "source": { "id": "frontend-app" }, "destination": { "id": "backend-api", "protocol": "tcp", "ports": { "start": 8080, "end": 8080 } } }] }
-
Database Access
{ "policies": [{ "source": { "id": "app-guid" }, "destination": { "id": "database-app-guid", "protocol": "tcp", "ports": { "start": 5432, "end": 5432 } } }] }
Control SSH access to application containers.
# Check SSH status
GET /v3/spaces/{guid}/features/ssh
# Enable/disable SSH
PATCH /v3/spaces/{guid}/features/ssh
{
"enabled": true
}
# Check app SSH status
GET /v3/apps/{guid}/features/ssh
# Enable/disable for specific app
PATCH /v3/apps/{guid}/features/ssh
{
"enabled": false
}
SSH must be enabled at all levels:
- Platform level (admin setting)
- Space level
- App level
If disabled at any level, SSH access is denied.
-
Disable by Default
- Enable only when needed
- Disable after troubleshooting
-
Audit SSH Sessions
- Monitor SSH access logs
- Track who accesses containers
-
Time-Limited Access
- Enable temporarily
- Automate disabling
Protect sensitive data in environment variables.
-
Never Store Secrets Directly
// DON'T DO THIS { "environment_variables": { "DATABASE_PASSWORD": "plaintext-password" } }
-
Use Service Bindings
- Credentials injected securely
- Rotatable through rebinding
- Automated by service brokers
-
Use CredHub Integration
{ "environment_variables": { "DATABASE_URL": "((database-url))" } }
Cloud Foundry reserves certain prefixes:
VCAP_*
- System use onlyCF_*
- Platform variablesPORT
- Assigned by platform
# Get app environment (requires SpaceDeveloper role)
GET /v3/apps/{guid}/env
Response includes:
- User-provided variables
- System environment variables
- Service credentials (VCAP_SERVICES)
-
Use Service Brokers
- Automated credential management
- Secure storage and rotation
-
External Secret Stores
- HashiCorp Vault
- AWS Secrets Manager
- Azure Key Vault
-
Credential Rotation
- Regular rotation schedule
- Automated through CI/CD
Track security-relevant activities.
GET /v3/audit_events
Key events to monitor:
-
Authentication Events
audit.user.login
audit.user.logout
audit.token.create
-
Authorization Events
audit.role.create
audit.role.delete
audit.permission.grant
-
Resource Access
audit.app.ssh-authorized
audit.app.environment_variables.view
audit.service_binding.create
-
Security Configuration
audit.security_group.create
audit.security_group.update
audit.network_policy.create
{
"guid": "event-guid",
"type": "audit.app.ssh-authorized",
"actor": {
"guid": "user-guid",
"type": "user",
"name": "[email protected]"
},
"target": {
"guid": "app-guid",
"type": "app",
"name": "production-api"
},
"data": {
"index": 0
},
"created_at": "2025-01-26T15:30:00Z"
}
- Default retention varies by deployment
- Export to external SIEM systems
- Implement long-term storage strategy
Each app instance runs in isolated containers:
- Separate namespaces
- Resource limits (CPU, memory)
- Restricted system calls
- Read-only root filesystem
During staging:
- Isolated build containers
- Time-limited execution
- Network restrictions
- No persistent storage
Running applications have:
- Minimal attack surface
- No root access
- Limited system capabilities
- Enforced resource quotas
Principle of Least Privilege
{
"rules": [
{
"protocol": "tcp",
"destination": "10.0.1.5",
"ports": "5432",
"description": "Only allow connection to specific database"
}
]
}
Deny by Default
- Start with no outbound access
- Add only required connections
- Document each rule purpose
Role-Based Access
- Assign minimum required roles
- Regular access reviews
- Remove unused permissions
Service Account Security
- Unique accounts per system
- Regular credential rotation
- Monitor usage patterns
Encryption in Transit
- Force HTTPS for all routes
- Use TLS for service connections
- Verify certificates
Secrets Management
- No hardcoded credentials
- Use platform secret services
- Implement rotation policies
Security Monitoring
# Monitor SSH access
GET /v3/audit_events?types=audit.app.ssh-authorized
# Track security group changes
GET /v3/audit_events?types=audit.security_group.update
# Monitor role assignments
GET /v3/audit_events?types=audit.role.create
Compliance Reporting
- Regular security audits
- Automated compliance checks
- Document security policies
Implement zero trust principles:
-
Verify Everything
- Authenticate all connections
- Authorize each request
- Encrypt all traffic
-
Microsegmentation
{ "policies": [{ "source": { "id": "frontend" }, "destination": { "id": "backend", "protocol": "tcp", "ports": { "start": 8080, "end": 8080 } } }] }
-
Continuous Verification
- Monitor all connections
- Detect anomalies
- Respond automatically
Automate security tasks:
#!/bin/bash
# Automated security group audit
# List all security groups
groups=$(cf curl /v3/security_groups | jq -r '.resources[].guid')
for group in $groups; do
# Check for overly permissive rules
rules=$(cf curl /v3/security_groups/$group | jq '.rules[]')
# Alert on 0.0.0.0/0 destinations
if echo "$rules" | grep -q '"destination":"0.0.0.0/0"'; then
echo "WARNING: Security group $group has unrestricted destination"
fi
done
Prepare for security incidents:
-
Detection
- Monitor audit logs
- Set up alerts
- Track anomalies
-
Response
- Isolate affected apps
- Revoke compromised credentials
- Update security groups
-
Recovery
- Restore from backups
- Apply security patches
- Update policies
- SSH disabled by default
- Minimal security group rules
- Network policies configured
- Secrets in service bindings
- Regular dependency updates
- Audit logging enabled
- Log forwarding configured
- Regular security updates
- Access reviews scheduled
- Incident response plan
- Security policies documented
- Regular security training
- Compliance audits scheduled
- Vulnerability scanning
- Penetration testing
-
Connection Blocked
- Check security groups
- Verify network policies
- Review destination IPs
-
SSH Access Denied
- Verify space SSH enabled
- Check app SSH setting
- Confirm user permissions
-
Audit Events Missing
- Check retention settings
- Verify permissions
- Ensure logging enabled
# Check effective security groups
GET /v3/spaces/{guid}/staging_security_groups
GET /v3/spaces/{guid}/running_security_groups
# Verify network policies
GET /networking/v1/external/policies?id=app-guid
# Review recent security events
GET /v3/audit_events?order_by=-created_at&types=audit.security_group
- Authentication Guide - User authentication and authorization
- Organizations & Spaces - Access control hierarchy
- Core Resources Guide - Application security settings