Zero Trust

Infrastructure & Governance Security Notes Jan 9, 2025 JAVASCRIPT
security architecture authentication authorization network-security

Definition

Zero Trust is a security architecture based on the principle “never trust, always verify.” Unlike traditional perimeter-based security (which assumes everything inside the corporate network is safe), Zero Trust assumes that threats exist both outside and inside the network. Every request for access - whether from a device in the office, a remote worker, or an internal microservice - must be authenticated, authorized, and continuously validated before being granted access to resources. Location, network, or previous authentication don’t grant implicit trust.

The philosophy emerged from the reality of modern computing: networks are flat, employees work remotely, applications run in the cloud, and attackers are inside the perimeter (via phishing, compromised credentials, or supply chain attacks). The old “castle-and-moat” model (hard perimeter, soft interior) is obsolete. Zero Trust instead builds security around identity and context - who is making the request, from what device, to access what resource, under what conditions. Every access decision is made dynamically based on risk assessment.

Zero Trust is not a single product or technology; it’s an architectural philosophy implemented through multiple technologies: multi-factor authentication (MFA), least-privilege access controls, microsegmentation, continuous monitoring, identity and access management (IAM), and device health verification. For APIs, this means every request must carry a valid, verified token (even from internal services), authorization checks happen on every operation, and all access is logged for audit and anomaly detection.

Example

Google BeyondCorp: Google implemented Zero Trust after the Aurora attacks. Every employee request - even from a Google office - must authenticate via MFA and pass device health checks. There’s no VPN or “trusted internal network.” Employees access internal tools (email, docs, code repos) via the internet using identity-based access controls. This enables work-from-anywhere while maintaining security.

Netflix Microservices: Netflix’s microservices don’t trust each other by default. Every service-to-service API call requires mutual TLS (mTLS) authentication. The billing service can’t call the payment service without proving its identity via certificates. This prevents lateral movement if one service is compromised.

Banking API: A bank’s mobile app makes API calls to check account balances. Even though the user authenticated at login, every API request includes a fresh JWT token. The API validates the token, checks if it’s expired, verifies the signature, and confirms the user still has permissions (account not frozen, user not deleted). Past authentication doesn’t grant future access.

Healthcare Records System: A doctor accessing patient records must authenticate with MFA, their device must pass security compliance checks (encrypted disk, up-to-date OS, no jailbreak), and access is granted only to patients they’re currently treating. If the doctor’s credentials are stolen, the attacker’s non-compliant device and unusual access patterns trigger blocks.

Cloud Infrastructure: AWS implements Zero Trust with IAM roles. An EC2 instance running your app doesn’t automatically have access to S3 buckets or databases. Each instance must assume an IAM role with explicitly granted permissions. Even if an attacker compromises the instance, they can’t access other resources without valid IAM credentials.

Analogy

The Museum Security System: Traditional security is like a museum with guards at the front door. Once you’re inside, you can wander anywhere. Zero Trust is like a museum where every room requires a badge swipe. Your badge is checked against the current access list for that specific room, and guards monitor cameras for suspicious behavior even if you have valid access.

The Airport vs. The Hotel: Traditional security is like a hotel - show ID at check-in, then roam freely. Zero Trust is like an airport - show ID at check-in, again at security, again at the gate, and again boarding the plane. Each checkpoint verifies your ticket and identity independently. Past verification doesn’t exempt you from future checks.

The Bank Vault with Compartments: Old security is one big vault with one lock. Zero Trust is a vault with individual safe deposit boxes, each requiring its own key. An employee with access to box 1 can’t open box 2 without the specific key. Even the bank manager needs explicit keys for each box.

The Hospital Badge System: Hospital staff wear badges with different colors and embedded chips. Each department (ER, pharmacy, operating rooms) has door readers that check the chip. A nurse’s badge might grant access to patient rooms but not the pharmacy. If a badge is stolen, it’s immediately deactivated remotely, and access logs help track where the thief went.

Code Example

// Zero Trust API implementation with multiple verification layers
import express from 'express';
import jwt from 'jsonwebtoken';
import { createHash } from 'crypto';

