Introduction
A fintech company migrated from a monolithic application to microservices, expecting to improve scalability and development velocity. Security testing remained focused on the public-facing API. Internal service-to-service communication happened over a private network, so the team assumed it was safe. When an attacker compromised a low-priority notification service through a vulnerable dependency, they discovered that internal services trusted each other implicitly. The attacker pivoted through the network, accessing the payments service and exfiltrating transaction data—all without touching the hardened public API.
Microservices architectures multiply attack surfaces. Instead of one application to secure, organizations have dozens or hundreds of services. The boundaries between services become critical security points.
Microservices Attack Surface
- Service-to-Service Communication: Function calls become network requests, each a potential interception point
- Distributed Trust Boundaries: Services must authenticate and authorize each other; implicit trust enables lateral movement
- Configuration Sprawl: Each service may have its own configuration, secrets, and access controls
- Dependency Multiplication: A vulnerability in any service's dependencies can compromise the system
Testing Service Mesh Security
Service meshes like Istio provide infrastructure-level security. Test that controls work:
mTLS Enforcement: Verify mutual TLS is required:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICTTest by attempting unencrypted connections—they should fail with STRICT mTLS.
Authorization Policies: Verify only authorized services communicate:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: payment-service-authz
spec:
selector:
matchLabels:
app: payment-service
rules:
- from:
- source:
principals: ["cluster.local/ns/production/sa/order-service"]
to:
- operation:
methods: ["POST"]
paths: ["/api/payments"]Test by attempting unauthorized access from other services.
Testing Inter-Service Authentication
Even without a service mesh, services should authenticate each other:
# Test service-to-service JWT validation
def test_service_authentication():
# Valid token
valid_token = create_service_token("order-service", "payment-service")
response = requests.post(url, headers={"Authorization": f"Bearer {valid_token}"})
assert response.status_code == 201
# Forged token should fail
forged_token = create_token_with_attacker_key("malicious-service")
response = requests.post(url, headers={"Authorization": f"Bearer {forged_token}"})
assert response.status_code == 401Testing Authorization Between Services
Verify services only access what they need:
def test_service_authorization():
token = get_service_token("order-service")
# Should succeed
response = requests.post("/api/payments", headers={"Authorization": f"Bearer {token}"})
assert response.status_code == 201
# Should fail - order-service shouldn't have refund permissions
response = requests.post("/api/refunds", headers={"Authorization": f"Bearer {token}"})
assert response.status_code == 403Testing Network Policies
Kubernetes Network Policies control pod communication:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes: [Ingress]Test that unpermitted traffic is blocked and egress restrictions prevent data exfiltration.
Testing Container Security
# Check for dangerous capabilities
kubectl exec -it pod-name -- capsh --print
# Check if container runs as root
kubectl exec -it pod-name -- id
# Scan images for vulnerabilities
trivy image payment-service:latestTesting Secrets Management
# Check environment variables (secrets shouldn't be here)
kubectl exec -it pod-name -- env | grep -i password
# Check secret mount permissions
kubectl exec -it pod-name -- ls -la /secrets/Verify services only access secrets they need and handle rotation gracefully.
Observability and Detection
Use distributed tracing to correlate requests across services. Test that security events are captured—trigger authentication failures and verify alerts are generated.
Conclusion
Microservices security testing requires covering service mesh configurations, inter-service authentication, authorization policies, container security, and network controls. Manual testing of distributed systems is time-consuming and error-prone.
On-demand security testing helps teams validate that microservices architectures are properly secured, identifying misconfigurations and trust boundary violations across complex systems. RedVeil's AI-powered platform can assess your microservices alongside traditional applications, providing verified findings across your distributed architecture.
Start testing your microservices security with RedVeil today.