Zero-Trust Architecture
Status: Complete
Category: Security
Default enforcement: Soft
Author: PushBackLog team
Tags
- Topic: security, architecture
- Skillset: backend, devops
- Technology: generic
- Stage: planning, execution, review
Summary
Zero-trust is a security architecture principle: no user, device, or service is implicitly trusted solely because it is inside the network perimeter. Every request must be authenticated, authorised, and validated regardless of its origin — whether it comes from the public internet, a corporate network, or another internal service. Zero-trust removes the assumption that being “inside” the perimeter is a meaningful security boundary, which it is not in cloud environments, remote work contexts, or after a perimeter breach.
Rationale
The network perimeter no longer exists
Traditional security architecture treated the corporate network boundary as a trust boundary: traffic inside the firewall is trusted; traffic outside is hostile. This model fails in several ways in modern environments:
- Cloud infrastructure has no “inside” — services communicate over the public internet with encryption
- Remote workers operate from networks outside any perimeter
- Third-party contractors and managed services operate from outside the perimeter with legitimate access needs
- A perimeter breach — a compromised internal machine, a stolen VPN credential — gives an attacker trusted internal access
The 2020 SolarWinds attack exploited implicit internal trust: an attacker with lateral access to internal systems was trusted because they were “inside”. Zero-trust would not have prevented the initial compromise, but it limits lateral movement and the blast radius of a breach.
Identity is the new perimeter
In a zero-trust model, identity replaces network location as the primary trust signal. Every service, user, and device must prove its identity on every request. Access is granted based on verified identity, device health, and resource sensitivity — not on which network the request originates from.
Guidance
Core zero-trust principles
| Principle | Implementation |
|---|---|
| Verify explicitly | Every request must present a verified credential — no implicit trust from network location |
| Use least-privilege access | Grant only the minimum permissions needed for the specific task |
| Assume breach | Design systems as if the network is already compromised; limit blast radius |
| Inspect and log all traffic | All traffic — internal and external — is logged for audit and anomaly detection |
| Re-verify continuously | Do not grant long-lived implicit trust; re-authenticate and re-authorise at session boundaries |
Service-to-service authentication
Internal services must authenticate to each other — not trust each other based on being on the same network or subnet.
// Each service presents a signed JWT when calling another service
// The receiving service validates the token — same validation as for user-facing APIs
async function callInventoryService(orderId: string): Promise<InventoryStatus> {
const serviceToken = await serviceIdentity.getSignedToken({
subject: 'order-service',
audience: 'inventory-service',
ttl: 300, // Short-lived
});
return fetch(`${INVENTORY_SERVICE_URL}/inventory/${orderId}`, {
headers: { Authorization: `Bearer ${serviceToken}` },
}).then(r => r.json());
}
Options for service-to-service identity:
- mTLS (mutual TLS) — each service presents a certificate; the receiving service validates it (zero-trust infrastructure level, managed by a service mesh like Istio or Linkerd)
- Short-lived JWT tokens from an internal identity provider (SPIFFE/SPIRE)
- Cloud IAM roles — in AWS, services use IAM roles; requests are signed with AWS Signature V4
Network segmentation and micro-segmentation
Replace flat network access with network policies that allow only the specific communication paths required:
# Kubernetes NetworkPolicy — order-service can only talk to inventory-service
# and the database. No other internal traffic allowed.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: order-service-egress
spec:
podSelector:
matchLabels: { app: order-service }
policyTypes: [Egress]
egress:
- to:
- podSelector:
matchLabels: { app: inventory-service }
ports:
- port: 3000
- to:
- podSelector:
matchLabels: { app: postgres }
ports:
- port: 5432
Device trust
For end-user access to sensitive systems, verify not only the user’s identity but also whether the device is managed and meets health requirements:
- Require managed devices (enrolled in MDM) for access to production dashboards
- Use certificate-based device authentication alongside user credentials
- Use short-lived certificates rather than long-lived VPN credentials
Practical adoption path
Zero-trust is a journey, not a binary state. A pragmatic order of adoption:
- Enforce MFA everywhere — the highest-impact first step
- Replace VPN with identity-aware proxy (BeyondCorp model: Google IAP, Cloudflare Access, Tailscale)
- Implement service-to-service mTLS (service mesh or manual)
- Adopt short-lived credentials — eliminate long-lived service account keys
- Apply network micro-segmentation — restrict internal service communication to declared paths
- Continuous monitoring and anomaly detection — treat unusual internal traffic as suspicious
Review checklist
- No service is trusted solely because it shares a network segment
- Service-to-service calls use mutual authentication (mTLS or signed tokens)
- Users authenticate with MFA for any privileged or production access
- Network policies restrict internal traffic to declared service dependencies
- All service-to-service calls are logged and auditable
- Service credentials are short-lived and automatically rotated