const app = express();

// Layer 1: TLS/mTLS enforcement
app.use((req, res, next) => {
  // Require HTTPS
  if (!req.secure && process.env.NODE_ENV === 'production') {
    return res.status(403).json({
      error: 'HTTPS required',
      message: 'All requests must use TLS encryption'
    });
  }

  // Verify client certificate (mTLS for service-to-service)
  if (req.path.startsWith('/internal/')) {
    const cert = req.socket.getPeerCertificate();
    if (!cert || !cert.subject) {
      return res.status(401).json({
        error: 'Client certificate required',
        message: 'Internal APIs require mutual TLS authentication'
      });
    }
    req.serviceName = cert.subject.CN; // Common Name identifies the service
  }

  next();
});

// Layer 2: Authentication - verify JWT token
async function authenticate(req, res, next) {
  const token = req.headers.authorization?.replace('Bearer ', '');

  if (!token) {
    return res.status(401).json({
      error: 'Authentication required',
      message: 'Missing or invalid authentication token'
    });
  }

  try {
    const decoded = jwt.verify(token, process.env.JWT_PUBLIC_KEY, {
      algorithms: ['RS256'],
      issuer: 'https://auth.company.com',
      audience: 'api.company.com'
    });

    // Check token is not revoked (Zero Trust: verify every time)
    const isRevoked = await checkTokenRevocation(decoded.jti);
    if (isRevoked) {
      return res.status(401).json({
        error: 'Token revoked',
        message: 'This token has been revoked'
      });
    }

    req.user = decoded;
    next();
  } catch (err) {
    return res.status(401).json({
      error: 'Invalid token',
      message: 'Token verification failed'
    });
  }
}

// Layer 3: Device Health Check (Zero Trust principle)
async function verifyDeviceHealth(req, res, next) {
  const deviceId = req.headers['x-device-id'];
  const deviceFingerprint = req.headers['x-device-fingerprint'];

  if (!deviceId || !deviceFingerprint) {
    return res.status(403).json({
      error: 'Device verification required',
      message: 'All requests must include device identification'
    });
  }

  // Check device compliance status
  const device = await getDeviceStatus(deviceId);

  if (!device) {
    return res.status(403).json({ error: 'Unknown device' });
  }

  if (device.status === 'compromised' || device.status === 'non_compliant') {
    await logSecurityEvent('blocked_non_compliant_device', {
      deviceId,
      userId: req.user.id,
      reason: device.status
    });

    return res.status(403).json({
      error: 'Device not compliant',
      message: 'Your device does not meet security requirements'
    });
  }

  req.device = device;
  next();
}

// Layer 4: Context-Aware Authorization
async function authorize(requiredPermissions) {
  return async (req, res, next) => {
    // Check user permissions
    const hasPermissions = requiredPermissions.every(p =>
      req.user.permissions.includes(p)
    );

    if (!hasPermissions) {
      return res.status(403).json({
        error: 'Insufficient permissions',
        required: requiredPermissions
      });
    }

    // Zero Trust: Check contextual risk factors
    const riskScore = await calculateRiskScore({
      userId: req.user.id,
      ip: req.ip,
      location: req.headers['x-geo-location'],
      device: req.device,
      time: new Date(),
      resource: req.path
    });

    // High risk requires step-up authentication
    if (riskScore > 75) {
      const hasRecentMFA = await checkRecentMFA(req.user.id);
      if (!hasRecentMFA) {
        return res.status(403).json({
          error: 'Step-up authentication required',
          message: 'High risk detected. Please re-authenticate with MFA.',
          challenge_url: '/api/auth/mfa-challenge'
        });
      }
    }

    // Log authorization decision for audit
    await logAccess({
      userId: req.user.id,
      resource: req.path,
      action: req.method,
      granted: true,
      riskScore,
      timestamp: new Date()
    });

    next();
  };
}

// Layer 5: Object-Level Authorization (never skip)
async function verifyResourceOwnership(req, res, next) {
  const resourceId = req.params.id;
  const resource = await db.findResource(resourceId);

  if (!resource) {
    return res.status(404).json({ error: 'Resource not found' });
  }

  // Zero Trust: Verify ownership on EVERY request
  if (resource.ownerId !== req.user.id && !req.user.permissions.includes('admin')) {
    await logSecurityEvent('unauthorized_access_attempt', {
      userId: req.user.id,
      resourceId,
      ownerId: resource.ownerId
    });

    return res.status(403).json({
      error: 'Forbidden',
      message: 'You do not have access to this resource'
    });
  }

  req.resource = resource;
  next();
}

// Zero Trust API Endpoint
app.get('/api/sensitive-data/:id',
  authenticate,              // Layer 2: Who are you?
  verifyDeviceHealth,        // Layer 3: Is your device secure?
  authorize(['read:data']),  // Layer 4: What can you do?
  verifyResourceOwnership,   // Layer 5: Can you access THIS resource?
  async (req, res) => {
    // All layers passed - grant access
    res.json({
      data: req.resource,
      metadata: {
        accessGrantedAt: new Date(),
        riskScore: req.riskScore
      }
    });
  }
);

// Helper: Calculate risk score based on context
async function calculateRiskScore(context) {
  let score = 0;

  // Unusual IP address
  const isKnownIP = await checkIPReputation(context.ip);
  if (!isKnownIP) score += 30;

  // Unusual location
  const normalLocation = await getUserNormalLocation(context.userId);
  if (context.location !== normalLocation) score += 25;

  // Off-hours access
  const hour = context.time.getHours();
  if (hour < 6 || hour > 22) score += 15;

  // Non-compliant device
  if (context.device.lastSecurityScan > 7 * 24 * 60 * 60 * 1000) score += 20;

  // Sensitive resource
  if (context.resource.includes('admin') || context.resource.includes('payment')) {
    score += 10;
  }

  return Math.min(score, 100);
}

Diagram

graph TB
    subgraph User["User / Client"]
        U[User Device]
        A[Application]
    end

    subgraph ZeroTrust["Zero Trust Control Plane"]
        DP[Device Posture Check
OS version, encryption, patch level] IA[Identity & Authentication
MFA, SSO, JWT verification] CA[Context Analysis
Location, time, behavior] PA[Policy Engine
Risk-based decisions] end subgraph Authorization["Authorization Layer"] RBACRole-Based Access
[Permissions check] ABAC[Attribute-Based Access
Context + Risk score] OLA[Object-Level Auth
Resource ownership] end subgraph Resources["Protected Resources"] API1[API: User Data] API2[API: Payments] DB[(Database)] S3[File Storage] end subgraph Monitoring["Continuous Monitoring"] SIEM[SIEM / Analytics] Audit[Audit Logs] Alert[Alerting & Response] end U --> DP U --> IA DP --> PA IA --> PA CA --> PA PA -->|Risk Score < 50| RBAC PA -->|Risk 50-75| ABAC PA -->|Risk > 75| MFA[Require MFA Step-Up] RBAC --> OLA ABAC --> OLA MFA --> OLA OLA -->|Authorized| API1 OLA -->|Authorized| API2 OLA -->|Denied| Block[403 Forbidden] API1 --> DB API2 --> DB API1 --> S3 DP --> Audit IA --> Audit PA --> Audit OLA --> Audit Audit --> SIEM SIEM --> Alert Alert -.Auto-Block Threats.-> PA style DP fill:#e6f3ff style IA fill:#e6f3ff style PA fill:#ffe6e6 style RBAC fill:#fffbe6 style ABAC fill:#fffbe6 style OLA fill:#fffbe6 style Block fill:#ffcccc style SIEM fill:#f3e6ff

Security Notes

SECURITY NOTES

CRITICAL: Zero Trust architecture assumes no implicit trust. Verify everything.

Zero Trust Principles:

  • Verify identity: Authenticate every request
  • Verify device: Check device security posture
  • Verify network: Don’t trust network location
  • Verify action: Authorize every action
  • Verify data: Classify and protect data

Implementation:

  • MFA: Require multi-factor authentication
  • Device security: Verify device is secure (antivirus, etc.)
  • Network isolation: Segment network, don’t trust networks
  • Encryption: Encrypt all data in transit
  • Data classification: Classify data by sensitivity

Authentication & Authorization:

  • Strong auth: MFA for all access
  • Short-lived tokens: Use short-lived tokens
  • Token binding: Bind tokens to device/user
  • Least privilege: Minimal permissions needed
  • Access review: Regular review of access

Network Security:

  • Microsegmentation: Divide network into segments
  • VPN/SSH: Encrypted access to resources
  • Firewall: Strict firewall rules
  • No perimeter trust: Don’t trust internal networks
  • Monitoring: Monitor all network traffic

Compliance & Monitoring:

  • Continuous verification: Continuously verify access
  • Anomaly detection: Detect unusual behavior
  • Logging: Log all access and actions
  • SIEM: Central security monitoring
  • Incident response: Quick response to anomalies

Benefits:

  • Reduced breach impact: Limiting damage from compromises
  • Cloud-friendly: Works well with cloud/hybrid
  • Remote work: Secure remote access without VPN
  • Insider threats: Protection against insider threats

Best Practices

  1. Verify Every Request: Never assume a previous successful authentication grants future access. Validate tokens, permissions, and context on every API call.

  2. Multi-Factor Authentication (MFA): Require MFA for all users, especially for privileged operations. Use TOTP, hardware keys (FIDO2), or biometrics.

  3. Least Privilege Access: Grant users/services only the minimum permissions needed. Default deny, explicitly allow. Review permissions quarterly.

  4. Device Posture Checks: Verify devices meet security requirements (encrypted disk, up-to-date OS, no jailbreak, security software installed) before granting access.

  5. Microsegmentation: Isolate workloads and services. Use network policies, security groups, and service meshes to prevent lateral movement.

  6. Continuous Monitoring: Log all access attempts (successful and failed). Use SIEM tools to detect anomalies and respond automatically.

  7. Context-Aware Authorization: Make authorization decisions based on multiple factors: identity, device, location, time, resource sensitivity, behavior patterns.

  8. Mutual TLS (mTLS): For service-to-service communication, use mTLS to verify both client and server identities via certificates.

  9. Just-In-Time (JIT) Access: Grant elevated privileges only when needed, for a limited time. Auto-revoke after the time window expires.

  10. Zero Trust Network Access (ZTNA): Replace VPNs with identity-based access. Users authenticate to a control plane that brokers connections to specific resources.

Common Mistakes

Trusting Internal Networks: Assuming internal APIs don’t need authentication because they’re “behind the firewall.” Modern networks are flat; assume breach.

Skipping Authorization After Authentication: Verifying identity but not checking permissions. User A accesses User B’s data because the API only checks if the request is authenticated.

Caching Authorization Decisions: Storing “user X can access resource Y” and reusing it. Permissions change; always verify in real-time.

No Device Verification: Allowing access from any device, including compromised phones or laptops. Implement device posture checks.

VPN as Security: Treating VPN as a security control. VPNs grant network access, not identity-based access. Use ZTNA instead.

Static Policies: Using fixed access rules that don’t adapt to risk. Implement dynamic, context-aware policies.

No Monitoring: Deploying Zero Trust architecture but not logging or monitoring access. Without visibility, you can’t detect abuse or breaches.

Trusting Service-to-Service Calls: Allowing internal microservices to call each other without authentication. Implement mTLS or service mesh authentication.

No Token Revocation: Issuing long-lived tokens without a way to revoke them. Implement token revocation lists or short expiration times.

Complexity Without Buy-In: Implementing Zero Trust without user education, causing friction and shadow IT workarounds.

Standards & RFCs

Standards & RFCs
2)- CISA Zero Trust Maturity Model - Assessment framework
6)- FIDO2 / WebAuthn - Passwordless authentication standards
8)- SAML 2.0 - Security Assertion Markup Language
9)- BeyondCorp (Google) - Zero Trust implementation white papers